Module Name:    src
Committed By:   rillig
Date:           Sat Aug 14 12:46:24 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: d_c99_bool_strict.exp
            d_c99_bool_strict_syshdr.exp d_init_array_using_string.exp
            msg_115.c msg_115.exp msg_124.exp msg_164.c msg_164.exp msg_242.c
            msg_242.exp
        src/usr.bin/xlint/lint1: init.c ops.def tree.c

Log Message:
lint: allow initialization of struct with constant member

The operator INIT, just like RETURN and FARG, initializes an object with
an expression.  The target object of such an initialization may be a
struct with constant members.

The operator ASSIGN, on the other hand, is entirely different.  It
overwrites the existing value of the object, and this is not allowed for
structs that have a constant member.  Therefore it was wrong to use the
operator ASSIGN for initialization.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp
cvs rdiff -u -r1.10 -r1.11 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
cvs rdiff -u -r1.4 -r1.5 \
    src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp
cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/xlint/lint1/msg_115.c
cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/msg_115.exp
cvs rdiff -u -r1.9 -r1.10 src/tests/usr.bin/xlint/lint1/msg_124.exp
cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/msg_164.c \
    src/tests/usr.bin/xlint/lint1/msg_242.c
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_164.exp \
    src/tests/usr.bin/xlint/lint1/msg_242.exp
cvs rdiff -u -r1.207 -r1.208 src/usr.bin/xlint/lint1/init.c
cvs rdiff -u -r1.23 -r1.24 src/usr.bin/xlint/lint1/ops.def
cvs rdiff -u -r1.332 -r1.333 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/d_c99_bool_strict.exp
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.27 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.28
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.27	Sun Jul  4 07:09:39 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp	Sat Aug 14 12:46:24 2021
@@ -144,10 +144,10 @@ d_c99_bool_strict.c(582): error: operand
 d_c99_bool_strict.c(583): error: operands of ':' have incompatible types (unsigned int != _Bool) [107]
 d_c99_bool_strict.c(589): warning: expression has null effect [129]
 d_c99_bool_strict.c(590): warning: expression has null effect [129]
-d_c99_bool_strict.c(603): error: operands of '=' have incompatible types (char != _Bool) [107]
-d_c99_bool_strict.c(604): error: operands of '=' have incompatible types (int != _Bool) [107]
-d_c99_bool_strict.c(605): error: operands of '=' have incompatible types (double != _Bool) [107]
-d_c99_bool_strict.c(606): error: operands of '=' have incompatible types (pointer != _Bool) [107]
+d_c99_bool_strict.c(603): error: operands of 'init' have incompatible types (char != _Bool) [107]
+d_c99_bool_strict.c(604): error: operands of 'init' have incompatible types (int != _Bool) [107]
+d_c99_bool_strict.c(605): error: operands of 'init' have incompatible types (double != _Bool) [107]
+d_c99_bool_strict.c(606): error: operands of 'init' have incompatible types (pointer != _Bool) [107]
 d_c99_bool_strict.c(623): error: operands of '=' have incompatible types (int != _Bool) [107]
 d_c99_bool_strict.c(624): error: operands of '=' have incompatible types (int != _Bool) [107]
 d_c99_bool_strict.c(625): error: operands of '=' have incompatible types (int != _Bool) [107]

Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.10 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.11
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.10	Tue Aug  3 18:44:33 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp	Sat Aug 14 12:46:24 2021
@@ -1,6 +1,6 @@
 d_c99_bool_strict_syshdr.c(43): error: controlling expression must be bool, not 'int' [333]
 d_c99_bool_strict_syshdr.c(53): error: controlling expression must be bool, not 'int' [333]
