Module Name: src Committed By: rillig Date: Thu Dec 31 18:51:28 UTC 2020
Modified Files: src/distrib/sets/lists/tests: mi src/tests/usr.bin/xlint/lint1: Makefile t_integration.sh src/usr.bin/xlint/common: tyname.c src/usr.bin/xlint/lint1: func.c Added Files: src/tests/usr.bin/xlint/lint1: d_fold_test.c d_fold_test.exp Log Message: lint: check that in "if (cond)", cond is scalar To generate a diff of this commit: cvs rdiff -u -r1.1003 -r1.1004 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.21 -r1.22 src/tests/usr.bin/xlint/lint1/Makefile cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/xlint/lint1/d_fold_test.c \ src/tests/usr.bin/xlint/lint1/d_fold_test.exp cvs rdiff -u -r1.14 -r1.15 src/tests/usr.bin/xlint/lint1/t_integration.sh cvs rdiff -u -r1.16 -r1.17 src/usr.bin/xlint/common/tyname.c cvs rdiff -u -r1.38 -r1.39 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/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.1003 src/distrib/sets/lists/tests/mi:1.1004 --- src/distrib/sets/lists/tests/mi:1.1003 Thu Dec 31 03:05:12 2020 +++ src/distrib/sets/lists/tests/mi Thu Dec 31 18:51:28 2020 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1003 2020/12/31 03:05:12 rillig Exp $ +# $NetBSD: mi,v 1.1004 2020/12/31 18:51:28 rillig Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -5782,6 +5782,8 @@ ./usr/tests/usr.bin/xlint/lint1/d_decl_old_style_arguments.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/d_decl_old_style_arguments.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/d_ellipsis_in_switch.c tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/xlint/lint1/d_fold_test.c tests-usr.bin-tests compattestfile,atf +./usr/tests/usr.bin/xlint/lint1/d_fold_test.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/d_gcc_compound_statements3.c tests-usr.bin-tests compattestfile,atf Index: src/tests/usr.bin/xlint/lint1/Makefile diff -u src/tests/usr.bin/xlint/lint1/Makefile:1.21 src/tests/usr.bin/xlint/lint1/Makefile:1.22 --- src/tests/usr.bin/xlint/lint1/Makefile:1.21 Wed Dec 30 13:15:07 2020 +++ src/tests/usr.bin/xlint/lint1/Makefile Thu Dec 31 18:51:28 2020 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.21 2020/12/30 13:15:07 rillig Exp $ +# $NetBSD: Makefile,v 1.22 2020/12/31 18:51:28 rillig Exp $ NOMAN= # defined @@ -50,6 +50,8 @@ FILES+= d_cvt_in_ternary.c FILES+= d_decl_old_style_arguments.c FILES+= d_decl_old_style_arguments.exp FILES+= d_ellipsis_in_switch.c +FILES+= d_fold_test.c +FILES+= d_fold_test.exp FILES+= d_gcc_compound_statements1.c FILES+= d_gcc_compound_statements2.c FILES+= d_gcc_compound_statements3.c Index: src/tests/usr.bin/xlint/lint1/t_integration.sh diff -u src/tests/usr.bin/xlint/lint1/t_integration.sh:1.14 src/tests/usr.bin/xlint/lint1/t_integration.sh:1.15 --- src/tests/usr.bin/xlint/lint1/t_integration.sh:1.14 Wed Dec 30 13:42:19 2020 +++ src/tests/usr.bin/xlint/lint1/t_integration.sh Thu Dec 31 18:51:28 2020 @@ -1,4 +1,4 @@ -# $NetBSD: t_integration.sh,v 1.14 2020/12/30 13:42:19 rillig Exp $ +# $NetBSD: t_integration.sh,v 1.15 2020/12/31 18:51:28 rillig Exp $ # # Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. # All rights reserved. @@ -74,6 +74,7 @@ test_case c99_union_init4 test_case cast_fun_array_param test_case cast_typeof test_case decl_old_style_arguments +test_case fold_test test_case gcc_extension test_case type_question_colon test_case typefun Index: src/usr.bin/xlint/common/tyname.c diff -u src/usr.bin/xlint/common/tyname.c:1.16 src/usr.bin/xlint/common/tyname.c:1.17 --- src/usr.bin/xlint/common/tyname.c:1.16 Tue Dec 29 13:33:03 2020 +++ src/usr.bin/xlint/common/tyname.c Thu Dec 31 18:51:28 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: tyname.c,v 1.16 2020/12/29 13:33:03 rillig Exp $ */ +/* $NetBSD: tyname.c,v 1.17 2020/12/31 18:51:28 rillig Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: tyname.c,v 1.16 2020/12/29 13:33:03 rillig Exp $"); +__RCSID("$NetBSD: tyname.c,v 1.17 2020/12/31 18:51:28 rillig Exp $"); #endif #include <limits.h> @@ -87,6 +87,8 @@ basic_type_name(tspec_t t) case DCOMPLEX: return "double _Complex"; case LCOMPLEX: return "long double _Complex"; case COMPLEX: return "_Complex"; + case SIGNED: return "signed"; + case UNSIGN: return "unsigned"; default: LERROR("basic_type_name(%d)", t); return NULL; @@ -204,6 +206,8 @@ tyname(char *buf, size_t bufsiz, const t case FCOMPLEX: case DCOMPLEX: case LCOMPLEX: + case SIGNED: + case UNSIGN: (void)snprintf(buf, bufsiz, "%s%s", cv, s); break; case PTR: Index: src/usr.bin/xlint/lint1/func.c diff -u src/usr.bin/xlint/lint1/func.c:1.38 src/usr.bin/xlint/lint1/func.c:1.39 --- src/usr.bin/xlint/lint1/func.c:1.38 Wed Dec 30 13:17:42 2020 +++ src/usr.bin/xlint/lint1/func.c Thu Dec 31 18:51:28 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: func.c,v 1.38 2020/12/30 13:17:42 rillig Exp $ */ +/* $NetBSD: func.c,v 1.39 2020/12/31 18:51:28 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.38 2020/12/30 13:17:42 rillig Exp $"); +__RCSID("$NetBSD: func.c,v 1.39 2020/12/31 18:51:28 rillig Exp $"); #endif #include <stdlib.h> @@ -527,6 +527,28 @@ label(int typ, sym_t *sym, tnode_t *tn) reached = 1; } +static tnode_t * +check_controlling_expression(tnode_t *tn) +{ + 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)) { + /* 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 */ + /* controlling expressions must have scalar type */ + error(204); + return NULL; + } + + return tn; +} + /* * T_IF T_LPARN expr T_RPARN */ @@ -535,10 +557,9 @@ if1(tnode_t *tn) { if (tn != NULL) - tn = cconv(tn); + tn = check_controlling_expression(tn); if (tn != NULL) - tn = promote(NOOP, 0, tn); - expr(tn, 0, 1, 0); + expr(tn, 0, 1, 0); pushctrl(T_IF); } @@ -690,14 +711,7 @@ while1(tnode_t *tn) } if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - if (tn != NULL && !tspec_is_scalar(tn->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn = NULL; - } + tn = check_controlling_expression(tn); pushctrl(T_WHILE); cstk->c_loop = 1; @@ -763,14 +777,7 @@ do2(tnode_t *tn) reached = 1; if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - if (tn != NULL && !tspec_is_scalar(tn->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn = NULL; - } + tn = check_controlling_expression(tn); if (tn != NULL && tn->tn_op == CON) { if (tspec_is_int(tn->tn_type->t_tspec)) { @@ -828,14 +835,7 @@ for1(tnode_t *tn1, tnode_t *tn2, tnode_t expr(tn1, 0, 0, 1); if (tn2 != NULL) - tn2 = cconv(tn2); - if (tn2 != NULL) - tn2 = promote(NOOP, 0, tn2); - if (tn2 != NULL && !tspec_is_scalar(tn2->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn2 = NULL; - } + tn2 = check_controlling_expression(tn2); if (tn2 != NULL) expr(tn2, 0, 1, 1); Added files: Index: src/tests/usr.bin/xlint/lint1/d_fold_test.c diff -u /dev/null src/tests/usr.bin/xlint/lint1/d_fold_test.c:1.1 --- /dev/null Thu Dec 31 18:51:28 2020 +++ src/tests/usr.bin/xlint/lint1/d_fold_test.c Thu Dec 31 18:51:28 2020 @@ -0,0 +1,70 @@ +# 2 "d_fold_test.c" + +/* + * Test how expressions are handled in a context where they are tested for + * truthiness, such as in the condition of an if statement. + */ + +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 (*f)(void)) { if (f) 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 does not require a scalar type, curiously. */ +int conditional_struct(struct s s) { return s ? 1 : 2; } Index: src/tests/usr.bin/xlint/lint1/d_fold_test.exp diff -u /dev/null src/tests/usr.bin/xlint/lint1/d_fold_test.exp:1.1 --- /dev/null Thu Dec 31 18:51:28 2020 +++ src/tests/usr.bin/xlint/lint1/d_fold_test.exp Thu Dec 31 18:51:28 2020 @@ -0,0 +1,16 @@ +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] +d_fold_test.c(60): warning: argument u unused in function if_union [231] +d_fold_test.c(65): controlling expressions must have scalar type [204] +d_fold_test.c(65): warning: argument s unused in function while_struct [231] +d_fold_test.c(66): controlling expressions must have scalar type [204] +d_fold_test.c(66): warning: end-of-loop code not reached [223] +d_fold_test.c(66): warning: argument s unused in function for_struct [231] +d_fold_test.c(67): controlling expressions must have scalar type [204] +d_fold_test.c(67): warning: argument s unused in function do_while_struct [231] +d_fold_test.c(70): first operand must have scalar type, op ? : [170] +d_fold_test.c(70): warning: function conditional_struct expects to return value [214] +d_fold_test.c(70): warning: argument s unused in function conditional_struct [231]