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