Fri Jan 1 20:02:56 2021 UTC ()
lint: add debug logging for initialization using named members


(rillig)
diff -r1.54 -r1.55 src/usr.bin/xlint/lint1/init.c

cvs diff -r1.54 -r1.55 src/usr.bin/xlint/lint1/init.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/init.c 2021/01/01 19:28:51 1.54
+++ src/usr.bin/xlint/lint1/init.c 2021/01/01 20:02:56 1.55
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $ */ 1/* $NetBSD: init.c,v 1.55 2021/01/01 20:02:56 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,30 +27,29 @@ @@ -27,30 +27,29 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: init.c,v 1.54 2021/01/01 19:28:51 rillig Exp $"); 40__RCSID("$NetBSD: init.c,v 1.55 2021/01/01 20:02:56 rillig Exp $");
41#endif 41#endif
42 42
43#include <ctype.h> 
44#include <stdlib.h> 43#include <stdlib.h>
45#include <string.h> 44#include <string.h>
46 45
47#include "lint1.h" 46#include "lint1.h"
48 47
49 48
50/* 49/*
51 * Type of stack which is used for initialisation of aggregate types. 50 * Type of stack which is used for initialisation of aggregate types.
52 * 51 *
53 * XXX: Since C99, a stack is an inappropriate data structure for modelling 52 * XXX: Since C99, a stack is an inappropriate data structure for modelling
54 * an initialization, since the designators don't have to be listed in a 53 * an initialization, since the designators don't have to be listed in a
55 * particular order and can designate parts of sub-objects. The member names 54 * particular order and can designate parts of sub-objects. The member names
56 * of non-leaf structs may thus appear repeatedly, as demonstrated in 55 * of non-leaf structs may thus appear repeatedly, as demonstrated in
@@ -64,26 +63,39 @@ __RCSID("$NetBSD: init.c,v 1.54 2021/01/ @@ -64,26 +63,39 @@ __RCSID("$NetBSD: init.c,v 1.54 2021/01/
64 * selected examples. 63 * selected examples.
65 */ 64 */
66typedef struct istk { 65typedef struct istk {
67 type_t *i_type; /* type of initialisation */ 66 type_t *i_type; /* type of initialisation */
68 type_t *i_subt; /* type of next level */ 67 type_t *i_subt; /* type of next level */
69 u_int i_brace : 1; /* need } for pop */ 68 u_int i_brace : 1; /* need } for pop */
70 u_int i_nolimit : 1; /* incomplete array type */ 69 u_int i_nolimit : 1; /* incomplete array type */
71 u_int i_namedmem : 1; /* has c9x named members */ 70 u_int i_namedmem : 1; /* has c9x named members */
72 sym_t *i_mem; /* next structure member */ 71 sym_t *i_mem; /* next structure member */
73 int i_remaining; /* # of remaining elements */ 72 int i_remaining; /* # of remaining elements */
74 struct istk *i_next; /* previous level */ 73 struct istk *i_next; /* previous level */
75} istk_t; 74} istk_t;
76 75
 76/*
 77 * The names for a nested C99 initialization designator, in a circular list.
 78 *
 79 * Example:
 80 * struct stat st = {
 81 * .st_size = 123,
 82 * .st_mtim.tv_sec = 45,
 83 * .st_mtim.tv_nsec
 84 * };
 85 *
 86 * During initialization, this list first contains ["st_size"], then
 87 * ["st_mtim", "tv_sec"], then ["st_mtim", "tv_nsec"].
 88 */
