Module Name:    src
Committed By:   rillig
Date:           Sat Apr 16 13:25:27 UTC 2022

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_081.c msg_100.c msg_340.c
            msg_340.exp
        src/usr.bin/xlint/lint1: err.c externs1.h main1.c

Log Message:
lint: model C language levels in a future-compatible way

The options -t, -s and -S are confusing because they are used
inconsistently.  The option -S enables C99 features, but when using it
instead of -s, it also doesn't enable all checks required by C90 and
later.  Prepare fixing of these inconsistencies by replacing the flag
variables with language levels that can be extended in a
straight-forward way as new C standards arrive.

| option | allow_trad | allow_c90 | allow_c99 | allow_c11 |
|--------|------------|-----------|-----------|-----------|
| -t     | x          | -         | -         | -         |
| (none) | x          | x         | -         | -         |
| -s     | -          | x         | -         | -         |
| -S     | -          | x         | x         | -         |
| -Ac11  | -          | x         | x         | x         |

Each usage of the old flag variables will be inspected and migrated
individually, to clean up the subtle variations in the conditions and to
provide a simpler model.

When lint was created in 1995, its focus was migrating traditional C
code to C90 code.  Lint does not help in migrating from C90 to C99 or
from C99 to C11 since there are only few silent changes, and simply
because nobody took the time to implement these migration aids.  If
necessary, such migration modes could be added separately.

There is a small functional change: when the option -s is combined with
either -S or -Ac11, lint now only keeps the last of these options.
Previously, these options could be combined, leading to a mixture of
language levels, halfway between C90, C99 and C11.  Especially combining
traditional C with C11 doesn't make sense, but xlint currently allows
it.

The 3 tests that accidentally specified multiple language levels have
been adjusted to a single language level.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/msg_081.c \
    src/tests/usr.bin/xlint/lint1/msg_100.c \
    src/tests/usr.bin/xlint/lint1/msg_340.exp
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_340.c
cvs rdiff -u -r1.159 -r1.160 src/usr.bin/xlint/lint1/err.c
cvs rdiff -u -r1.154 -r1.155 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.59 -r1.60 src/usr.bin/xlint/lint1/main1.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/msg_081.c
diff -u src/tests/usr.bin/xlint/lint1/msg_081.c:1.3 src/tests/usr.bin/xlint/lint1/msg_081.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_081.c:1.3	Sun Jan 31 11:12:07 2021
+++ src/tests/usr.bin/xlint/lint1/msg_081.c	Sat Apr 16 13:25:27 2022
@@ -1,8 +1,8 @@
-/*	$NetBSD: msg_081.c,v 1.3 2021/01/31 11:12:07 rillig Exp $	*/
+/*	$NetBSD: msg_081.c,v 1.4 2022/04/16 13:25:27 rillig Exp $	*/
 # 3 "msg_081.c"
 
-// Test for message: \a undefined in traditional C [81]
+/* Test for message: \a undefined in traditional C [81] */
 
-/* lint1-flags: -Stw */
+/* lint1-flags: -tw */
 
 char str[] = "The bell\a rings";	/* expect: 81 */
Index: src/tests/usr.bin/xlint/lint1/msg_100.c
diff -u src/tests/usr.bin/xlint/lint1/msg_100.c:1.3 src/tests/usr.bin/xlint/lint1/msg_100.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_100.c:1.3	Sun Jan 31 11:12:07 2021
+++ src/tests/usr.bin/xlint/lint1/msg_100.c	Sat Apr 16 13:25:27 2022
@@ -1,9 +1,9 @@
-/*	$NetBSD: msg_100.c,v 1.3 2021/01/31 11:12:07 rillig Exp $	*/
+/*	$NetBSD: msg_100.c,v 1.4 2022/04/16 13:25:27 rillig Exp $	*/
 # 3 "msg_100.c"
 
-// Test for message: unary + is illegal in traditional C [100]
+/* Test for message: unary + is illegal in traditional C [100] */
 
-/* lint1-flags: -Stw */
+/* lint1-flags: -tw */
 
 int
 unary_plus(int x)
