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) */