1 /* $NetBSD: c11_generic_expression.c,v 1.18 2023/07/09 11:18:55 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 compile-time error. 21 */ 22 const char * 23 classify_type_without_default(double var) 24 { 25 /* expect-2: warning: parameter 'var' unused in function 'classify_type_without_default' [231] */ 26 27 return _Generic(var, 28 long double: "long double", 29 long long: "long long", 30 unsigned: "unsigned" 31 ); 32 /* expect-1: warning: function 'classify_type_without_default' expects to return value [214] */ 33 } 34 35 /* 36 * In this case, the 'default' expression is selected. 37 */ 38 const char * 39 classify_type_with_default(double var) 40 { 41 /* expect-2: warning: parameter 'var' unused in function 'classify_type_with_default' [231] */ 42 43 return _Generic(var, 44 long double: "long double", 45 long long: "long long", 46 unsigned: "unsigned", 47 default: "unknown" 48 ); 49 } 50 51 /* 52 * The type of a _Generic expression is the one from the selected association. 53 */ 54 const char * 55 classify_char(char c) 56 { 57 /* expect-2: warning: parameter 'c' unused in function 'classify_char' [231] */ 58 59 return _Generic(c, 60 char: "yes", 61 default: 0.0 62 ); 63 } 64 65 /* 66 * Before cgram.y 1.238 from 2021-06-27, lint accepted a comma-expression, 67 * which looked as if _Generic would accept multiple arguments before the 68 * selection. 69 */ 70 /* ARGSUSED */ 71 const int * 72 comma_expression(char first, double second) 73 { 74 /* expect+1: error: syntax error 'second' [249] */ 75 return _Generic(first, second, 76 char: "first", 77 double: 2.0 78 ); 79 /* expect+1: warning: function 'comma_expression' falls off bottom without returning value [217] */ 80 } 81 82 /* 83 * Ensure that assignment-expressions are accepted by the grammar, as 84 * opposed to comma-expressions. 85 */ 86 /* ARGSUSED */ 87 int 88 assignment_expression(int first, int second) 89 { 90 return _Generic(first = second, 91 int: second = first 92 ); 93 } 94 95 int 96 primary_expression(void) 97 { 98 return _Generic(0, int: assignment_expression)(0, 0); 99 } 100 101 /* 102 * The types don't match, therefore build_generic_selection returns NULL, 103 * which is then silently ignored by init_expr. This situation is already 104 * covered by the compilers, so there is no need for lint to double-check it. 105 */ 106 const char *x = _Generic( 107 1ULL + 1.0f, 108 int: 1 109 ); 110