Module Name:    src
Committed By:   rillig
Date:           Thu Mar 18 14:58:44 UTC 2021

Modified Files:
        src/usr.bin/xlint/lint1: init.c lint1.h

Log Message:
lint: document the initialization of an object in more detail

This will help fixing the bugs that are currently demonstrated in
msg_168.c and d_struct_init_nested.c.


To generate a diff of this commit:
cvs rdiff -u -r1.91 -r1.92 src/usr.bin/xlint/lint1/init.c
cvs rdiff -u -r1.73 -r1.74 src/usr.bin/xlint/lint1/lint1.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/xlint/lint1/init.c
diff -u src/usr.bin/xlint/lint1/init.c:1.91 src/usr.bin/xlint/lint1/init.c:1.92
--- src/usr.bin/xlint/lint1/init.c:1.91	Wed Mar 17 15:45:30 2021
+++ src/usr.bin/xlint/lint1/init.c	Thu Mar 18 14:58:44 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: init.c,v 1.91 2021/03/17 15:45:30 rillig Exp $	*/
+/*	$NetBSD: init.c,v 1.92 2021/03/18 14:58:44 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: init.c,v 1.91 2021/03/17 15:45:30 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.92 2021/03/18 14:58:44 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -64,9 +64,23 @@ __RCSID("$NetBSD: init.c,v 1.91 2021/03/
  */
 typedef	struct initstack_element {
 
-	/* XXX: Why is i_type often null? */
-	type_t	*i_type;		/* type of initialization */
-	type_t	*i_subt;		/* type of next level */
+	/*
+	 * The type to be initialized at this level.
+	 */
+	type_t	*i_type;
+	/*
+	 * The type that is initialized inside a further level of
+	 * braces.  It is completely independent from i_type->t_subt.
+	 *
+	 * For example, in 'int var = { init }', initially there is an
+	 * initstack_element with i_subt == int.  When the '{' is processed,
+	 * an element with i_type == int is pushed to the stack.  When the
+	 * corresponding '}' is processed, the inner element is popped again.
+	 *
+	 * During initialization, only the top 2 elements of the stack are
+	 * looked at.
+	 */
+	type_t	*i_subt;
 
 	/*
 	 * This level of the initializer requires a '}' to be completed.
@@ -607,6 +621,7 @@ again:
 			initstk = inxt;
 			goto again;
 		}
+		/* XXX: Why is this set to 1 unconditionally? */
 		istk->i_remaining = 1;
 		break;
 	}
@@ -639,6 +654,11 @@ check_too_many_initializers(void)
 	initerr = true;
 }
 
+/*
+ * Process a '{' in an initializer by starting the initialization of the
+ * nested data structure, with i_type being the i_subt of the outer
+ * initialization level.
+ */
 static void
 initstack_next_brace(void)
 {
@@ -657,8 +677,9 @@ initstack_next_brace(void)
 		initstack_push();
 	if (!initerr) {
 		initstk->i_brace = true;
-		debug_step("%p %s", namedmem, type_name(
-		    initstk->i_type != NULL ? initstk->i_type
+		debug_named_member();
+		debug_step("expecting type '%s'",
+		    type_name(initstk->i_type != NULL ? initstk->i_type
 			: initstk->i_subt));
 	}
 
@@ -675,6 +696,7 @@ initstack_next_nobrace(void)
 	if (initstk->i_type == NULL && !is_scalar(initstk->i_subt->t_tspec)) {
 		/* {}-enclosed initializer required */
 		error(181);
+		/* XXX: maybe set initerr here */
 	}
 
 	if (!initerr)
@@ -683,7 +705,7 @@ initstack_next_nobrace(void)
 	/*
 	 * Make sure an entry with a scalar type is at the top of the stack.
 	 *
-	 * FIXME: Since C99 an initializer for an object with automatic
+	 * FIXME: Since C99, an initializer for an object with automatic
 	 *  storage need not be a constant expression anymore.  It is
 	 *  perfectly fine to initialize a struct with a struct expression,
 	 *  see d_struct_init_nested.c for a demonstration.
@@ -727,6 +749,10 @@ init_lbrace(void)
 	debug_leave();
 }
 
+/*
+ * Process a '}' in an initializer by finishing the current level of the
+ * initialization stack.
+ */
 void
 init_rbrace(void)
 {
@@ -734,11 +760,7 @@ init_rbrace(void)
 		return;
 
 	debug_enter();
-	debug_initstack();
-
 	initstack_pop_brace();
-
-	debug_initstack();
 	debug_leave();
 }
 
@@ -784,9 +806,9 @@ init_using_expr(tnode_t *tn)
 	scl_t	sclass;
 
 	debug_enter();
+	debug_initstack();
 	debug_named_member();
 	debug_node(tn, debug_ind);
-	debug_initstack();
 
 	if (initerr || tn == NULL) {
 		debug_leave();
@@ -852,7 +874,7 @@ init_using_expr(tnode_t *tn)
 	lt = ln->tn_type->t_tspec;
 	rt = tn->tn_type->t_tspec;
 
-	lint_assert(is_scalar(lt));
+	lint_assert(is_scalar(lt));	/* at least before C99 */
 
 	if (!typeok(INIT, 0, ln, tn)) {
 		debug_initstack();

Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.73 src/usr.bin/xlint/lint1/lint1.h:1.74
--- src/usr.bin/xlint/lint1/lint1.h:1.73	Wed Mar 17 02:24:06 2021
+++ src/usr.bin/xlint/lint1/lint1.h	Thu Mar 18 14:58:44 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.73 2021/03/17 02:24:06 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.74 2021/03/18 14:58:44 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -160,7 +160,7 @@ struct type {
 	bool	t_is_enum : 1;	/* type is (or was) enum (t_enum valid) */
 	bool	t_packed : 1;
 	union {
-		int	_t_dim;		/* dimension */
+		int	_t_dim;		/* dimension (if ARRAY) */
 		struct_or_union	*_t_str;
 		enumeration	*_t_enum;
 		struct	sym *_t_args;	/* arguments (if t_proto) */

Reply via email to