Module Name:    src
Committed By:   rillig
Date:           Tue Aug  3 18:38:02 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: expr_cast.c expr_cast.exp msg_214.c
            msg_214.exp
        src/usr.bin/xlint/lint1: decl.c tree.c

Log Message:
lint: casting to a struct is not allowed in C99, only with GCC


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/expr_cast.c \
    src/tests/usr.bin/xlint/lint1/expr_cast.exp
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_214.c \
    src/tests/usr.bin/xlint/lint1/msg_214.exp
cvs rdiff -u -r1.217 -r1.218 src/usr.bin/xlint/lint1/decl.c
cvs rdiff -u -r1.327 -r1.328 src/usr.bin/xlint/lint1/tree.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/expr_cast.c
diff -u src/tests/usr.bin/xlint/lint1/expr_cast.c:1.1 src/tests/usr.bin/xlint/lint1/expr_cast.c:1.2
--- src/tests/usr.bin/xlint/lint1/expr_cast.c:1.1	Tue Aug  3 18:03:54 2021
+++ src/tests/usr.bin/xlint/lint1/expr_cast.c	Tue Aug  3 18:38:02 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: expr_cast.c,v 1.1 2021/08/03 18:03:54 rillig Exp $	*/
+/*	$NetBSD: expr_cast.c,v 1.2 2021/08/03 18:38:02 rillig Exp $	*/
 # 3 "expr_cast.c"
 
 /*
@@ -6,8 +6,14 @@
  *
  * K&R C does not mention any restrictions on the target type.
  * C90 requires both the source type and the target type to be scalar.
+ *
+ * GCC allows casting to a struct type but there is no documentation about
+ * it at https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html.  See
+ * c-typeck.c, function build_c_cast, RECORD_OR_UNION_TYPE_P.
  */
 
+/* lint1-flags: -Sw */
+
 struct S {
 	int member;
 };
@@ -20,14 +26,8 @@ cast(void)
 	} local = {
 		0.0
 	};
-	/* expect-3: warning: 'local' set but not used in function 'cast' [191] */
-	/*
-	 * ^^ XXX: The variable _is_ used, but only in a semantically wrong
-	 * expression.  Lint should rather warn about the invalid cast in the
-	 * 'return' statement, but since all C compilers since C90 are
-	 * required to detect this already, there is no point in duplicating
-	 * that work.
-	 */
 
+	/* expect+2: error: invalid cast from 'struct S' to 'struct S' [147] */
+	/* expect+1: warning: function cast expects to return value [214] */
 	return (struct S)local;
 }
Index: src/tests/usr.bin/xlint/lint1/expr_cast.exp
diff -u src/tests/usr.bin/xlint/lint1/expr_cast.exp:1.1 src/tests/usr.bin/xlint/lint1/expr_cast.exp:1.2
--- src/tests/usr.bin/xlint/lint1/expr_cast.exp:1.1	Tue Aug  3 18:03:54 2021
+++ src/tests/usr.bin/xlint/lint1/expr_cast.exp	Tue Aug  3 18:38:02 2021
@@ -1 +1,2 @@
-expr_cast.c(20): warning: 'local' set but not used in function 'cast' [191]
+expr_cast.c(32): error: invalid cast from 'struct S' to 'struct S' [147]
+expr_cast.c(32): warning: function cast expects to return value [214]

Index: src/tests/usr.bin/xlint/lint1/msg_214.c
diff -u src/tests/usr.bin/xlint/lint1/msg_214.c:1.2 src/tests/usr.bin/xlint/lint1/msg_214.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_214.c:1.2	Sun Feb 21 09:07:58 2021
+++ src/tests/usr.bin/xlint/lint1/msg_214.c	Tue Aug  3 18:38:02 2021
@@ -1,7 +1,12 @@
-/*	$NetBSD: msg_214.c,v 1.2 2021/02/21 09:07:58 rillig Exp $	*/
+/*	$NetBSD: msg_214.c,v 1.3 2021/08/03 18:38:02 rillig Exp $	*/
 # 3 "msg_214.c"
 
 // Test for message: function %s expects to return value [214]
 
-TODO: "Add example code that triggers the above message." /* expect: 249 */
-TODO: "Add example code that almost triggers the above message."
+int
+int_function(void)
+{
+	/* TODO: add quotes around '%s' */
+	/* expect+1: warning: function int_function expects to return value [214] */
+	return;
+}
Index: src/tests/usr.bin/xlint/lint1/msg_214.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_214.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_214.exp:1.3
--- src/tests/usr.bin/xlint/lint1/msg_214.exp:1.2	Sun Mar 21 20:45:00 2021
+++ src/tests/usr.bin/xlint/lint1/msg_214.exp	Tue Aug  3 18:38:02 2021
@@ -1 +1 @@
-msg_214.c(6): error: syntax error ':' [249]
+msg_214.c(11): warning: function int_function expects to return value [214]

Index: src/usr.bin/xlint/lint1/decl.c
diff -u src/usr.bin/xlint/lint1/decl.c:1.217 src/usr.bin/xlint/lint1/decl.c:1.218
--- src/usr.bin/xlint/lint1/decl.c:1.217	Sun Aug  1 18:37:29 2021
+++ src/usr.bin/xlint/lint1/decl.c	Tue Aug  3 18:38:02 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.217 2021/08/01 18:37:29 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.218 2021/08/03 18:38:02 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: decl.c,v 1.217 2021/08/01 18:37:29 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.218 2021/08/03 18:38:02 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -2230,7 +2230,7 @@ eqtype(const type_t *tp1, const type_t *
 				return false;
 		}
 
-		/* dont check prototypes for traditional */
+		/* don't check prototypes for traditional */
 		if (t == FUNC && !tflag) {
 			if (tp1->t_proto && tp2->t_proto) {
 				if (!eqargs(tp1, tp2, dowarn))

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.327 src/usr.bin/xlint/lint1/tree.c:1.328
--- src/usr.bin/xlint/lint1/tree.c:1.327	Tue Aug  3 17:44:59 2021
+++ src/usr.bin/xlint/lint1/tree.c	Tue Aug  3 18:38:02 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.327 2021/08/03 17:44:59 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.328 2021/08/03 18:38:02 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.327 2021/08/03 17:44:59 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.328 2021/08/03 18:38:02 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3414,7 +3414,8 @@ cast(tnode_t *tn, type_t *tp)
 		error(329, type_name(tn->tn_type), type_name(tp));
 		return NULL;
 	} else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
-		if (!Sflag || nt == ARRAY || nt == FUNC)
+		/* Casting to a struct is an undocumented GCC extension. */
+		if (!(gflag && nt == STRUCT))
 			goto invalid_cast;
 	} else if (ot == STRUCT || ot == UNION) {
 		goto invalid_cast;

Reply via email to