Index: src/tests/usr.bin/xlint/lint1/msg_340.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_340.exp:1.3 src/tests/usr.bin/xlint/lint1/msg_340.exp:1.4
--- src/tests/usr.bin/xlint/lint1/msg_340.exp:1.3	Mon Jul  5 19:53:43 2021
+++ src/tests/usr.bin/xlint/lint1/msg_340.exp	Sat Apr 16 13:25:27 2022
@@ -1 +1 @@
-msg_340.c(16): error: initialization with '[a...b]' is a GCC extension [340]
+msg_340.c(16): warning: initialization with '[a...b]' is a GCC extension [340]

Index: src/tests/usr.bin/xlint/lint1/msg_340.c
diff -u src/tests/usr.bin/xlint/lint1/msg_340.c:1.2 src/tests/usr.bin/xlint/lint1/msg_340.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_340.c:1.2	Mon Jul  5 19:53:43 2021
+++ src/tests/usr.bin/xlint/lint1/msg_340.c	Sat Apr 16 13:25:27 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_340.c,v 1.2 2021/07/05 19:53:43 rillig Exp $	*/
+/*	$NetBSD: msg_340.c,v 1.3 2022/04/16 13:25:27 rillig Exp $	*/
 # 3 "msg_340.c"
 
 // Test for message: initialization with '[a...b]' is a GCC extension [340]
@@ -7,7 +7,7 @@
  * In strict C mode, GCC extensions are flagged as such.
  */
 
-/* lint1-flags: -Ssw */
+/* lint1-flags: -Sw */
 
 int
 example(void)