-d_c99_bool_strict_syshdr.c(87): error: operands of '=' have incompatible types (_Bool != int) [107]
+d_c99_bool_strict_syshdr.c(87): error: operands of 'init' have incompatible types (_Bool != int) [107]
 d_c99_bool_strict_syshdr.c(162): error: return value type mismatch (_Bool) and (int) [211]
 d_c99_bool_strict_syshdr.c(175): error: operand of '!' must be bool, not 'int' [330]
 d_c99_bool_strict_syshdr.c(175): warning: function 'str_equal_bad' expects to return value [214]

Index: src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp
diff -u src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.4 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.5
--- src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.4	Fri Apr  9 23:03:26 2021
+++ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp	Sat Aug 14 12:46:24 2021
@@ -1,7 +1,7 @@
-d_init_array_using_string.c(16): warning: illegal pointer combination (pointer to const char) and (pointer to int), op = [124]
-d_init_array_using_string.c(17): warning: illegal pointer combination (pointer to const int) and (pointer to char), op = [124]
-d_init_array_using_string.c(34): warning: illegal pointer combination [184]
-d_init_array_using_string.c(35): warning: illegal pointer combination [184]
+d_init_array_using_string.c(16): warning: illegal pointer combination (pointer to const char) and (pointer to int), op init [124]
+d_init_array_using_string.c(17): warning: illegal pointer combination (pointer to const int) and (pointer to char), op init [124]
+d_init_array_using_string.c(34): warning: illegal pointer combination (pointer to const char) and (pointer to int), op init [124]
+d_init_array_using_string.c(35): warning: illegal pointer combination (pointer to const int) and (pointer to char), op init [124]
 d_init_array_using_string.c(59): error: cannot initialize 'array[10] of const char' from 'pointer to int' [185]
 d_init_array_using_string.c(60): error: cannot initialize 'array[10] of const int' from 'pointer to char' [185]
 d_init_array_using_string.c(69): warning: non-null byte ignored in string initializer [187]

Index: src/tests/usr.bin/xlint/lint1/msg_115.c
diff -u src/tests/usr.bin/xlint/lint1/msg_115.c:1.7 src/tests/usr.bin/xlint/lint1/msg_115.c:1.8
--- src/tests/usr.bin/xlint/lint1/msg_115.c:1.7	Tue Aug 10 20:43:13 2021
+++ src/tests/usr.bin/xlint/lint1/msg_115.c	Sat Aug 14 12:46:24 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_115.c,v 1.7 2021/08/10 20:43:13 rillig Exp $	*/
+/*	$NetBSD: msg_115.c,v 1.8 2021/08/14 12:46:24 rillig Exp $	*/
 # 3 "msg_115.c"
 
 // Test for message: %soperand of '%s' must be modifiable lvalue [115]
