Module Name: src Committed By: rillig Date: Fri Jan 8 02:11:45 UTC 2021
Modified Files: src/tests/usr.bin/xlint/lint1: d_fold_test.c d_fold_test.exp msg_204.c msg_204.exp src/usr.bin/xlint/lint1: func.c Log Message: lint: fix function as controlling expression (since 2020-12-31) It's perfectly valid to directly use a function name as the controlling expression of an if statement. That function name is converted implicitly to a pointer to that function, and that is a scalar value then. Spotted by christos in lib/libpthread/pthread.c:634. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/d_fold_test.c \ src/tests/usr.bin/xlint/lint1/d_fold_test.exp cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_204.c \ src/tests/usr.bin/xlint/lint1/msg_204.exp cvs rdiff -u -r1.52 -r1.53 src/usr.bin/xlint/lint1/func.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/d_fold_test.c diff -u src/tests/usr.bin/xlint/lint1/d_fold_test.c:1.1 src/tests/usr.bin/xlint/lint1/d_fold_test.c:1.2 --- src/tests/usr.bin/xlint/lint1/d_fold_test.c:1.1 Thu Dec 31 18:51:28 2020 +++ src/tests/usr.bin/xlint/lint1/d_fold_test.c Fri Jan 8 02:11:45 2021 @@ -58,7 +58,7 @@ void if_enum(enum e e) { if (e) return void if_array(struct arr arr) { if (arr.arr) return; } void if_struct(struct s s) { if (s) return; } void if_union(union u u) { if (u) return; } -void if_function(void (*f)(void)) { if (f) return; } +void if_function(void) { if (if_function) return; } void if_pointer(void *p) { if (p) return; } /* C99 6.8.5 */ Index: src/tests/usr.bin/xlint/lint1/d_fold_test.exp diff -u src/tests/usr.bin/xlint/lint1/d_fold_test.exp:1.1 src/tests/usr.bin/xlint/lint1/d_fold_test.exp:1.2 --- src/tests/usr.bin/xlint/lint1/d_fold_test.exp:1.1 Thu Dec 31 18:51:28 2020 +++ src/tests/usr.bin/xlint/lint1/d_fold_test.exp Fri Jan 8 02:11:45 2021 @@ -1,5 +1,3 @@ -d_fold_test.c(58): controlling expressions must have scalar type [204] -d_fold_test.c(58): warning: argument arr unused in function if_array [231] d_fold_test.c(59): controlling expressions must have scalar type [204] d_fold_test.c(59): warning: argument s unused in function if_struct [231] d_fold_test.c(60): controlling expressions must have scalar type [204] Index: src/tests/usr.bin/xlint/lint1/msg_204.c diff -u src/tests/usr.bin/xlint/lint1/msg_204.c:1.2 src/tests/usr.bin/xlint/lint1/msg_204.c:1.3 --- src/tests/usr.bin/xlint/lint1/msg_204.c:1.2 Fri Jan 8 01:40:03 2021 +++ src/tests/usr.bin/xlint/lint1/msg_204.c Fri Jan 8 02:11:45 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_204.c,v 1.2 2021/01/08 01:40:03 rillig Exp $ */ +/* $NetBSD: msg_204.c,v 1.3 2021/01/08 02:11:45 rillig Exp $ */ # 3 "msg_204.c" // Test for message: controlling expressions must have scalar type [204] @@ -32,3 +32,70 @@ bug_between_2020_12_31_and_2021_01_08(vo if (function_pointer) function_pointer(); } + +struct s { + int member; +}; + +union u { + int member; +}; + +enum e { + E +}; + +struct arr { + int arr[4]; +}; + +/* C99 6.2.5p2 */ +void if_Bool(_Bool b) { if (b) return; } + +/* C99 6.2.5p3 */ +void if_char(char c) { if (c) return; } + +/* C99 6.2.5p4 */ +void if_signed_char(signed char sc) { if (sc) return; } +void if_short_int(short s) { if (s) return; } +void if_int(int i) { if (i) return; } +void if_long_int(long int l) { if (l) return; } +void if_long_long_int(long long int ll) { if (ll) return; } + +/* C99 6.2.5p6 */ +void if_unsigned_char(unsigned char uc) { if (uc) return; } +void if_unsigned_short_int(unsigned short us) { if (us) return; } +void if_unsigned_int(unsigned int ui) { if (ui) return; } +void if_unsigned_long_int(unsigned long int ul) { if (ul) return; } +void if_unsigned_long_long_int(unsigned long long int ull) { if (ull) return; } + +/* C99 6.2.5p10 */ +void if_float(float f) { if (f) return; } +void if_double(double d) { if (d) return; } +void if_long_double(long double ld) { if (ld) return; } + +/* C99 6.2.5p11 */ +void if_float_Complex(float _Complex fc) { if (fc) return; } +void if_double_Complex(double _Complex dc) { if (dc) return; } +void if_long_double_Complex(long double _Complex ldc) { if (ldc) return; } + +/* C99 6.2.5p16 */ +void if_enum(enum e e) { if (e) return; } + +/* C99 6.2.5p20 */ +void if_array(struct arr arr) { if (arr.arr) return; } +void if_struct(struct s s) { if (s) return; } +void if_union(union u u) { if (u) return; } +void if_function(void) { if (if_function) return; } +void if_pointer(void *p) { if (p) return; } + +/* C99 6.8.5 */ +void while_struct(struct s s) { while (s) return; } +void for_struct(struct s s) { for (;s;) return; } +void do_while_struct(struct s s) { do { return; } while (s); } + +/* + * C99 6.5.15 for the '?:' operator does not explicitly mention that the + * controlling expression must have a scalar type, curiously. + */ +int conditional_struct(struct s s) { return s ? 1 : 2; } Index: src/tests/usr.bin/xlint/lint1/msg_204.exp diff -u src/tests/usr.bin/xlint/lint1/msg_204.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_204.exp:1.3 --- src/tests/usr.bin/xlint/lint1/msg_204.exp:1.2 Fri Jan 8 01:40:03 2021 +++ src/tests/usr.bin/xlint/lint1/msg_204.exp Fri Jan 8 02:11:45 2021 @@ -1,2 +1,14 @@ -msg_204.c(19): controlling expressions must have scalar type [204] -msg_204.c(28): controlling expressions must have scalar type [204] +msg_204.c(87): controlling expressions must have scalar type [204] +msg_204.c(87): warning: argument s unused in function if_struct [231] +msg_204.c(88): controlling expressions must have scalar type [204] +msg_204.c(88): warning: argument u unused in function if_union [231] +msg_204.c(93): controlling expressions must have scalar type [204] +msg_204.c(93): warning: argument s unused in function while_struct [231] +msg_204.c(94): controlling expressions must have scalar type [204] +msg_204.c(94): warning: end-of-loop code not reached [223] +msg_204.c(94): warning: argument s unused in function for_struct [231] +msg_204.c(95): controlling expressions must have scalar type [204] +msg_204.c(95): warning: argument s unused in function do_while_struct [231] +msg_204.c(101): first operand must have scalar type, op ? : [170] +msg_204.c(101): warning: function conditional_struct expects to return value [214] +msg_204.c(101): warning: argument s unused in function conditional_struct [231] Index: src/usr.bin/xlint/lint1/func.c diff -u src/usr.bin/xlint/lint1/func.c:1.52 src/usr.bin/xlint/lint1/func.c:1.53 --- src/usr.bin/xlint/lint1/func.c:1.52 Fri Jan 8 01:40:03 2021 +++ src/usr.bin/xlint/lint1/func.c Fri Jan 8 02:11:45 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: func.c,v 1.52 2021/01/08 01:40:03 rillig Exp $ */ +/* $NetBSD: func.c,v 1.53 2021/01/08 02:11:45 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: func.c,v 1.52 2021/01/08 01:40:03 rillig Exp $"); +__RCSID("$NetBSD: func.c,v 1.53 2021/01/08 02:11:45 rillig Exp $"); #endif #include <stdlib.h> @@ -537,16 +537,13 @@ default_label(void) static tnode_t * check_controlling_expression(tnode_t *tn) { - // FIXME: dereference before null check - // FIXME: This is evaluated too early; see test msg_204 - tspec_t t = tn->tn_type->t_tspec; if (tn != NULL) tn = cconv(tn); if (tn != NULL) tn = promote(NOOP, 0, tn); - if (tn != NULL && !tspec_is_scalar(t)) { + if (tn != NULL && !tspec_is_scalar(tn->tn_type->t_tspec)) { /* C99 6.5.15p4 for the ?: operator; see typeok:QUEST */ /* C99 6.8.4.1p1 for if statements */ /* C99 6.8.5p2 for while, do and for loops */