1/* $NetBSD: c11_generic_expression.c,v 1.19 2023/08/06 19:44:50 rillig Exp $ */ 2# 3 "c11_generic_expression.c" 3 4/* lint1-extra-flags: -X 351 */ 5 6/* 7 * C99 added support for type-generic macros, but these were limited to the 8 * header <tgmath.h>. C11 made this feature generally available. 9 * 10 * The generic selection is typically used with macros, but since lint1 works 11 * on the preprocessed source, the test cases look a bit strange. 12 * 13 * C11 6.5.1.1 "Generic selection" 14 */ 15 16/* lint1-extra-flags: -Ac11 */ 17 18/* 19 * The type of 'var' is not compatible with any of the types from the 20 * generic-association. This is a constraint violation that the compiler must 21 * detect, therefore lint doesn't repeat that diagnostic. 22 */ 23const char * 24classify_type_without_default(double var) 25{ 26 /* expect-2: warning: parameter 'var' unused in function 'classify_type_without_default' [231] */ 27 28 return _Generic(var, 29 long double: "long double", 30 long long: "long long", 31 unsigned: "unsigned" 32 ); 33 /* expect-1: error: function 'classify_type_without_default' expects to return value [214] */ 34} 35 36/* 37 * In this case, the 'default' expression is selected. 38 */ 39const char * 40classify_type_with_default(double var) 41{ 42 /* expect-2: warning: parameter 'var' unused in function 'classify_type_with_default' [231] */ 43 44 return _Generic(var, 45 long double: "long double", 46 long long: "long long", 47 unsigned: "unsigned", 48 default: "unknown" 49 ); 50} 51 52/* 53 * The type of a _Generic expression is the one from the selected association. 54 */ 55const char * 56classify_char(char c) 57{ 58 /* expect-2: warning: parameter 'c' unused in function 'classify_char' [231] */ 59 60 return _Generic(c, 61 char: "yes", 62 default: 0.0 63 ); 64} 65 66/* 67 * Before cgram.y 1.238 from 2021-06-27, lint accepted a comma-expression, 68 * which looked as if _Generic would accept multiple arguments before the 69 * selection. 70 */ 71/* ARGSUSED */ 72const int * 73comma_expression(char first, double second) 74{ 75 /* expect+1: error: syntax error 'second' [249] */ 76 return _Generic(first, second, 77 char: "first", 78 double: 2.0 79 ); 80 /* expect+1: warning: function 'comma_expression' falls off bottom without returning value [217] */ 81} 82 83/* 84 * Ensure that assignment-expressions are accepted by the grammar, as 85 * opposed to comma-expressions. 86 */ 87/* ARGSUSED */ 88int 89assignment_expression(int first, int second) 90{ 91 return _Generic(first = second, 92 int: second = first 93 ); 94} 95 96int 97primary_expression(void) 98{ 99 return _Generic(0, int: assignment_expression)(0, 0); 100} 101 102/* 103 * The types don't match, therefore build_generic_selection returns NULL, 104 * which is then silently ignored by init_expr. This situation is already 105 * covered by the compilers, so there is no need for lint to double-check it. 106 */ 107const char *x = _Generic( 108 1ULL + 1.0f, 109 int: 1 110); 111