Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: check that in "if (cond)", cond is...
details: https://anonhg.NetBSD.org/src/rev/443b75ab219f
branches: trunk
changeset: 1017570:443b75ab219f
user: rillig <rillig%NetBSD.org@localhost>
date: Thu Dec 31 18:51:28 2020 +0000
description:
lint: check that in "if (cond)", cond is scalar
diffstat:
distrib/sets/lists/tests/mi | 4 +-
tests/usr.bin/xlint/lint1/Makefile | 4 +-
tests/usr.bin/xlint/lint1/d_fold_test.c | 70 ++++++++++++++++++++++++++++++
tests/usr.bin/xlint/lint1/d_fold_test.exp | 16 ++++++
tests/usr.bin/xlint/lint1/t_integration.sh | 3 +-
usr.bin/xlint/common/tyname.c | 8 ++-
usr.bin/xlint/lint1/func.c | 58 ++++++++++++------------
7 files changed, 129 insertions(+), 34 deletions(-)
diffs (291 lines):
diff -r 70afa6e5da58 -r 443b75ab219f distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi Thu Dec 31 17:39:36 2020 +0000
+++ b/distrib/sets/lists/tests/mi Thu Dec 31 18:51:28 2020 +0000
@@ -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
diff -r 70afa6e5da58 -r 443b75ab219f tests/usr.bin/xlint/lint1/Makefile
--- a/tests/usr.bin/xlint/lint1/Makefile Thu Dec 31 17:39:36 2020 +0000
+++ b/tests/usr.bin/xlint/lint1/Makefile Thu Dec 31 18:51:28 2020 +0000
@@ -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_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
diff -r 70afa6e5da58 -r 443b75ab219f tests/usr.bin/xlint/lint1/d_fold_test.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/usr.bin/xlint/lint1/d_fold_test.c Thu Dec 31 18:51:28 2020 +0000
@@ -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; }
diff -r 70afa6e5da58 -r 443b75ab219f tests/usr.bin/xlint/lint1/d_fold_test.exp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/usr.bin/xlint/lint1/d_fold_test.exp Thu Dec 31 18:51:28 2020 +0000
@@ -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]
diff -r 70afa6e5da58 -r 443b75ab219f tests/usr.bin/xlint/lint1/t_integration.sh
--- a/tests/usr.bin/xlint/lint1/t_integration.sh Thu Dec 31 17:39:36 2020 +0000
+++ b/tests/usr.bin/xlint/lint1/t_integration.sh Thu Dec 31 18:51:28 2020 +0000
@@ -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 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
diff -r 70afa6e5da58 -r 443b75ab219f usr.bin/xlint/common/tyname.c
--- a/usr.bin/xlint/common/tyname.c Thu Dec 31 17:39:36 2020 +0000
+++ b/usr.bin/xlint/common/tyname.c Thu Dec 31 18:51:28 2020 +0000
@@ -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 @@
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 @@
case FCOMPLEX:
case DCOMPLEX:
case LCOMPLEX:
+ case SIGNED:
+ case UNSIGN:
(void)snprintf(buf, bufsiz, "%s%s", cv, s);
break;
case PTR:
diff -r 70afa6e5da58 -r 443b75ab219f usr.bin/xlint/lint1/func.c
--- a/usr.bin/xlint/lint1/func.c Thu Dec 31 17:39:36 2020 +0000
+++ b/usr.bin/xlint/lint1/func.c Thu Dec 31 18:51:28 2020 +0000
@@ -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 @@
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 @@
{
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 @@
}
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 @@
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 @@
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);
Home |
Main Index |
Thread Index |
Old Index