Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/xlint/lint1 lint: document the initialization of an ...



details:   https://anonhg.NetBSD.org/src/rev/2ca2edde3d13
branches:  trunk
changeset: 960401:2ca2edde3d13
user:      rillig <rillig%NetBSD.org@localhost>
date:      Thu Mar 18 14:58:44 2021 +0000

description:
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.

diffstat:

 usr.bin/xlint/lint1/init.c  |  50 ++++++++++++++++++++++++++++++++------------
 usr.bin/xlint/lint1/lint1.h |   4 +-
 2 files changed, 38 insertions(+), 16 deletions(-)

diffs (155 lines):

diff -r 753d24ba129d -r 2ca2edde3d13 usr.bin/xlint/lint1/init.c
--- a/usr.bin/xlint/lint1/init.c        Thu Mar 18 14:05:37 2021 +0000
+++ b/usr.bin/xlint/lint1/init.c        Thu Mar 18 14:58:44 2021 +0000
@@ -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 @@
  */
 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 @@
                        initstk = inxt;
                        goto again;
                }
+               /* XXX: Why is this set to 1 unconditionally? */
                istk->i_remaining = 1;
                break;
        }
@@ -639,6 +654,11 @@
        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_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 @@
        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 @@
        /*
         * 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 @@
        debug_leave();
 }
 
+/*
+ * Process a '}' in an initializer by finishing the current level of the
+ * initialization stack.
+ */
 void
 init_rbrace(void)
 {
@@ -734,11 +760,7 @@
                return;
 
        debug_enter();
-       debug_initstack();
-
        initstack_pop_brace();
-
-       debug_initstack();
        debug_leave();
 }
 
@@ -784,9 +806,9 @@
        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 @@
        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();
diff -r 753d24ba129d -r 2ca2edde3d13 usr.bin/xlint/lint1/lint1.h
--- a/usr.bin/xlint/lint1/lint1.h       Thu Mar 18 14:05:37 2021 +0000
+++ b/usr.bin/xlint/lint1/lint1.h       Thu Mar 18 14:58:44 2021 +0000
@@ -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 @@
        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) */



Home | Main Index | Thread Index | Old Index