77typedef struct namlist { 89typedef struct namlist {
78 const char *n_name; 90 const char *n_name;
79 struct namlist *n_prev; 91 struct namlist *n_prev;
80 struct namlist *n_next; 92 struct namlist *n_next;
81} namlist_t; 93} namlist_t;
82 94
83 95
84/* 96/*
85 * initerr is set as soon as a fatal error occurred in an initialisation. 97 * initerr is set as soon as a fatal error occurred in an initialisation.
86 * The effect is that the rest of the initialisation is ignored (parsed 98 * The effect is that the rest of the initialisation is ignored (parsed
87 * by yacc, expression trees built, but no initialisation takes place). 99 * by yacc, expression trees built, but no initialisation takes place).
88 */ 100 */
89int initerr; 101int initerr;
@@ -134,26 +146,41 @@ pop_member(void) @@ -134,26 +146,41 @@ pop_member(void)
134 DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem)); 146 DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem));
135 if (namedmem->n_next == namedmem) { 147 if (namedmem->n_next == namedmem) {
136 free(namedmem); 148 free(namedmem);
137 namedmem = NULL; 149 namedmem = NULL;
138 } else { 150 } else {
139 namlist_t *nam = namedmem; 151 namlist_t *nam = namedmem;
140 namedmem = namedmem->n_next; 152 namedmem = namedmem->n_next;
141 nam->n_prev->n_next = nam->n_next; 153 nam->n_prev->n_next = nam->n_next;
142 nam->n_next->n_prev = nam->n_prev; 154 nam->n_next->n_prev = nam->n_prev;
143 free(nam); 155 free(nam);
144 } 156 }
145} 157}
146 158
 159static void
 160named_member_dprint(void)
 161{
 162 namlist_t *name;
 163
 164 if (namedmem == NULL)
 165 return;
 166 name = namedmem;
 167 DPRINTF(("named member:"));
 168 do {
 169 DPRINTF((" %s", name->n_name));
 170 name = name->n_next;
 171 } while (name != namedmem);
 172 DPRINTF(("\n"));
 173}
147 174
148/* 175/*
149 * Initialize the initialisation stack by putting an entry for the variable 176 * Initialize the initialisation stack by putting an entry for the variable
150 * which is to be initialized on it. 177 * which is to be initialized on it.
151 */ 178 */
152void 179void
153initstack_init(void) 180initstack_init(void)
154{ 181{
155 istk_t *istk; 182 istk_t *istk;
156 183
157 if (initerr) 184 if (initerr)
158 return; 185 return;
159 186
@@ -536,26 +563,28 @@ mkinit(tnode_t *tn) @@ -536,26 +563,28 @@ mkinit(tnode_t *tn)
536 ptrdiff_t offs; 563 ptrdiff_t offs;
537 sym_t *sym; 564 sym_t *sym;
538 tspec_t lt, rt; 565 tspec_t lt, rt;
539 tnode_t *ln; 566 tnode_t *ln;
540 struct mbl *tmem; 567 struct mbl *tmem;
541 scl_t sc; 568 scl_t sc;
542#ifdef DEBUG 569#ifdef DEBUG
543 char buf[64], sbuf[64]; 570 char buf[64], sbuf[64];
544#endif 571#endif
545 572
546 DPRINTF(("%s: type=%s, value=%s\n", __func__, 573 DPRINTF(("%s: type=%s, value=%s\n", __func__,
547 tyname(buf, sizeof(buf), tn->tn_type), 574 tyname(buf, sizeof(buf), tn->tn_type),
548 print_tnode(sbuf, sizeof(sbuf), tn))); 575 print_tnode(sbuf, sizeof(sbuf), tn)));
 576 named_member_dprint();
 577
549 if (initerr || tn == NULL) 578 if (initerr || tn == NULL)
550 return; 579 return;
551 580
552 sc = initsym->s_scl; 581 sc = initsym->s_scl;
553 582
554 /* 583 /*
555 * Do not test for automatic aggregate initialisation. If the 584 * Do not test for automatic aggregate initialisation. If the
556 * initializer starts with a brace we have the warning already. 585 * initializer starts with a brace we have the warning already.
557 * If not, an error will be printed that the initializer must 586 * If not, an error will be printed that the initializer must
558 * be enclosed by braces. 587 * be enclosed by braces.
559 */ 588 */
560 589
561 /* 590 /*