1 /* $NetBSD: lang_level_c99.c,v 1.2 2023/08/06 19:44:50 rillig Exp $ */ 2 # 3 "lang_level_c99.c" 3 4 /* 5 * Tests that are specific to the C99 language level, in particular, features 6 * that were added in C99. 7 * 8 * In the below comments, [-] means unsupported and [x] means supported. 9 */ 10 11 /* lint1-flags: -S -w -X 351 */ 12 13 /* C99 Foreword */ 14 15 // [-] restricted character set support via digraphs and <iso646.h> 16 // 17 // Lint neither parses digraphs nor trigraphs. 18 19 // [x] wide character library support in <wchar.h> and <wctype.h> 20 // 21 // On all supported platforms, 'wchar_t' == 'int'. 22 23 const int wide_string[] = L"wide"; 24 25 // [x] more precise aliasing rules via effective type 26 // 27 // Irrelevant, as lint does not check the runtime behavior. 28 29 // [x] restricted pointers 30 // 31 // Can be parsed, are otherwise ignored. 32 33 // [-] variable length arrays 34 // 35 // Variable length arrays are handled as if the number of elements in the array 36 // were always 1. 37 38 /* FIXME: Parameter 'n' _is_ actually used. */ 39 /* expect+2: warning: parameter 'n' unused in function 'variable_length_arrays' [231] */ 40 unsigned long long 41 variable_length_arrays(int n) 42 { 43 int vla[n]; 44 /* FIXME: The array dimension is not constant, but still negative. */ 45 /* expect+1: error: negative array dimension (-4) [20] */ 46 typedef int sizeof_vla[-(int)sizeof(vla)]; 47 return sizeof(vla); 48 } 49 50 // [x] flexible array members 51 // 52 // Flexible array members are parsed but not validated thoroughly. 53 54 void 55 flexible_array_members(void) 56 { 57 struct { 58 int regular; 59 int flexible[]; 60 } s = { 61 0, 62 // Flexible array member must not be initialized. Lint does 63 // not detect this, leaving the job to the C99 compiler. 64 { 1, 3, 4, } 65 }; 66 /* expect+1: error: negative array dimension (-4) [20] */ 67 typedef int sizeof_s[-(int)sizeof(s)]; 68 } 69 70 // [x] static and type qualifiers in parameter array declarators 71 // 72 // Can be parsed, are otherwise ignored. 73 74 // [-] complex (and imaginary) support in <complex.h> 75 // 76 // Lint does not keep track of which parts of a complex object are initialized. 77 // 78 // Lint does not support '_Imaginary'. 79 80 // [x] type-generic math macros in <tgmath.h> 81 // 82 // Irrelevant, as lint only sees the preprocessed source code. 83 84 // [x] the long long int type and library functions 85 // 86 // On all platforms supported by lint, 'long long' is 64 bits wide. The other 87 // fixed-width types are 'char', 'short', 'int' and (only on 64-bit platforms) 88 // '__int128_t'. 89 // 90 // The lint standard libraries -lstdc and -lposix do not contain the 91 // functions added in C99. 92 93 /* expect+1: error: negative array dimension (-1) [20] */ 94 typedef int sizeof_char[-(int)sizeof(char)]; 95 /* expect+1: error: negative array dimension (-2) [20] */ 96 typedef int sizeof_short[-(int)sizeof(short)]; 97 /* expect+1: error: negative array dimension (-4) [20] */ 98 typedef int sizeof_int[-(int)sizeof(int)]; 99 /* expect+1: error: negative array dimension (-8) [20] */ 100 typedef int sizeof_long_long[-(int)sizeof(long long)]; 101 102 // [x] increased minimum translation limits 103 // 104 // Irrelevant, as lint does not have any hard-coded limits. 105 106 // [x] additional floating-point characteristics in <float.h> 107 // 108 // Lint has very limited support for floating point numbers, as it fully relies 109 // on the host platform. This is noticeable when cross-compiling between 110 // platforms with different size or representation of 'long double'. 111 112 // [x] remove implicit int 113 // 114 // Lint parses old-style declarations and marks them as errors. 115 116 // [x] reliable integer division 117 // 118 // The lint source code requires a C99 compiler, so when mapping the integer 119 // operations to those from the host platform, lint uses these. 120 121 // [-] universal character names (\u and \U) 122 // 123 // No, as nothing in the NetBSD source tree uses this feature. 124 125 // [-] extended identifiers 126 // 127 // No, as nothing in the NetBSD source tree uses this feature. 128 129 // [x] hexadecimal floating-point constants and %a and %A printf/scanf 130 // conversion specifiers 131 132 void pf(); /* no prototype parameters */ 133 134 void 135 hexadecimal_floating_point_constants(void) 136 { 137 double hex = 0x1.0p34; 138 pf("%s %a\n", "hex", hex); 139 } 140 141 // [x] compound literals 142 // 143 // See d_c99_compound_literal_comma.c. 144 145 // [x] designated initializers 146 // 147 // See d_c99_init.c. 148 149 // [x] // comments 150 // 151 // Also supported in GCC mode. 152 153 // [?] extended integer types and library functions in <inttypes.h> and 154 // <stdint.h> 155 // 156 // TODO 157 158 // [x] remove implicit function declaration 159 160 void 161 call_implicitly_declared_function(void) 162 { 163 /* expect+1: error: function 'implicitly_declared_function' implicitly declared to return int [215] */ 164 implicitly_declared_function(0); 165 } 166 167 // [x] preprocessor arithmetic done in intmax_t/uintmax_t 168 // 169 // Irrelevant, as lint only sees the preprocessed source code. 170 171 // [x] mixed declarations and code 172 173 // [x] new block scopes for selection and iteration statements 174 175 // [?] integer constant type rules 176 // 177 // TODO 178 179 // [?] integer promotion rules 180 // 181 // TODO 182 183 // [x] macros with a variable number of arguments 184 // 185 // Irrelevant, as lint only sees the preprocessed source code. 186 187 // [x] the vscanf family of functions in <stdio.h> and <wchar.h> 188 // 189 // Irrelevant, as typical C99 compilers already check these. 190 191 // [x] additional math library functions in <math.h> 192 // 193 // Irrelevant, as lint does not check arithmetic expressions. 194 // 195 // Lint also does not generate its own standard library definition for libm. 196 197 // [x] treatment of error conditions by math library functions 198 // (math_errhandling) 199 // 200 // Irrelevant, as lint does not check for error handling. 201 202 // [x] floating-point environment access in <fenv.h> 203 // 204 // TODO 205 206 // [x] IEC 60559 (also known as IEC 559 or IEEE arithmetic) support 207 // 208 // On platforms that conform to IEC 60559, lint performs the arithmetic 209 // operations accordingly. When cross-compiling on a vax host for other target 210 // platforms, no such support is available. 211 212 // [x] trailing comma allowed in enum declaration 213 // 214 // Yes, see the grammar rule 'enums_with_opt_comma'. 215 216 // [-] %lf conversion specifier allowed in printf 217 // 218 // TODO: see tests/lint2/msg_013.exp. 219 220 // [x] inline functions 221 // 222 // Yes, also allowed in GCC mode. 223 224 // [x] the snprintf family of functions in <stdio.h> 225 // 226 // The snprintf functions are treated like all other functions. The checks for 227 // matching format strings targets traditional C only and thus does not apply 228 // to these functions, as they have a prototype definition. 229 230 // [x] boolean type in <stdbool.h> 231 // 232 // Yes. Conversion to and from boolean follows 6.3.1.2. See also the -T flag, 233 // which enables 'strict bool mode'. 234 235 // [x] idempotent type qualifiers 236 // 237 // Lint warns about duplicate type qualifiers but accepts them otherwise. 238 239 /* expect+1: warning: duplicate 'const' [10] */ 240 const const int duplicate_type_qualifier = 2; 241 242 // [x] empty macro arguments 243 // 244 // Irrelevant, as lint only sees the preprocessed source code. 245 246 // [?] new structure type compatibility rules (tag compatibility) 247 // 248 // TODO 249 250 // [x] additional predefined macro names 251 // 252 // Irrelevant, as lint only sees the preprocessed source code. 253 254 // [-] _Pragma preprocessing operator 255 // 256 // No, not yet asked for. 257 258 // [-] standard pragmas 259 // 260 // No, not yet asked for. 261 262 // [x] __func__ predefined identifier 263 // 264 // Yes, see 'fallback_symbol'. 265 266 // [x] va_copy macro 267 // 268 // Irrelevant, as lint only sees the preprocessed source code. 269 270 // [x] additional strftime conversion specifiers 271 // 272 // Irrelevant, as lint does not check strftime in depth. 273 274 // [?] LIA compatibility annex 275 // 276 // TODO 277 278 // [x] deprecate ungetc at the beginning of a binary file 279 // 280 // Irrelevant, as lint's analysis is not that deep into the runtime behavior. 281 282 // [x] remove deprecation of aliased array parameters 283 // 284 // Irrelevant, as lint does not check for aliasing. 285 286 // [?] conversion of array to pointer not limited to lvalues 287 // 288 // TODO 289 290 // [x] relaxed constraints on aggregate and union initialization 291 // 292 // Yes, struct and union members can be initialized with non-constant 293 // expressions. Members that have struct or union type can be initialized with 294 // an expression of the same type. 295 296 // [x] relaxed restrictions on portable header names 297 // 298 // Irrelevant, as lint only sees the preprocessed source code. 299 300 // [x] return without expression not permitted in function that returns a value 301 // (and vice versa) 302 303 void 304 return_no_expr(int x) 305 { 306 x++; 307 /* expect+1: error: void function 'return_no_expr' cannot return value [213] */ 308 return x; 309 } 310 311 int 312 return_expr(void) 313 { 314 /* expect+1: error: function 'return_expr' expects to return value [214] */ 315 return; 316 } 317