Index: src/usr.bin/xlint/lint1/err.c
diff -u src/usr.bin/xlint/lint1/err.c:1.159 src/usr.bin/xlint/lint1/err.c:1.160
--- src/usr.bin/xlint/lint1/err.c:1.159	Fri Apr  8 21:29:29 2022
+++ src/usr.bin/xlint/lint1/err.c	Sat Apr 16 13:25:27 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: err.c,v 1.159 2022/04/08 21:29:29 rillig Exp $	*/
+/*	$NetBSD: err.c,v 1.160 2022/04/16 13:25:27 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: err.c,v 1.159 2022/04/08 21:29:29 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.160 2022/04/16 13:25:27 rillig Exp $");
 #endif
 
 #include <sys/types.h>
@@ -630,12 +630,6 @@ void
 	va_end(ap);
 }
 
-/*
- * XXX I think the logic is possibly somewhat screwed up here. The
- * question is, how do we want to interpret the -s and -S flags going
- * forward? We need to answer that and then we can fix this to be
- * "right"... [perry, 2 Nov 2002]
-*/
 void
 (c99ism)(int msgid, ...)
 {

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.154 src/usr.bin/xlint/lint1/externs1.h:1.155
--- src/usr.bin/xlint/lint1/externs1.h:1.154	Sat Apr  9 23:41:22 2022
+++ src/usr.bin/xlint/lint1/externs1.h	Sat Apr 16 13:25:27 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.154 2022/04/09 23:41:22 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.155 2022/04/16 13:25:27 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,24 +37,41 @@
 extern	int	aflag;
 extern	bool	bflag;
 extern	bool	cflag;
-extern	bool	c11flag;
 extern	bool	eflag;
 extern	bool	Fflag;
-extern	bool	gflag;
 extern	bool	hflag;
 extern	bool	pflag;
 extern	bool	rflag;
-extern	bool	sflag;
-extern	bool	tflag;
 extern	bool	uflag;
 extern	bool	vflag;
 extern	bool	yflag;
 extern	bool	wflag;
 extern	bool	zflag;
-extern	bool	Sflag;
 extern	bool	Tflag;
 extern	bool	Pflag;
 
+extern	bool	allow_trad;
+extern	bool	allow_c90;
+extern	bool	allow_c99;
+extern	bool	allow_c11;
+extern	bool	allow_gcc;
+
+/*
+ * TODO: Replace the old flags with the new expressions, checking in each
+ * case whether the specific condition still makes sense.  When lint was
+ * invented in 1995, it did not know about C99 mode, which makes all
+ * conditions involving tflag and sflag suspicious.
+ *
+ * In 1995, gflag meant "C90 plus GCC extensions".  That definition needs to
+ * be extended to C99 and later as well to properly match "C99 + GCC" or "C11
+ * + GCC".
+ */
+#define tflag	(allow_trad && !allow_c90)
+#define sflag	(!allow_trad && !allow_c99)
+#define Sflag	(!!allow_c99)
+#define c11flag	(!!allow_c11)
+#define gflag	(!!allow_gcc)
+
 extern	void	norecover(void);
 
 /*

Index: src/usr.bin/xlint/lint1/main1.c
diff -u src/usr.bin/xlint/lint1/main1.c:1.59 src/usr.bin/xlint/lint1/main1.c:1.60
--- src/usr.bin/xlint/lint1/main1.c:1.59	Sun Feb 27 11:40:29 2022
+++ src/usr.bin/xlint/lint1/main1.c	Sat Apr 16 13:25:27 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: main1.c,v 1.59 2022/02/27 11:40:29 rillig Exp $	*/
+/*	$NetBSD: main1.c,v 1.60 2022/04/16 13:25:27 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: main1.c,v 1.59 2022/02/27 11:40:29 rillig Exp $");
+__RCSID("$NetBSD: main1.c,v 1.60 2022/04/16 13:25:27 rillig Exp $");
 #endif
 
 #include <sys/types.h>
@@ -68,18 +68,12 @@ bool	bflag;
 /* Print warnings for pointer casts. */
 bool	cflag;
 
-/* Allow features from C11, C99 and C90. */
-bool	c11flag;
-
 /* Perform stricter checking of enum types and operations on enum types. */
 bool	eflag;
 
 /* Print complete pathnames, not only the basename. */
 bool	Fflag;
 
-/* Enable some extensions of gcc */
-bool	gflag;
-
 /* Treat warnings as errors */
 bool	wflag;
 
@@ -98,17 +92,8 @@ bool	pflag;
  */
 bool	rflag;
 
-/* Strict ANSI C mode. */
-bool	sflag;
-
 bool	Tflag;
 
-/* Traditional C mode. */
-bool	tflag;
-
-/* Enable C99 extensions */
-bool	Sflag;
-
 /* Picky flag */
 bool	Pflag;
 
@@ -124,6 +109,17 @@ bool	vflag = true;
 /* Complain about structures which are never defined. */
 bool	zflag = true;
 
+/*
+ * The default language level is the one that checks for compatibility
+ * between traditional C and C90.  As of 2022, this default is no longer
+ * useful since most traditional C code has already been migrated.
+ */
+bool	allow_trad = true;
+bool	allow_c90 = true;
+bool	allow_c99;
+bool	allow_c11;
+bool	allow_gcc;
+
 err_set	msgset;
 
 sig_atomic_t fpe;
@@ -211,15 +207,30 @@ main(int argc, char *argv[])
 		case 'c':	cflag = true;	break;
 		case 'e':	eflag = true;	break;
 		case 'F':	Fflag = true;	break;
-		case 'g':	gflag = true;	break;
+		case 'g':	allow_gcc = true;	break;
 		case 'h':	hflag = true;	break;
 		case 'p':	pflag = true;	break;
 		case 'P':	Pflag = true;	break;
 		case 'r':	rflag = true;	break;
-		case 's':	sflag = true;	break;
-		case 'S':	Sflag = true;	break;
+		case 's':
+			allow_trad = false;
+			allow_c90 = true;
+			allow_c99 = false;
+			allow_c11 = false;
+			break;
+		case 'S':
+			allow_trad = false;
+			allow_c90 = true;
+			allow_c99 = true;
+			allow_c11 = false;
+			break;
 		case 'T':	Tflag = true;	break;
-		case 't':	tflag = true;	break;
+		case 't':
+			allow_trad = true;
+			allow_c90 = false;
+			allow_c99 = false;
+			allow_c11 = false;
+			break;
 		case 'u':	uflag = false;	break;
 		case 'w':	wflag = true;	break;
 		case 'v':	vflag = false;	break;
@@ -228,9 +239,10 @@ main(int argc, char *argv[])
 
 		case 'A':
 			if (strcmp(optarg, "c11") == 0) {
-				c11flag = true;
-				Sflag = true;
-				sflag = false;
+				allow_trad = false;
+				allow_c90 = true;
+				allow_c99 = true;
+				allow_c11 = true;
 			} else
 				usage();
 			break;
@@ -273,7 +285,7 @@ main(int argc, char *argv[])
 	initdecl();
 	initscan();
 
-	if (gflag && !tflag) {
+	if (allow_gcc && !tflag) {
 		if ((yyin = gcc_builtins()) == NULL)
 			err(1, "cannot open builtins");
 		yyparse();

Reply via email to