@@ -26,9 +26,9 @@ void take_const_member(const_member);
 const_member
 initialize_const_struct_member(void)
 {
-	/* FIXME: In an initialization, const members can be assigned. */
-	/* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
+	/* In a simple initialization, const members can be assigned. */
 	const_member cm1 = (const_member) { 12345 };
+
 	if (cm1.member != 0)
 		/* In a function call, const members can be assigned. */
 		take_const_member(cm1);
@@ -36,7 +36,7 @@ initialize_const_struct_member(void)
 	struct {
 		const_member member;
 	} cm2 = {
-	    /* In an initialization, const members can be assigned. */
+	    /* In a nested initialization, const members can be assigned. */
 	    cm1,
 	};
 	if (cm2.member.member != 0) {

Index: src/tests/usr.bin/xlint/lint1/msg_115.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_115.exp:1.6 src/tests/usr.bin/xlint/lint1/msg_115.exp:1.7
--- src/tests/usr.bin/xlint/lint1/msg_115.exp:1.6	Tue Aug 10 20:43:13 2021
+++ src/tests/usr.bin/xlint/lint1/msg_115.exp	Sat Aug 14 12:46:24 2021
@@ -5,4 +5,3 @@ msg_115.c(13): warning: left operand of 
 msg_115.c(14): warning: left operand of '/=' must be modifiable lvalue [115]
 msg_115.c(15): warning: left operand of '%=' must be modifiable lvalue [115]
 msg_115.c(16): warning: operand of 'x++' must be modifiable lvalue [115]
-msg_115.c(31): warning: left operand of '=' must be modifiable lvalue [115]

Index: src/tests/usr.bin/xlint/lint1/msg_124.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_124.exp:1.9 src/tests/usr.bin/xlint/lint1/msg_124.exp:1.10
--- src/tests/usr.bin/xlint/lint1/msg_124.exp:1.9	Sun Jan 24 11:21:58 2021
+++ src/tests/usr.bin/xlint/lint1/msg_124.exp	Sat Aug 14 12:46:24 2021
@@ -1,6 +1,6 @@
-msg_124.c(18): warning: illegal pointer combination (pointer to function(int) returning void) and (pointer to int), op = [124]
-msg_124.c(19): warning: illegal pointer combination (pointer to function(pointer to function(int) returning void) returning pointer to function(int) returning void) and (pointer to int), op = [124]
-msg_124.c(20): warning: illegal pointer combination (pointer to function(pointer to const char, ...) returning int) and (pointer to int), op = [124]
+msg_124.c(18): warning: illegal pointer combination (pointer to function(int) returning void) and (pointer to int), op init [124]
+msg_124.c(19): warning: illegal pointer combination (pointer to function(pointer to function(int) returning void) returning pointer to function(int) returning void) and (pointer to int), op init [124]
+msg_124.c(20): warning: illegal pointer combination (pointer to function(pointer to const char, ...) returning int) and (pointer to int), op init [124]
 msg_124.c(32): warning: ANSI C forbids comparison of 'void *' with function pointer [274]
 msg_124.c(33): warning: illegal pointer combination (pointer to const char) and (pointer to const int), op == [124]
 msg_124.c(34): warning: illegal pointer combination (pointer to const char) and (pointer to function(int) returning void), op == [124]

Index: src/tests/usr.bin/xlint/lint1/msg_164.c
diff -u src/tests/usr.bin/xlint/lint1/msg_164.c:1.3 src/tests/usr.bin/xlint/lint1/msg_164.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_164.c:1.3	Sun Jan 31 11:12:07 2021
+++ src/tests/usr.bin/xlint/lint1/msg_164.c	Sat Aug 14 12:46:24 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_164.c,v 1.3 2021/01/31 11:12:07 rillig Exp $	*/
+/*	$NetBSD: msg_164.c,v 1.4 2021/08/14 12:46:24 rillig Exp $	*/
 # 3 "msg_164.c"
 
 // Test for message: assignment of negative constant to unsigned type [164]
@@ -6,7 +6,8 @@
 void
 example(void)
 {
-	unsigned char uch = -3;		/* expect: 164 */
+	/* expect+1: warning: initialization of unsigned with negative constant [221] */
+	unsigned char uch = -3;
 
 	uch = -5;			/* expect: 164 */
 	uch += -7;			/* expect: 222 */
Index: src/tests/usr.bin/xlint/lint1/msg_242.c
diff -u src/tests/usr.bin/xlint/lint1/msg_242.c:1.3 src/tests/usr.bin/xlint/lint1/msg_242.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_242.c:1.3	Sat Feb 27 18:01:29 2021
+++ src/tests/usr.bin/xlint/lint1/msg_242.c	Sat Aug 14 12:46:24 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_242.c,v 1.3 2021/02/27 18:01:29 rillig Exp $	*/
+/*	$NetBSD: msg_242.c,v 1.4 2021/08/14 12:46:24 rillig Exp $	*/
 # 3 "msg_242.c"
 
 // Test for message: combination of '%s' and '%s', op %s [242]
@@ -16,10 +16,17 @@ void
 example(enum E e, int i)
 {
 	enum E e2 = e;
-	enum E e3 = i;		/* expect: 242 */
-	int i2 = e;		/* expect: 242 */
+	/* expect+1: warning: initialization of 'enum E' with 'int' [277] */
+	enum E e3 = i;
+	/* expect+1: warning: initialization of 'int' with 'enum E' [277] */
+	int i2 = e;
 	int i3 = i;
 
+	/* expect+1: warning: combination of 'enum E' and 'int', op = [242] */
+	e3 = i;
+	/* expect+1: warning: combination of 'int' and 'enum E', op = [242] */
+	i2 = e;
+
 	sink_enum(e2);
 	sink_enum(e3);
 	sink_int(i2);

Index: src/tests/usr.bin/xlint/lint1/msg_164.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_164.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_164.exp:1.3
--- src/tests/usr.bin/xlint/lint1/msg_164.exp:1.2	Fri Jan  8 21:25:03 2021
+++ src/tests/usr.bin/xlint/lint1/msg_164.exp	Sat Aug 14 12:46:24 2021
@@ -1,4 +1,4 @@
-msg_164.c(9): warning: assignment of negative constant to unsigned type [164]
-msg_164.c(11): warning: assignment of negative constant to unsigned type [164]
-msg_164.c(12): warning: conversion of negative constant to unsigned type [222]
+msg_164.c(10): warning: initialization of unsigned with negative constant [221]
+msg_164.c(12): warning: assignment of negative constant to unsigned type [164]
 msg_164.c(13): warning: conversion of negative constant to unsigned type [222]
+msg_164.c(14): warning: conversion of negative constant to unsigned type [222]
Index: src/tests/usr.bin/xlint/lint1/msg_242.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_242.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_242.exp:1.3
--- src/tests/usr.bin/xlint/lint1/msg_242.exp:1.2	Sat Feb 27 18:01:29 2021
+++ src/tests/usr.bin/xlint/lint1/msg_242.exp	Sat Aug 14 12:46:24 2021
@@ -1,2 +1,4 @@
-msg_242.c(19): warning: combination of 'enum E' and 'int', op = [242]
-msg_242.c(20): warning: combination of 'int' and 'enum E', op = [242]
+msg_242.c(20): warning: initialization of 'enum E' with 'int' [277]
+msg_242.c(22): warning: initialization of 'int' with 'enum E' [277]
+msg_242.c(26): warning: combination of 'enum E' and 'int', op = [242]
+msg_242.c(28): warning: combination of 'int' and 'enum E', op = [242]

Index: src/usr.bin/xlint/lint1/init.c
diff -u src/usr.bin/xlint/lint1/init.c:1.207 src/usr.bin/xlint/lint1/init.c:1.208
--- src/usr.bin/xlint/lint1/init.c:1.207	Tue Aug 10 20:43:12 2021
+++ src/usr.bin/xlint/lint1/init.c	Sat Aug 14 12:46:23 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: init.c,v 1.207 2021/08/10 20:43:12 rillig Exp $	*/
+/*	$NetBSD: init.c,v 1.208 2021/08/14 12:46:23 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: init.c,v 1.207 2021/08/10 20:43:12 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.208 2021/08/14 12:46:23 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -812,12 +812,11 @@ initialization_add_designator(struct ini
 }
 
 /*
- * An object with automatic storage duration that has a single initializer
- * expression without braces and is not an array is initialized by delegating
- * to the ASSIGN operator.
+ * Initialize an object with automatic storage duration that has an
+ * initializer expression without braces.
  */
 static bool
-initialization_expr_using_assign(struct initialization *in, tnode_t *rn)
+initialization_expr_using_op(struct initialization *in, tnode_t *rn)
 {
 	tnode_t *ln, *tn;
 
@@ -828,13 +827,12 @@ initialization_expr_using_assign(struct 
 	if (in->in_sym->s_type->t_tspec == ARRAY)
 		return false;
 
-	debug_step("handing over to ASSIGN");
+	debug_step("handing over to INIT");
 
 	ln = build_name(in->in_sym, 0);
 	ln->tn_type = expr_unqualified_type(ln->tn_type);
 
-	/* TODO: allow 'const' on the left-hand side; see msg_115.c */
-	tn = build_binary(ln, ASSIGN, rn);
+	tn = build_binary(ln, INIT, rn);
 	expr(tn, false, false, false, false);
 
 	return true;
@@ -899,7 +897,7 @@ initialization_expr(struct initializatio
 
 	if (tn == NULL)
 		goto advance;
-	if (initialization_expr_using_assign(in, tn))
+	if (initialization_expr_using_op(in, tn))
 		goto done;
 	if (initialization_init_array_using_string(in, tn))
 		goto advance;

Index: src/usr.bin/xlint/lint1/ops.def
diff -u src/usr.bin/xlint/lint1/ops.def:1.23 src/usr.bin/xlint/lint1/ops.def:1.24
--- src/usr.bin/xlint/lint1/ops.def:1.23	Tue Aug 10 16:59:28 2021
+++ src/usr.bin/xlint/lint1/ops.def	Sat Aug 14 12:46:23 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ops.def,v 1.23 2021/08/10 16:59:28 rillig Exp $ */
+/*	$NetBSD: ops.def,v 1.24 2021/08/14 12:46:23 rillig Exp $ */
 
 begin_ops()
 
@@ -106,7 +106,7 @@ op(	IMAG,	"imag",		-,-,-,-,-,-,-,-,-,-,-
 
 /* INIT, CASE and FARG are pseudo operators that don't appear in the tree. */
 /*	name	repr		b l b B i c a s f v t b s l r p c e e = */
-op(	INIT,	"init",		1,-,1,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-)
+op(	INIT,	"init",		1,-,1,-,-,-,-,-,-,-,-,-,1,-,-,-,-,1,-,-)
 op(	CASE,	"case",		-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-)
 /*
  * FARG is only used temporarily in check_prototype_argument to check type

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.332 src/usr.bin/xlint/lint1/tree.c:1.333
--- src/usr.bin/xlint/lint1/tree.c:1.332	Tue Aug 10 20:43:12 2021
+++ src/usr.bin/xlint/lint1/tree.c	Sat Aug 14 12:46:23 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.332 2021/08/10 20:43:12 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.333 2021/08/14 12:46:23 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.332 2021/08/10 20:43:12 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.333 2021/08/14 12:46:23 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -513,7 +513,7 @@ build_binary(tnode_t *ln, op_t op, tnode
 	 * union member, or if it is not to be assigned to the left operand
 	 */
 	if (mp->m_binary && op != ARROW && op != POINT &&
-	    op != ASSIGN && op != RETURN) {
+	    op != ASSIGN && op != RETURN && op != INIT) {
 		rn = promote(op, false, rn);
 	}
 
@@ -587,6 +587,7 @@ build_binary(tnode_t *ln, op_t op, tnode
 	case XORASS:
 	case ORASS:
 	case RETURN:
+	case INIT:
 		ntn = build_assignment(op, ln, rn);
 		break;
 	case COMMA:
@@ -1520,7 +1521,6 @@ check_assign_types_compatible(op_t op, i
 
 	if (lt == PTR && rt == PTR) {
 		switch (op) {
-		case INIT:
 		case RETURN:
 			warn_incompatible_pointers(NULL, ltp, rtp);
 			break;
@@ -2876,7 +2876,8 @@ build_assignment(op_t op, tnode_t *ln, t
 			rn = fold(rn);
 	}
 
-	if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
+	if ((op == ASSIGN || op == RETURN || op == INIT) &&
+	    (lt == STRUCT || rt == STRUCT)) {
 		lint_assert(lt == rt);
 		lint_assert(ln->tn_type->t_str == rn->tn_type->t_str);
 		if (is_incomplete(ln->tn_type)) {

Reply via email to