Sat Jan 2 18:06:01 2021 UTC ()
lint: add a few more tests

No serious bugs found this time.


(rillig)
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_000.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_000.exp
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_001.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_001.exp
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_002.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_002.exp
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_004.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_004.exp
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_005.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_005.exp
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_085.c
diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_085.exp
diff -r1.100 -r1.101 src/usr.bin/xlint/lint1/decl.c

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_000.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_000.c 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_000.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
1/* $NetBSD: msg_000.c,v 1.1 2021/01/02 10:22:42 rillig Exp $ */ 1/* $NetBSD: msg_000.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_000.c" 2# 3 "msg_000.c"
3 3
4// Test for message: empty declaration [0] 4// Test for message: empty declaration [0]
5 5
6TODO: "Add example code that triggers the above message." 6extern int extern_declared;
7TODO: "Add example code that almost triggers the above message." 7
 8;
 9
 10static int local_defined;

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_000.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_000.exp 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_000.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_001.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_001.c 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_001.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
1/* $NetBSD: msg_001.c,v 1.1 2021/01/02 10:22:42 rillig Exp $ */ 1/* $NetBSD: msg_001.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_001.c" 2# 3 "msg_001.c"
3 3
4// Test for message: old style declaration; add int [1] 4// Test for message: old style declaration; add int [1]
5 5
6TODO: "Add example code that triggers the above message." 6old_style = 1;
7TODO: "Add example code that almost triggers the above message." 7
 8int new_style = 1;

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_001.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_001.exp 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_001.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_002.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_002.c 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_002.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
1/* $NetBSD: msg_002.c,v 1.1 2021/01/02 10:22:42 rillig Exp $ */ 1/* $NetBSD: msg_002.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_002.c" 2# 3 "msg_002.c"
3 3
4// Test for message: empty declaration [2] 4// Test for message: empty declaration [2]
5 5
6TODO: "Add example code that triggers the above message." 6int;
7TODO: "Add example code that almost triggers the above message." 7
 8int local_variable;

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_002.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_002.exp 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_002.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_004.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_004.c 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_004.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,21 @@ @@ -1,7 +1,21 @@
1/* $NetBSD: msg_004.c,v 1.1 2021/01/02 10:22:42 rillig Exp $ */ 1/* $NetBSD: msg_004.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_004.c" 2# 3 "msg_004.c"
3 3
4// Test for message: illegal type combination [4] 4// Test for message: illegal type combination [4]
5 5
6TODO: "Add example code that triggers the above message." 6// XXX: this goes undetected
7TODO: "Add example code that almost triggers the above message." 7signed double signed_double;
 8
 9int ok_int;
 10double ok_double;
 11float _Complex ok_float_complex;
 12
 13int _Complex illegal_int_complex;
 14
 15char enum {
 16 CHAR
 17};
 18
 19long struct {
 20 int member;
 21};

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_004.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_004.exp 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_004.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_005.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_005.c 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_005.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
1/* $NetBSD: msg_005.c,v 1.1 2021/01/02 10:22:42 rillig Exp $ */ 1/* $NetBSD: msg_005.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_005.c" 2# 3 "msg_005.c"
3 3
4// Test for message: modifying typedef with '%s'; only qualifiers allowed [5] 4// Test for message: modifying typedef with '%s'; only qualifiers allowed [5]
5 5
6TODO: "Add example code that triggers the above message." 6typedef int number;
7TODO: "Add example code that almost triggers the above message." 7number long long_variable;
 8number const const_variable;

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_005.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_005.exp 2021/01/02 10:22:42 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_005.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_085.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_085.c 2021/01/02 10:22:43 1.1
+++ src/tests/usr.bin/xlint/lint1/msg_085.c 2021/01/02 18:06:01 1.2
@@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@
1/* $NetBSD: msg_085.c,v 1.1 2021/01/02 10:22:43 rillig Exp $ */ 1/* $NetBSD: msg_085.c,v 1.2 2021/01/02 18:06:01 rillig Exp $ */
2# 3 "msg_085.c" 2# 3 "msg_085.c"
3 3
4// Test for message: dubious tag declaration: %s %s [85] 4// Test for message: dubious tag declaration: %s %s [85]
5 5
6TODO: "Add example code that triggers the above message." 6extern int stat(struct stat *);
7TODO: "Add example code that almost triggers the above message." 7
 8struct ok;
 9extern int ok(struct ok *);

cvs diff -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/Attic/msg_085.exp (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_085.exp 2021/01/02 10:22:43 1.1
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_085.exp 2021/01/02 18:06:01 1.2

cvs diff -r1.100 -r1.101 src/usr.bin/xlint/lint1/decl.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2021/01/02 17:17:00 1.100
+++ src/usr.bin/xlint/lint1/decl.c 2021/01/02 18:06:01 1.101
@@ -1,1398 +1,1398 @@ @@ -1,1398 +1,1398 @@
1/* $NetBSD: decl.c,v 1.100 2021/01/02 17:17:00 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.101 2021/01/02 18:06:01 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project. 19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products 20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission. 21 * derived from this software without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
41__RCSID("$NetBSD: decl.c,v 1.100 2021/01/02 17:17:00 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.101 2021/01/02 18:06:01 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51const char *unnamed = "<unnamed>"; 51const char *unnamed = "<unnamed>";
52 52
53/* shared type structures for arithmtic types and void */ 53/* shared type structures for arithmtic types and void */
54static type_t *typetab; 54static type_t *typetab;
55 55
56/* value of next enumerator during declaration of enum types */ 56/* value of next enumerator during declaration of enum types */
57int enumval; 57int enumval;
58 58
59/* 59/*
60 * pointer to top element of a stack which contains information local 60 * pointer to top element of a stack which contains information local
61 * to nested declarations 61 * to nested declarations
62 */ 62 */
63dinfo_t *dcs; 63dinfo_t *dcs;
64 64
65static type_t *tdeferr(type_t *, tspec_t); 65static type_t *tdeferr(type_t *, tspec_t);
66static void settdsym(type_t *, sym_t *); 66static void settdsym(type_t *, sym_t *);
67static tspec_t merge_type_specifiers(tspec_t, tspec_t); 67static tspec_t merge_type_specifiers(tspec_t, tspec_t);
68static void align(int, int); 68static void align(int, int);
69static sym_t *newtag(sym_t *, scl_t, int, int); 69static sym_t *newtag(sym_t *, scl_t, int, int);
70static int eqargs(type_t *, type_t *, int *); 70static int eqargs(type_t *, type_t *, int *);
71static int mnoarg(type_t *, int *); 71static int mnoarg(type_t *, int *);
72static int check_old_style_definition(sym_t *, sym_t *); 72static int check_old_style_definition(sym_t *, sym_t *);
73static int check_prototype_declaration(sym_t *, sym_t *); 73static int check_prototype_declaration(sym_t *, sym_t *);
74static sym_t *new_style_function(sym_t *, sym_t *); 74static sym_t *new_style_function(sym_t *, sym_t *);
75static void old_style_function(sym_t *, sym_t *); 75static void old_style_function(sym_t *, sym_t *);
76static void ledecl(sym_t *); 76static void ledecl(sym_t *);
77static int check_init(sym_t *); 77static int check_init(sym_t *);
78static void check_argument_usage(int, sym_t *); 78static void check_argument_usage(int, sym_t *);
79static void check_variable_usage(int, sym_t *); 79static void check_variable_usage(int, sym_t *);
80static void check_label_usage(sym_t *); 80static void check_label_usage(sym_t *);
81static void check_tag_usage(sym_t *); 81static void check_tag_usage(sym_t *);
82static void check_global_variable(sym_t *); 82static void check_global_variable(sym_t *);
83static void check_global_variable_size(sym_t *); 83static void check_global_variable_size(sym_t *);
84 84
85/* 85/*
86 * initializes all global vars used in declarations 86 * initializes all global vars used in declarations
87 */ 87 */
88void 88void
89initdecl(void) 89initdecl(void)
90{ 90{
91 int i; 91 int i;
92 92
93 /* declaration stack */ 93 /* declaration stack */
94 dcs = xcalloc(1, sizeof (dinfo_t)); 94 dcs = xcalloc(1, sizeof (dinfo_t));
95 dcs->d_ctx = EXTERN; 95 dcs->d_ctx = EXTERN;
96 dcs->d_ldlsym = &dcs->d_dlsyms; 96 dcs->d_ldlsym = &dcs->d_dlsyms;
97 97
98 /* type information and classification */ 98 /* type information and classification */
99 inittyp(); 99 inittyp();
100 100
101 /* shared type structures */ 101 /* shared type structures */
102 typetab = xcalloc(NTSPEC, sizeof (type_t)); 102 typetab = xcalloc(NTSPEC, sizeof (type_t));
103 for (i = 0; i < NTSPEC; i++) 103 for (i = 0; i < NTSPEC; i++)
104 typetab[i].t_tspec = NOTSPEC; 104 typetab[i].t_tspec = NOTSPEC;
105 typetab[BOOL].t_tspec = BOOL; 105 typetab[BOOL].t_tspec = BOOL;
106 typetab[CHAR].t_tspec = CHAR; 106 typetab[CHAR].t_tspec = CHAR;
107 typetab[SCHAR].t_tspec = SCHAR; 107 typetab[SCHAR].t_tspec = SCHAR;
108 typetab[UCHAR].t_tspec = UCHAR; 108 typetab[UCHAR].t_tspec = UCHAR;
109 typetab[SHORT].t_tspec = SHORT; 109 typetab[SHORT].t_tspec = SHORT;
110 typetab[USHORT].t_tspec = USHORT; 110 typetab[USHORT].t_tspec = USHORT;
111 typetab[INT].t_tspec = INT; 111 typetab[INT].t_tspec = INT;
112 typetab[UINT].t_tspec = UINT; 112 typetab[UINT].t_tspec = UINT;
113 typetab[LONG].t_tspec = LONG; 113 typetab[LONG].t_tspec = LONG;
114 typetab[ULONG].t_tspec = ULONG; 114 typetab[ULONG].t_tspec = ULONG;
115 typetab[QUAD].t_tspec = QUAD; 115 typetab[QUAD].t_tspec = QUAD;
116 typetab[UQUAD].t_tspec = UQUAD; 116 typetab[UQUAD].t_tspec = UQUAD;
117 typetab[FLOAT].t_tspec = FLOAT; 117 typetab[FLOAT].t_tspec = FLOAT;
118 typetab[DOUBLE].t_tspec = DOUBLE; 118 typetab[DOUBLE].t_tspec = DOUBLE;
119 typetab[LDOUBLE].t_tspec = LDOUBLE; 119 typetab[LDOUBLE].t_tspec = LDOUBLE;
120 typetab[FCOMPLEX].t_tspec = FCOMPLEX; 120 typetab[FCOMPLEX].t_tspec = FCOMPLEX;
121 typetab[DCOMPLEX].t_tspec = DCOMPLEX; 121 typetab[DCOMPLEX].t_tspec = DCOMPLEX;
122 typetab[LCOMPLEX].t_tspec = LCOMPLEX; 122 typetab[LCOMPLEX].t_tspec = LCOMPLEX;
123 typetab[COMPLEX].t_tspec = COMPLEX; 123 typetab[COMPLEX].t_tspec = COMPLEX;
124 typetab[VOID].t_tspec = VOID; 124 typetab[VOID].t_tspec = VOID;
125 /* 125 /*
126 * Next two are not real types. They are only used by the parser 126 * Next two are not real types. They are only used by the parser
127 * to return keywords "signed" and "unsigned" 127 * to return keywords "signed" and "unsigned"
128 */ 128 */
129 typetab[SIGNED].t_tspec = SIGNED; 129 typetab[SIGNED].t_tspec = SIGNED;
130 typetab[UNSIGN].t_tspec = UNSIGN; 130 typetab[UNSIGN].t_tspec = UNSIGN;
131} 131}
132 132
133/* 133/*
134 * Returns a shared type structure for arithmetic types and void. 134 * Returns a shared type structure for arithmetic types and void.
135 * 135 *
136 * It's important to duplicate this structure (using duptyp() or tduptyp()) 136 * It's important to duplicate this structure (using duptyp() or tduptyp())
137 * if it is to be modified (adding qualifiers or anything else). 137 * if it is to be modified (adding qualifiers or anything else).
138 */ 138 */
139type_t * 139type_t *
140gettyp(tspec_t t) 140gettyp(tspec_t t)
141{ 141{
142 142
143 return &typetab[t]; 143 return &typetab[t];
144} 144}
145 145
146type_t * 146type_t *
147duptyp(const type_t *tp) 147duptyp(const type_t *tp)
148{ 148{
149 type_t *ntp; 149 type_t *ntp;
150 150
151 ntp = getblk(sizeof (type_t)); 151 ntp = getblk(sizeof (type_t));
152 *ntp = *tp; 152 *ntp = *tp;
153 return ntp; 153 return ntp;
154} 154}
155 155
156/* 156/*
157 * Use tduptyp() instead of duptyp() inside expressions (if the 157 * Use tduptyp() instead of duptyp() inside expressions (if the
158 * allocated memory should be freed after the expr). 158 * allocated memory should be freed after the expr).
159 */ 159 */
160type_t * 160type_t *
161tduptyp(const type_t *tp) 161tduptyp(const type_t *tp)
162{ 162{
163 type_t *ntp; 163 type_t *ntp;
164 164
165 ntp = tgetblk(sizeof (type_t)); 165 ntp = tgetblk(sizeof (type_t));
166 *ntp = *tp; 166 *ntp = *tp;
167 return ntp; 167 return ntp;
168} 168}
169 169
170/* 170/*
171 * Returns 1 if the argument is void or an incomplete array, 171 * Returns 1 if the argument is void or an incomplete array,
172 * struct, union or enum type. 172 * struct, union or enum type.
173 */ 173 */
174int 174int
175incompl(type_t *tp) 175incompl(type_t *tp)
176{ 176{
177 tspec_t t; 177 tspec_t t;
178 178
179 if ((t = tp->t_tspec) == VOID) { 179 if ((t = tp->t_tspec) == VOID) {
180 return 1; 180 return 1;
181 } else if (t == ARRAY) { 181 } else if (t == ARRAY) {
182 return tp->t_aincompl; 182 return tp->t_aincompl;
183 } else if (t == STRUCT || t == UNION) { 183 } else if (t == STRUCT || t == UNION) {
184 return tp->t_str->sincompl; 184 return tp->t_str->sincompl;
185 } else if (t == ENUM) { 185 } else if (t == ENUM) {
186 return tp->t_enum->eincompl; 186 return tp->t_enum->eincompl;
187 } 187 }
188 return 0; 188 return 0;
189} 189}
190 190
191/* 191/*
192 * Mark an array, struct, union or enum type as complete or incomplete. 192 * Mark an array, struct, union or enum type as complete or incomplete.
193 */ 193 */
194void 194void
195setcomplete(type_t *tp, int complete) 195setcomplete(type_t *tp, int complete)
196{ 196{
197 tspec_t t; 197 tspec_t t;
198 198
199 if ((t = tp->t_tspec) == ARRAY) { 199 if ((t = tp->t_tspec) == ARRAY) {
200 tp->t_aincompl = !complete; 200 tp->t_aincompl = !complete;
201 } else if (t == STRUCT || t == UNION) { 201 } else if (t == STRUCT || t == UNION) {
202 tp->t_str->sincompl = !complete; 202 tp->t_str->sincompl = !complete;
203 } else { 203 } else {
204 lint_assert(t == ENUM); 204 lint_assert(t == ENUM);
205 tp->t_enum->eincompl = !complete; 205 tp->t_enum->eincompl = !complete;
206 } 206 }
207} 207}
208 208
209/* 209/*
210 * Remember the storage class of the current declaration in dcs->d_scl 210 * Remember the storage class of the current declaration in dcs->d_scl
211 * (the top element of the declaration stack) and detect multiple 211 * (the top element of the declaration stack) and detect multiple
212 * storage classes. 212 * storage classes.
213 */ 213 */
214void 214void
215add_storage_class(scl_t sc) 215add_storage_class(scl_t sc)
216{ 216{
217 217
218 if (sc == INLINE) { 218 if (sc == INLINE) {
219 if (dcs->d_inline) 219 if (dcs->d_inline)
220 /* duplicate '%s' */ 220 /* duplicate '%s' */
221 warning(10, "inline"); 221 warning(10, "inline");
222 dcs->d_inline = 1; 222 dcs->d_inline = 1;
223 return; 223 return;
224 } 224 }
225 if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || 225 if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
226 dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) { 226 dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) {
227 /* storage class after type is obsolescent */ 227 /* storage class after type is obsolescent */
228 warning(83); 228 warning(83);
229 } 229 }
230 if (dcs->d_scl == NOSCL) { 230 if (dcs->d_scl == NOSCL) {
231 dcs->d_scl = sc; 231 dcs->d_scl = sc;
232 } else { 232 } else {
233 /* 233 /*
234 * multiple storage classes. An error will be reported in 234 * multiple storage classes. An error will be reported in
235 * deftyp(). 235 * deftyp().
236 */ 236 */
237 dcs->d_mscl = 1; 237 dcs->d_mscl = 1;
238 } 238 }
239} 239}
240 240
241/* 241/*
242 * Remember the type, modifier or typedef name returned by the parser 242 * Remember the type, modifier or typedef name returned by the parser
243 * in *dcs (top element of decl stack). This information is used in 243 * in *dcs (top element of decl stack). This information is used in
244 * deftyp() to build the type used for all declarators in this 244 * deftyp() to build the type used for all declarators in this
245 * declaration. 245 * declaration.
246 * 246 *
247 * If tp->t_typedef is 1, the type comes from a previously defined typename. 247 * If tp->t_typedef is 1, the type comes from a previously defined typename.
248 * Otherwise it comes from a type specifier (int, long, ...) or a 248 * Otherwise it comes from a type specifier (int, long, ...) or a
249 * struct/union/enum tag. 249 * struct/union/enum tag.
250 */ 250 */
251void 251void
252add_type(type_t *tp) 252add_type(type_t *tp)
253{ 253{
254 tspec_t t; 254 tspec_t t;
255#ifdef DEBUG 255#ifdef DEBUG
256 printf("%s: %s\n", __func__, type_name(tp)); 256 printf("%s: %s\n", __func__, type_name(tp));
257#endif 257#endif
258 if (tp->t_typedef) { 258 if (tp->t_typedef) {
259 /* 259 /*
260 * something like "typedef int a; int a b;" 260 * something like "typedef int a; int a b;"
261 * This should not happen with current grammar. 261 * This should not happen with current grammar.
262 */ 262 */
263 lint_assert(dcs->d_type == NULL); 263 lint_assert(dcs->d_type == NULL);
264 lint_assert(dcs->d_atyp == NOTSPEC); 264 lint_assert(dcs->d_atyp == NOTSPEC);
265 lint_assert(dcs->d_lmod == NOTSPEC); 265 lint_assert(dcs->d_lmod == NOTSPEC);
266 lint_assert(dcs->d_smod == NOTSPEC); 266 lint_assert(dcs->d_smod == NOTSPEC);
267 267
268 dcs->d_type = tp; 268 dcs->d_type = tp;
269 return; 269 return;
270 } 270 }
271 271
272 t = tp->t_tspec; 272 t = tp->t_tspec;
273 273
274 if (t == STRUCT || t == UNION || t == ENUM) { 274 if (t == STRUCT || t == UNION || t == ENUM) {
275 /* 275 /*
276 * something like "int struct a ..." 276 * something like "int struct a ..."
277 * struct/union/enum with anything else is not allowed 277 * struct/union/enum with anything else is not allowed
278 */ 278 */
279 if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || 279 if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
280 dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) { 280 dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
281 /* 281 /*
282 * remember that an error must be reported in 282 * remember that an error must be reported in
283 * deftyp(). 283 * deftyp().
284 */ 284 */
285 dcs->d_terr = 1; 285 dcs->d_terr = 1;
286 dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC; 286 dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC;
287 } 287 }
288 dcs->d_type = tp; 288 dcs->d_type = tp;
289 return; 289 return;
290 } 290 }
291 291
292 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { 292 if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
293 /* 293 /*
294 * something like "struct a int" 294 * something like "struct a int"
295 * struct/union/enum with anything else is not allowed 295 * struct/union/enum with anything else is not allowed
296 */ 296 */
297 dcs->d_terr = 1; 297 dcs->d_terr = 1;
298 return; 298 return;
299 } 299 }
300 300
301 if (t == COMPLEX) { 301 if (t == COMPLEX) {
302 if (dcs->d_cmod == FLOAT) 302 if (dcs->d_cmod == FLOAT)
303 t = FCOMPLEX; 303 t = FCOMPLEX;
304 else if (dcs->d_cmod == DOUBLE) 304 else if (dcs->d_cmod == DOUBLE)
305 t = DCOMPLEX; 305 t = DCOMPLEX;
306 else { 306 else {
307 /* Invalid type for _Complex */ 307 /* Invalid type for _Complex */
308 error(308); 308 error(308);
309 t = DCOMPLEX; /* just as a fallback */ 309 t = DCOMPLEX; /* just as a fallback */
310 } 310 }
311 dcs->d_cmod = NOTSPEC; 311 dcs->d_cmod = NOTSPEC;
312 } 312 }
313 313
314 if (t == LONG && dcs->d_lmod == LONG) { 314 if (t == LONG && dcs->d_lmod == LONG) {
315 /* "long long" or "long ... long" */ 315 /* "long long" or "long ... long" */
316 t = QUAD; 316 t = QUAD;
317 dcs->d_lmod = NOTSPEC; 317 dcs->d_lmod = NOTSPEC;
318 if (!quadflg) 318 if (!quadflg)
319 /* %s C does not support 'long long' */ 319 /* %s C does not support 'long long' */
320 (void)c99ism(265, tflag ? "traditional" : "c89"); 320 (void)c99ism(265, tflag ? "traditional" : "c89");
321 } 321 }
322 322
323 if (dcs->d_type != NULL && dcs->d_type->t_typedef) { 323 if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
324 /* something like "typedef int a; a long ..." */ 324 /* something like "typedef int a; a long ..." */
325 dcs->d_type = tdeferr(dcs->d_type, t); 325 dcs->d_type = tdeferr(dcs->d_type, t);
326 return; 326 return;
327 } 327 }
328 328
329 /* now it can be only a combination of arithmetic types and void */ 329 /* now it can be only a combination of arithmetic types and void */
330 if (t == SIGNED || t == UNSIGN) { 330 if (t == SIGNED || t == UNSIGN) {
331 /* remember specifiers "signed" & "unsigned" in dcs->d_smod */ 331 /* remember specifiers "signed" & "unsigned" in dcs->d_smod */
332 if (dcs->d_smod != NOTSPEC) 332 if (dcs->d_smod != NOTSPEC)
333 /* 333 /*
334 * more than one "signed" and/or "unsigned"; print 334 * more than one "signed" and/or "unsigned"; print
335 * an error in deftyp() 335 * an error in deftyp()
336 */ 336 */
337 dcs->d_terr = 1; 337 dcs->d_terr = 1;
338 dcs->d_smod = t; 338 dcs->d_smod = t;
339 } else if (t == SHORT || t == LONG || t == QUAD) { 339 } else if (t == SHORT || t == LONG || t == QUAD) {
340 /* 340 /*
341 * remember specifiers "short", "long" and "long long" in 341 * remember specifiers "short", "long" and "long long" in
342 * dcs->d_lmod 342 * dcs->d_lmod
343 */ 343 */
344 if (dcs->d_lmod != NOTSPEC) 344 if (dcs->d_lmod != NOTSPEC)
345 /* more than one, print error in deftyp() */ 345 /* more than one, print error in deftyp() */
346 dcs->d_terr = 1; 346 dcs->d_terr = 1;
347 dcs->d_lmod = t; 347 dcs->d_lmod = t;
348 } else if (t == FLOAT || t == DOUBLE) { 348 } else if (t == FLOAT || t == DOUBLE) {
349 if (dcs->d_lmod == NOTSPEC || dcs->d_lmod == LONG) { 349 if (dcs->d_lmod == NOTSPEC || dcs->d_lmod == LONG) {
350 if (dcs->d_cmod != NOTSPEC 350 if (dcs->d_cmod != NOTSPEC
351 || (t == FLOAT && dcs->d_lmod == LONG)) 351 || (t == FLOAT && dcs->d_lmod == LONG))
352 dcs->d_terr = 1; 352 dcs->d_terr = 1;
353 dcs->d_cmod = t; 353 dcs->d_cmod = t;
354 } else { 354 } else {
355 if (dcs->d_atyp != NOTSPEC) 355 if (dcs->d_atyp != NOTSPEC)
356 dcs->d_terr = 1; 356 dcs->d_terr = 1;
357 dcs->d_atyp = t; 357 dcs->d_atyp = t;
358 } 358 }
359 } else if (t == PTR) { 359 } else if (t == PTR) {
360 dcs->d_type = tp; 360 dcs->d_type = tp;
361 } else { 361 } else {
362 /* 362 /*
363 * remember specifiers "void", "char", "int", 363 * remember specifiers "void", "char", "int",
364 * or "_Complex" int dcs->d_atyp 364 * or "_Complex" int dcs->d_atyp
365 */ 365 */
366 if (dcs->d_atyp != NOTSPEC) 366 if (dcs->d_atyp != NOTSPEC)
367 /* more than one, print error in deftyp() */ 367 /* more than one, print error in deftyp() */
368 dcs->d_terr = 1; 368 dcs->d_terr = 1;
369 dcs->d_atyp = t; 369 dcs->d_atyp = t;
370 } 370 }
371} 371}
372 372
373/* 373/*
374 * called if a list of declaration specifiers contains a typedef name 374 * called if a list of declaration specifiers contains a typedef name
375 * and other specifiers (except struct, union, enum, typedef name) 375 * and other specifiers (except struct, union, enum, typedef name)
376 */ 376 */
377static type_t * 377static type_t *
378tdeferr(type_t *td, tspec_t t) 378tdeferr(type_t *td, tspec_t t)
379{ 379{
380 tspec_t t2; 380 tspec_t t2;
381 381
382 t2 = td->t_tspec; 382 t2 = td->t_tspec;
383 383
384 switch (t) { 384 switch (t) {
385 case SIGNED: 385 case SIGNED:
386 case UNSIGN: 386 case UNSIGN:
387 if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG || 387 if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
388 t2 == QUAD) { 388 t2 == QUAD) {
389 if (!tflag) 389 if (!tflag)
390 /* modifying typedef with ... */ 390 /* modifying typedef with '%s'; only ... */
391 warning(5, ttab[t].tt_name); 391 warning(5, ttab[t].tt_name);
392 td = duptyp(gettyp(merge_type_specifiers(t2, t))); 392 td = duptyp(gettyp(merge_type_specifiers(t2, t)));
393 td->t_typedef = 1; 393 td->t_typedef = 1;
394 return td; 394 return td;
395 } 395 }
396 break; 396 break;
397 case SHORT: 397 case SHORT:
398 if (t2 == INT || t2 == UINT) { 398 if (t2 == INT || t2 == UINT) {
399 /* modifying typedef with ... */ 399 /* modifying typedef with '%s'; only qualifiers ... */
400 warning(5, "short"); 400 warning(5, "short");
401 td = duptyp(gettyp(t2 == INT ? SHORT : USHORT)); 401 td = duptyp(gettyp(t2 == INT ? SHORT : USHORT));
402 td->t_typedef = 1; 402 td->t_typedef = 1;
403 return td; 403 return td;
404 } 404 }
405 break; 405 break;
406 case LONG: 406 case LONG:
407 if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG || 407 if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
408 t2 == FLOAT || t2 == DOUBLE || t2 == DCOMPLEX) { 408 t2 == FLOAT || t2 == DOUBLE || t2 == DCOMPLEX) {
409 /* modifying typedef with ... */ 409 /* modifying typedef with ... */
410 warning(5, "long"); 410 warning(5, "long");
411 if (t2 == INT) { 411 if (t2 == INT) {
412 td = gettyp(LONG); 412 td = gettyp(LONG);
413 } else if (t2 == UINT) { 413 } else if (t2 == UINT) {
414 td = gettyp(ULONG); 414 td = gettyp(ULONG);
415 } else if (t2 == LONG) { 415 } else if (t2 == LONG) {
416 td = gettyp(QUAD); 416 td = gettyp(QUAD);
417 } else if (t2 == ULONG) { 417 } else if (t2 == ULONG) {
418 td = gettyp(UQUAD); 418 td = gettyp(UQUAD);
419 } else if (t2 == FLOAT) { 419 } else if (t2 == FLOAT) {
420 td = gettyp(DOUBLE); 420 td = gettyp(DOUBLE);
421 } else if (t2 == DOUBLE) { 421 } else if (t2 == DOUBLE) {
422 td = gettyp(LDOUBLE); 422 td = gettyp(LDOUBLE);
423 } else if (t2 == DCOMPLEX) { 423 } else if (t2 == DCOMPLEX) {
424 td = gettyp(LCOMPLEX); 424 td = gettyp(LCOMPLEX);
425 } 425 }
426 td = duptyp(td); 426 td = duptyp(td);
427 td->t_typedef = 1; 427 td->t_typedef = 1;
428 return td; 428 return td;
429 } 429 }
430 break; 430 break;
431 /* LINTED206: (enumeration values not handled in switch) */ 431 /* LINTED206: (enumeration values not handled in switch) */
432 case NOTSPEC: 432 case NOTSPEC:
433 case USHORT: 433 case USHORT:
434 case UCHAR: 434 case UCHAR:
435 case SCHAR: 435 case SCHAR:
436 case CHAR: 436 case CHAR:
437 case BOOL: 437 case BOOL:
438 case FUNC: 438 case FUNC:
439 case ARRAY: 439 case ARRAY:
440 case PTR: 440 case PTR:
441 case ENUM: 441 case ENUM:
442 case UNION: 442 case UNION:
443 case STRUCT: 443 case STRUCT:
444 case VOID: 444 case VOID:
445 case LDOUBLE: 445 case LDOUBLE:
446 case FLOAT: 446 case FLOAT:
447 case DOUBLE: 447 case DOUBLE:
448 case UQUAD: 448 case UQUAD:
449 case QUAD: 449 case QUAD:
450#ifdef INT128_SIZE 450#ifdef INT128_SIZE
451 case UINT128: 451 case UINT128:
452 case INT128: 452 case INT128:
453#endif 453#endif
454 case ULONG: 454 case ULONG:
455 case UINT: 455 case UINT:
456 case INT: 456 case INT:
457 case FCOMPLEX: 457 case FCOMPLEX:
458 case DCOMPLEX: 458 case DCOMPLEX:
459 case LCOMPLEX: 459 case LCOMPLEX:
460 case COMPLEX: 460 case COMPLEX:
461 break; 461 break;
462 } 462 }
463 463
464 /* Anything other is not accepted. */ 464 /* Anything other is not accepted. */
465 465
466 dcs->d_terr = 1; 466 dcs->d_terr = 1;
467 return td; 467 return td;
468} 468}
469 469
470/* 470/*
471 * Remember the symbol of a typedef name (2nd arg) in a struct, union 471 * Remember the symbol of a typedef name (2nd arg) in a struct, union
472 * or enum tag if the typedef name is the first defined for this tag. 472 * or enum tag if the typedef name is the first defined for this tag.
473 * 473 *
474 * If the tag is unnamed, the typdef name is used for identification 474 * If the tag is unnamed, the typdef name is used for identification
475 * of this tag in lint2. Although it's possible that more than one typedef 475 * of this tag in lint2. Although it's possible that more than one typedef
476 * name is defined for one tag, the first name defined should be unique 476 * name is defined for one tag, the first name defined should be unique
477 * if the tag is unnamed. 477 * if the tag is unnamed.
478 */ 478 */
479static void 479static void
480settdsym(type_t *tp, sym_t *sym) 480settdsym(type_t *tp, sym_t *sym)
481{ 481{
482 tspec_t t; 482 tspec_t t;
483 483
484 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 484 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
485 if (tp->t_str->stdef == NULL) 485 if (tp->t_str->stdef == NULL)
486 tp->t_str->stdef = sym; 486 tp->t_str->stdef = sym;
487 } else if (t == ENUM) { 487 } else if (t == ENUM) {
488 if (tp->t_enum->etdef == NULL) 488 if (tp->t_enum->etdef == NULL)
489 tp->t_enum->etdef = sym; 489 tp->t_enum->etdef = sym;
490 } 490 }
491} 491}
492 492
493static size_t 493static size_t
494bitfieldsize(sym_t **mem) 494bitfieldsize(sym_t **mem)
495{ 495{
496 size_t len = (*mem)->s_type->t_flen; 496 size_t len = (*mem)->s_type->t_flen;
497 while (*mem && (*mem)->s_type->t_isfield) { 497 while (*mem && (*mem)->s_type->t_isfield) {
498 len += (*mem)->s_type->t_flen; 498 len += (*mem)->s_type->t_flen;
499 *mem = (*mem)->s_next; 499 *mem = (*mem)->s_next;
500 } 500 }
501 return ((len + INT_SIZE - 1) / INT_SIZE) * INT_SIZE; 501 return ((len + INT_SIZE - 1) / INT_SIZE) * INT_SIZE;
502} 502}
503 503
504static void 504static void
505setpackedsize(type_t *tp) 505setpackedsize(type_t *tp)
506{ 506{
507 str_t *sp; 507 str_t *sp;
508 sym_t *mem; 508 sym_t *mem;
509 509
510 switch (tp->t_tspec) { 510 switch (tp->t_tspec) {
511 case STRUCT: 511 case STRUCT:
512 case UNION: 512 case UNION:
513 sp = tp->t_str; 513 sp = tp->t_str;
514 sp->size = 0; 514 sp->size = 0;
515 for (mem = sp->memb; mem != NULL; mem = mem->s_next) { 515 for (mem = sp->memb; mem != NULL; mem = mem->s_next) {
516 if (mem->s_type->t_isfield) { 516 if (mem->s_type->t_isfield) {
517 sp->size += bitfieldsize(&mem); 517 sp->size += bitfieldsize(&mem);
518 if (mem == NULL) 518 if (mem == NULL)
519 break; 519 break;
520 } 520 }
521 size_t x = (size_t)tsize(mem->s_type); 521 size_t x = (size_t)tsize(mem->s_type);
522 if (tp->t_tspec == STRUCT) 522 if (tp->t_tspec == STRUCT)
523 sp->size += x; 523 sp->size += x;
524 else if (x > sp->size) 524 else if (x > sp->size)
525 sp->size = x; 525 sp->size = x;
526 } 526 }
527 break; 527 break;
528 default: 528 default:
529 /* %s attribute ignored for %s */ 529 /* %s attribute ignored for %s */
530 warning(326, "packed", type_name(tp)); 530 warning(326, "packed", type_name(tp));
531 break; 531 break;
532 } 532 }
533} 533}
534 534
535void 535void
536addpacked(void) 536addpacked(void)
537{ 537{
538 if (dcs->d_type == NULL) 538 if (dcs->d_type == NULL)
539 dcs->d_ispacked = 1; 539 dcs->d_ispacked = 1;
540 else 540 else
541 setpackedsize(dcs->d_type); 541 setpackedsize(dcs->d_type);
542} 542}
543 543
544void 544void
545add_attr_used(void) 545add_attr_used(void)
546{ 546{
547 dcs->d_used = 1; 547 dcs->d_used = 1;
548} 548}
549 549
550/* 550/*
551 * Remember a qualifier which is part of the declaration specifiers 551 * Remember a qualifier which is part of the declaration specifiers
552 * (and not the declarator) in the top element of the declaration stack. 552 * (and not the declarator) in the top element of the declaration stack.
553 * Also detect multiple qualifiers of the same kind. 553 * Also detect multiple qualifiers of the same kind.
554 554
555 * The remembered qualifier is used by deftyp() to construct the type 555 * The remembered qualifier is used by deftyp() to construct the type
556 * for all declarators. 556 * for all declarators.
557 */ 557 */
558void 558void
559add_qualifier(tqual_t q) 559add_qualifier(tqual_t q)
560{ 560{
561 561
562 if (q == CONST) { 562 if (q == CONST) {
563 if (dcs->d_const) { 563 if (dcs->d_const) {
564 /* duplicate '%s' */ 564 /* duplicate '%s' */
565 warning(10, "const"); 565 warning(10, "const");
566 } 566 }
567 dcs->d_const = 1; 567 dcs->d_const = 1;
568 } else { 568 } else {
569 if (q == THREAD) 569 if (q == THREAD)
570 return; 570 return;
571 lint_assert(q == VOLATILE); 571 lint_assert(q == VOLATILE);
572 if (dcs->d_volatile) { 572 if (dcs->d_volatile) {
573 /* duplicate '%s' */ 573 /* duplicate '%s' */
574 warning(10, "volatile"); 574 warning(10, "volatile");
575 } 575 }
576 dcs->d_volatile = 1; 576 dcs->d_volatile = 1;
577 } 577 }
578} 578}
579 579
580/* 580/*
581 * Go to the next declaration level (structs, nested structs, blocks, 581 * Go to the next declaration level (structs, nested structs, blocks,
582 * argument declaration lists ...) 582 * argument declaration lists ...)
583 */ 583 */
584void 584void
585pushdecl(scl_t sc) 585pushdecl(scl_t sc)
586{ 586{
587 dinfo_t *di; 587 dinfo_t *di;
588 588
589 /* put a new element on the declaration stack */ 589 /* put a new element on the declaration stack */
590 di = xcalloc(1, sizeof (dinfo_t)); 590 di = xcalloc(1, sizeof (dinfo_t));
591 di->d_next = dcs; 591 di->d_next = dcs;
592 dcs = di; 592 dcs = di;
593 di->d_ctx = sc; 593 di->d_ctx = sc;
594 di->d_ldlsym = &di->d_dlsyms; 594 di->d_ldlsym = &di->d_dlsyms;
595 if (dflag) 595 if (dflag)
596 (void)printf("pushdecl(%p %d)\n", dcs, (int)sc); 596 (void)printf("pushdecl(%p %d)\n", dcs, (int)sc);
597 597
598} 598}
599 599
600/* 600/*
601 * Go back to previous declaration level 601 * Go back to previous declaration level
602 */ 602 */
603void 603void
604popdecl(void) 604popdecl(void)
605{ 605{
606 dinfo_t *di; 606 dinfo_t *di;
607 607
608 if (dflag) 608 if (dflag)
609 (void)printf("popdecl(%p %d)\n", dcs, (int)dcs->d_ctx); 609 (void)printf("popdecl(%p %d)\n", dcs, (int)dcs->d_ctx);
610 610
611 lint_assert(dcs->d_next != NULL); 611 lint_assert(dcs->d_next != NULL);
612 di = dcs; 612 di = dcs;
613 dcs = di->d_next; 613 dcs = di->d_next;
614 switch (di->d_ctx) { 614 switch (di->d_ctx) {
615 case MOS: 615 case MOS:
616 case MOU: 616 case MOU:
617 case ENUMCON: 617 case ENUMCON:
618 /* 618 /*
619 * Symbols declared in (nested) structs or enums are 619 * Symbols declared in (nested) structs or enums are
620 * part of the next level (they are removed from the 620 * part of the next level (they are removed from the
621 * symbol table if the symbols of the outher level are 621 * symbol table if the symbols of the outher level are
622 * removed). 622 * removed).
623 */ 623 */
624 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) 624 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
625 dcs->d_ldlsym = di->d_ldlsym; 625 dcs->d_ldlsym = di->d_ldlsym;
626 break; 626 break;
627 case ARG: 627 case ARG:
628 /* 628 /*
629 * All symbols in dcs->d_dlsyms are introduced in old style 629 * All symbols in dcs->d_dlsyms are introduced in old style
630 * argument declarations (it's not clean, but possible). 630 * argument declarations (it's not clean, but possible).
631 * They are appended to the list of symbols declared in 631 * They are appended to the list of symbols declared in
632 * an old style argument identifier list or a new style 632 * an old style argument identifier list or a new style
633 * parameter type list. 633 * parameter type list.
634 */ 634 */
635 if (di->d_dlsyms != NULL) { 635 if (di->d_dlsyms != NULL) {
636 *di->d_ldlsym = dcs->d_fpsyms; 636 *di->d_ldlsym = dcs->d_fpsyms;
637 dcs->d_fpsyms = di->d_dlsyms; 637 dcs->d_fpsyms = di->d_dlsyms;
638 } 638 }
639 break; 639 break;
640 case ABSTRACT: 640 case ABSTRACT:
641 /* 641 /*
642 * casts and sizeof 642 * casts and sizeof
643 * Append all symbols declared in the abstract declaration 643 * Append all symbols declared in the abstract declaration
644 * to the list of symbols declared in the surrounding 644 * to the list of symbols declared in the surrounding
645 * declaration or block. 645 * declaration or block.
646 * XXX I'm not sure whether they should be removed from the 646 * XXX I'm not sure whether they should be removed from the
647 * symbol table now or later. 647 * symbol table now or later.
648 */ 648 */
649 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) 649 if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
650 dcs->d_ldlsym = di->d_ldlsym; 650 dcs->d_ldlsym = di->d_ldlsym;
651 break; 651 break;
652 case AUTO: 652 case AUTO:
653 /* check usage of local vars */ 653 /* check usage of local vars */
654 check_usage(di); 654 check_usage(di);
655 /* FALLTHROUGH */ 655 /* FALLTHROUGH */
656 case PARG: 656 case PARG:
657 /* usage of arguments will be checked by funcend() */ 657 /* usage of arguments will be checked by funcend() */
658 rmsyms(di->d_dlsyms); 658 rmsyms(di->d_dlsyms);
659 break; 659 break;
660 case EXTERN: 660 case EXTERN:
661 /* there is nothing after external declarations */ 661 /* there is nothing after external declarations */
662 /* FALLTHROUGH */ 662 /* FALLTHROUGH */
663 default: 663 default:
664 lint_assert(0); 664 lint_assert(0);
665 } 665 }
666 free(di); 666 free(di);
667} 667}
668 668
669/* 669/*
670 * Set flag d_asm in all declaration stack elements up to the 670 * Set flag d_asm in all declaration stack elements up to the
671 * outermost one. 671 * outermost one.
672 * 672 *
673 * This is used to mark compound statements which have, possibly in 673 * This is used to mark compound statements which have, possibly in
674 * nested compound statements, asm statements. For these compound 674 * nested compound statements, asm statements. For these compound
675 * statements no warnings about unused or unitialized variables are 675 * statements no warnings about unused or unitialized variables are
676 * printed. 676 * printed.
677 * 677 *
678 * There is no need to clear d_asm in dinfo structs with context AUTO, 678 * There is no need to clear d_asm in dinfo structs with context AUTO,
679 * because these structs are freed at the end of the compound statement. 679 * because these structs are freed at the end of the compound statement.
680 * But it must be cleared in the outermost dinfo struct, which has 680 * But it must be cleared in the outermost dinfo struct, which has
681 * context EXTERN. This could be done in clrtyp() and would work for 681 * context EXTERN. This could be done in clrtyp() and would work for
682 * C, but not for C++ (due to mixed statements and declarations). Thus 682 * C, but not for C++ (due to mixed statements and declarations). Thus
683 * we clear it in global_clean_up_decl(), which is used to do some cleanup 683 * we clear it in global_clean_up_decl(), which is used to do some cleanup
684 * after global declarations/definitions. 684 * after global declarations/definitions.
685 */ 685 */
686void 686void
687setasm(void) 687setasm(void)
688{ 688{
689 dinfo_t *di; 689 dinfo_t *di;
690 690
691 for (di = dcs; di != NULL; di = di->d_next) 691 for (di = dcs; di != NULL; di = di->d_next)
692 di->d_asm = 1; 692 di->d_asm = 1;
693} 693}
694 694
695/* 695/*
696 * Clean all elements of the top element of declaration stack which 696 * Clean all elements of the top element of declaration stack which
697 * will be used by the next declaration 697 * will be used by the next declaration
698 */ 698 */
699void 699void
700clrtyp(void) 700clrtyp(void)
701{ 701{
702 702
703 dcs->d_atyp = dcs->d_cmod = dcs->d_smod = dcs->d_lmod = NOTSPEC; 703 dcs->d_atyp = dcs->d_cmod = dcs->d_smod = dcs->d_lmod = NOTSPEC;
704 dcs->d_scl = NOSCL; 704 dcs->d_scl = NOSCL;
705 dcs->d_type = NULL; 705 dcs->d_type = NULL;
706 dcs->d_const = dcs->d_volatile = 0; 706 dcs->d_const = dcs->d_volatile = 0;
707 dcs->d_inline = 0; 707 dcs->d_inline = 0;
708 dcs->d_mscl = dcs->d_terr = 0; 708 dcs->d_mscl = dcs->d_terr = 0;
709 dcs->d_nedecl = 0; 709 dcs->d_nedecl = 0;
710 dcs->d_notyp = 0; 710 dcs->d_notyp = 0;
711} 711}
712 712
713/* 713/*
714 * Create a type structure from the information gathered in 714 * Create a type structure from the information gathered in
715 * the declaration stack. 715 * the declaration stack.
716 * Complain about storage classes which are not possible in current 716 * Complain about storage classes which are not possible in current
717 * context. 717 * context.
718 */ 718 */
719void 719void
720deftyp(void) 720deftyp(void)
721{ 721{
722 tspec_t t, s, l, c; 722 tspec_t t, s, l, c;
723 type_t *tp; 723 type_t *tp;
724 scl_t scl; 724 scl_t scl;
725 725
726 t = dcs->d_atyp; /* BOOL, CHAR, INT, COMPLEX, VOID */ 726 t = dcs->d_atyp; /* BOOL, CHAR, INT, COMPLEX, VOID */
727 s = dcs->d_smod; /* SIGNED, UNSIGNED */ 727 s = dcs->d_smod; /* SIGNED, UNSIGNED */
728 l = dcs->d_lmod; /* SHORT, LONG, QUAD */ 728 l = dcs->d_lmod; /* SHORT, LONG, QUAD */
729 c = dcs->d_cmod; /* FLOAT, DOUBLE */ 729 c = dcs->d_cmod; /* FLOAT, DOUBLE */
730 tp = dcs->d_type; 730 tp = dcs->d_type;
731 scl = dcs->d_scl; 731 scl = dcs->d_scl;
732 732
733#ifdef DEBUG 733#ifdef DEBUG
734 printf("%s: %s\n", __func__, type_name(tp)); 734 printf("%s: %s\n", __func__, type_name(tp));
735#endif 735#endif
736 if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC && 736 if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC &&
737 tp == NULL) 737 tp == NULL)
738 dcs->d_notyp = 1; 738 dcs->d_notyp = 1;
739 if (t == NOTSPEC && s == NOTSPEC && (l == NOTSPEC || l == LONG) && 739 if (t == NOTSPEC && s == NOTSPEC && (l == NOTSPEC || l == LONG) &&
740 tp == NULL) 740 tp == NULL)
741 t = c; 741 t = c;
742 742
743 if (tp != NULL) { 743 if (tp != NULL) {
744 lint_assert(t == NOTSPEC); 744 lint_assert(t == NOTSPEC);
745 lint_assert(s == NOTSPEC); 745 lint_assert(s == NOTSPEC);
746 lint_assert(l == NOTSPEC); 746 lint_assert(l == NOTSPEC);
747 } 747 }
748 748
749 if (tp == NULL) { 749 if (tp == NULL) {
750 switch (t) { 750 switch (t) {
751 case BOOL: 751 case BOOL:
752 break; 752 break;
753 case NOTSPEC: 753 case NOTSPEC:
754 t = INT; 754 t = INT;
755 /* FALLTHROUGH */ 755 /* FALLTHROUGH */
756 case INT: 756 case INT:
757 if (s == NOTSPEC) 757 if (s == NOTSPEC)
758 s = SIGNED; 758 s = SIGNED;
759 break; 759 break;
760 case CHAR: 760 case CHAR:
761 if (l != NOTSPEC) { 761 if (l != NOTSPEC) {
762 dcs->d_terr = 1; 762 dcs->d_terr = 1;
763 l = NOTSPEC; 763 l = NOTSPEC;
764 } 764 }
765 break; 765 break;
766 case FLOAT: 766 case FLOAT:
767 if (l == LONG) { 767 if (l == LONG) {
768 l = NOTSPEC; 768 l = NOTSPEC;
769 t = DOUBLE; 769 t = DOUBLE;
770 if (!tflag) 770 if (!tflag)
771 /* use 'double' instead of 'long ... */ 771 /* use 'double' instead of 'long ... */
772 warning(6); 772 warning(6);
773 } 773 }
774 break; 774 break;
775 case DOUBLE: 775 case DOUBLE:
776 if (l == LONG) { 776 if (l == LONG) {
777 case LDOUBLE: 777 case LDOUBLE:
778 l = NOTSPEC; 778 l = NOTSPEC;
779 t = LDOUBLE; 779 t = LDOUBLE;
780 if (tflag) 780 if (tflag)
781 /* 'long double' is illegal in ... */ 781 /* 'long double' is illegal in ... */
782 warning(266); 782 warning(266);
783 } 783 }
784 break; 784 break;
785 case DCOMPLEX: 785 case DCOMPLEX:
786 if (l == LONG) { 786 if (l == LONG) {
787 l = NOTSPEC; 787 l = NOTSPEC;
788 t = LCOMPLEX; 788 t = LCOMPLEX;
789 if (tflag) 789 if (tflag)
790 /* 'long double' is illegal in ... */ 790 /* 'long double' is illegal in ... */
791 warning(266); 791 warning(266);
792 } 792 }
793 break; 793 break;
794 case VOID: 794 case VOID:
795 case FCOMPLEX: 795 case FCOMPLEX:
796 case LCOMPLEX: 796 case LCOMPLEX:
797 break; 797 break;
798 default: 798 default:
799 LERROR("deftyp(%s)", tspec_name(t)); 799 LERROR("deftyp(%s)", tspec_name(t));
800 } 800 }
801 if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) { 801 if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
802 dcs->d_terr = 1; 802 dcs->d_terr = 1;
803 l = s = NOTSPEC; 803 l = s = NOTSPEC;
804 } 804 }
805 if (l != NOTSPEC) 805 if (l != NOTSPEC)
806 t = l; 806 t = l;
807 dcs->d_type = gettyp(merge_type_specifiers(t, s)); 807 dcs->d_type = gettyp(merge_type_specifiers(t, s));
808 } 808 }
809 809
810 if (dcs->d_mscl) { 810 if (dcs->d_mscl) {
811 /* only one storage class allowed */ 811 /* only one storage class allowed */
812 error(7); 812 error(7);
813 } 813 }
814 if (dcs->d_terr) { 814 if (dcs->d_terr) {
815 /* illegal type combination */ 815 /* illegal type combination */
816 error(4); 816 error(4);
817 } 817 }
818 818
819 if (dcs->d_ctx == EXTERN) { 819 if (dcs->d_ctx == EXTERN) {
820 if (scl == REG || scl == AUTO) { 820 if (scl == REG || scl == AUTO) {
821 /* illegal storage class */ 821 /* illegal storage class */
822 error(8); 822 error(8);
823 scl = NOSCL; 823 scl = NOSCL;
824 } 824 }
825 } else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) { 825 } else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
826 if (scl != NOSCL && scl != REG) { 826 if (scl != NOSCL && scl != REG) {
827 /* only register valid ... */ 827 /* only register valid ... */
828 error(9); 828 error(9);
829 scl = NOSCL; 829 scl = NOSCL;
830 } 830 }
831 } 831 }
832 832
833 dcs->d_scl = scl; 833 dcs->d_scl = scl;
834 834
835 if (dcs->d_const && dcs->d_type->t_const) { 835 if (dcs->d_const && dcs->d_type->t_const) {
836 lint_assert(dcs->d_type->t_typedef); 836 lint_assert(dcs->d_type->t_typedef);
837 /* typedef already qualified with '%s' */ 837 /* typedef already qualified with '%s' */
838 warning(68, "const"); 838 warning(68, "const");
839 } 839 }
840 if (dcs->d_volatile && dcs->d_type->t_volatile) { 840 if (dcs->d_volatile && dcs->d_type->t_volatile) {
841 lint_assert(dcs->d_type->t_typedef); 841 lint_assert(dcs->d_type->t_typedef);
842 /* typedef already qualified with '%s' */ 842 /* typedef already qualified with '%s' */
843 warning(68, "volatile"); 843 warning(68, "volatile");
844 } 844 }
845 845
846 if (dcs->d_const || dcs->d_volatile) { 846 if (dcs->d_const || dcs->d_volatile) {
847 dcs->d_type = duptyp(dcs->d_type); 847 dcs->d_type = duptyp(dcs->d_type);
848 dcs->d_type->t_const |= dcs->d_const; 848 dcs->d_type->t_const |= dcs->d_const;
849 dcs->d_type->t_volatile |= dcs->d_volatile; 849 dcs->d_type->t_volatile |= dcs->d_volatile;
850 } 850 }
851} 851}
852 852
853/* 853/*
854 * Merge type specifiers (char, ..., long long, signed, unsigned). 854 * Merge type specifiers (char, ..., long long, signed, unsigned).
855 */ 855 */
856static tspec_t 856static tspec_t
857merge_type_specifiers(tspec_t t, tspec_t s) 857merge_type_specifiers(tspec_t t, tspec_t s)
858{ 858{
859 859
860 if (s == SIGNED || s == UNSIGN) { 860 if (s == SIGNED || s == UNSIGN) {
861 if (t == CHAR) { 861 if (t == CHAR) {
862 t = s == SIGNED ? SCHAR : UCHAR; 862 t = s == SIGNED ? SCHAR : UCHAR;
863 } else if (t == SHORT) { 863 } else if (t == SHORT) {
864 t = s == SIGNED ? SHORT : USHORT; 864 t = s == SIGNED ? SHORT : USHORT;
865 } else if (t == INT) { 865 } else if (t == INT) {
866 t = s == SIGNED ? INT : UINT; 866 t = s == SIGNED ? INT : UINT;
867 } else if (t == LONG) { 867 } else if (t == LONG) {
868 t = s == SIGNED ? LONG : ULONG; 868 t = s == SIGNED ? LONG : ULONG;
869 } else if (t == QUAD) { 869 } else if (t == QUAD) {
870 t = s == SIGNED ? QUAD : UQUAD; 870 t = s == SIGNED ? QUAD : UQUAD;
871 } 871 }
872 } 872 }
873 873
874 return t; 874 return t;
875} 875}
876 876
877/* 877/*
878 * Return the length of a type in bits. 878 * Return the length of a type in bits.
879 * 879 *
880 * Printing a message if the outhermost dimension of an array is 0 must 880 * Printing a message if the outhermost dimension of an array is 0 must
881 * be done by the caller. All other problems are reported by length() 881 * be done by the caller. All other problems are reported by length()
882 * if name is not NULL. 882 * if name is not NULL.
883 */ 883 */
884int 884int
885length(type_t *tp, const char *name) 885length(type_t *tp, const char *name)
886{ 886{
887 int elem, elsz; 887 int elem, elsz;
888 888
889 elem = 1; 889 elem = 1;
890 while (tp && tp->t_tspec == ARRAY) { 890 while (tp && tp->t_tspec == ARRAY) {
891 elem *= tp->t_dim; 891 elem *= tp->t_dim;
892 tp = tp->t_subt; 892 tp = tp->t_subt;
893 } 893 }
894 if (tp == NULL) 894 if (tp == NULL)
895 return -1; 895 return -1;
896 896
897 switch (tp->t_tspec) { 897 switch (tp->t_tspec) {
898 case FUNC: 898 case FUNC:
899 /* compiler takes size of function */ 899 /* compiler takes size of function */
900 LERROR("%s", msgs[12]); 900 LERROR("%s", msgs[12]);
901 /* NOTREACHED */ 901 /* NOTREACHED */
902 case STRUCT: 902 case STRUCT:
903 case UNION: 903 case UNION:
904 if (incompl(tp) && name != NULL) { 904 if (incompl(tp) && name != NULL) {
905 /* incomplete structure or union %s: %s */ 905 /* incomplete structure or union %s: %s */
906 error(31, tp->t_str->stag->s_name, name); 906 error(31, tp->t_str->stag->s_name, name);
907 } 907 }
908 elsz = tp->t_str->size; 908 elsz = tp->t_str->size;
909 break; 909 break;
910 case ENUM: 910 case ENUM:
911 if (incompl(tp) && name != NULL) { 911 if (incompl(tp) && name != NULL) {
912 /* incomplete enum type: %s */ 912 /* incomplete enum type: %s */
913 warning(13, name); 913 warning(13, name);
914 } 914 }
915 /* FALLTHROUGH */ 915 /* FALLTHROUGH */
916 default: 916 default:
917 elsz = size(tp->t_tspec); 917 elsz = size(tp->t_tspec);
918 if (elsz <= 0) 918 if (elsz <= 0)
919 LERROR("length(%d)", elsz); 919 LERROR("length(%d)", elsz);
920 break; 920 break;
921 } 921 }
922 return elem * elsz; 922 return elem * elsz;
923} 923}
924 924
925/* 925/*
926 * Get the alignment of the given Type in bits. 926 * Get the alignment of the given Type in bits.
927 */ 927 */
928int 928int
929getbound(type_t *tp) 929getbound(type_t *tp)
930{ 930{
931 size_t a; 931 size_t a;
932 tspec_t t; 932 tspec_t t;
933 933
934 while (tp && tp->t_tspec == ARRAY) 934 while (tp && tp->t_tspec == ARRAY)
935 tp = tp->t_subt; 935 tp = tp->t_subt;
936 936
937 if (tp == NULL) 937 if (tp == NULL)
938 return -1; 938 return -1;
939 939
940 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 940 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
941 a = tp->t_str->align; 941 a = tp->t_str->align;
942 } else if (t == FUNC) { 942 } else if (t == FUNC) {
943 /* compiler takes alignment of function */ 943 /* compiler takes alignment of function */
944 error(14); 944 error(14);
945 a = WORST_ALIGN(1) * CHAR_BIT; 945 a = WORST_ALIGN(1) * CHAR_BIT;
946 } else { 946 } else {
947 if ((a = size(t)) == 0) { 947 if ((a = size(t)) == 0) {
948 a = CHAR_BIT; 948 a = CHAR_BIT;
949 } else if (a > WORST_ALIGN(1) * CHAR_BIT) { 949 } else if (a > WORST_ALIGN(1) * CHAR_BIT) {
950 a = WORST_ALIGN(1) * CHAR_BIT; 950 a = WORST_ALIGN(1) * CHAR_BIT;
951 } 951 }
952 } 952 }
953 lint_assert(a >= CHAR_BIT); 953 lint_assert(a >= CHAR_BIT);
954 lint_assert(a <= WORST_ALIGN(1) * CHAR_BIT); 954 lint_assert(a <= WORST_ALIGN(1) * CHAR_BIT);
955 return a; 955 return a;
956} 956}
957 957
958/* 958/*
959 * Concatenate two lists of symbols by s_next. Used by declarations of 959 * Concatenate two lists of symbols by s_next. Used by declarations of
960 * struct/union/enum elements and parameters. 960 * struct/union/enum elements and parameters.
961 */ 961 */
962sym_t * 962sym_t *
963lnklst(sym_t *l1, sym_t *l2) 963lnklst(sym_t *l1, sym_t *l2)
964{ 964{
965 sym_t *l; 965 sym_t *l;
966 966
967 if ((l = l1) == NULL) 967 if ((l = l1) == NULL)
968 return l2; 968 return l2;
969 while (l1->s_next != NULL) 969 while (l1->s_next != NULL)
970 l1 = l1->s_next; 970 l1 = l1->s_next;
971 l1->s_next = l2; 971 l1->s_next = l2;
972 return l; 972 return l;
973} 973}
974 974
975/* 975/*
976 * Check if the type of the given symbol is valid and print an error 976 * Check if the type of the given symbol is valid and print an error
977 * message if it is not. 977 * message if it is not.
978 * 978 *
979 * Invalid types are: 979 * Invalid types are:
980 * - arrays of incomlete types or functions 980 * - arrays of incomlete types or functions
981 * - functions returning arrays or functions 981 * - functions returning arrays or functions
982 * - void types other than type of function or pointer 982 * - void types other than type of function or pointer
983 */ 983 */
984void 984void
985check_type(sym_t *sym) 985check_type(sym_t *sym)
986{ 986{
987 tspec_t to, t; 987 tspec_t to, t;
988 type_t **tpp, *tp; 988 type_t **tpp, *tp;
989 989
990 tpp = &sym->s_type; 990 tpp = &sym->s_type;
991 to = NOTSPEC; 991 to = NOTSPEC;
992 while ((tp = *tpp) != NULL) { 992 while ((tp = *tpp) != NULL) {
993 t = tp->t_tspec; 993 t = tp->t_tspec;
994 /* 994 /*
995 * If this is the type of an old style function definition, 995 * If this is the type of an old style function definition,
996 * a better warning is printed in funcdef(). 996 * a better warning is printed in funcdef().
997 */ 997 */
998 if (t == FUNC && !tp->t_proto && 998 if (t == FUNC && !tp->t_proto &&
999 !(to == NOTSPEC && sym->s_osdef)) { 999 !(to == NOTSPEC && sym->s_osdef)) {
1000 if (sflag && hflag) 1000 if (sflag && hflag)
1001 /* function declaration is not a prototype */ 1001 /* function declaration is not a prototype */
1002 warning(287); 1002 warning(287);
1003 } 1003 }
1004 if (to == FUNC) { 1004 if (to == FUNC) {
1005 if (t == FUNC || t == ARRAY) { 1005 if (t == FUNC || t == ARRAY) {
1006 /* function returns illegal type */ 1006 /* function returns illegal type */
1007 error(15); 1007 error(15);
1008 if (t == FUNC) { 1008 if (t == FUNC) {
1009 *tpp = incref(*tpp, PTR); 1009 *tpp = incref(*tpp, PTR);
1010 } else { 1010 } else {
1011 *tpp = incref((*tpp)->t_subt, PTR); 1011 *tpp = incref((*tpp)->t_subt, PTR);
1012 } 1012 }
1013 return; 1013 return;
1014 } else if (tp->t_const || tp->t_volatile) { 1014 } else if (tp->t_const || tp->t_volatile) {
1015 if (sflag) { /* XXX oder better !tflag ? */ 1015 if (sflag) { /* XXX oder better !tflag ? */
1016 /* function cannot return const... */ 1016 /* function cannot return const... */
1017 warning(228); 1017 warning(228);
1018 } 1018 }
1019 } 1019 }
1020 } if (to == ARRAY) { 1020 } if (to == ARRAY) {
1021 if (t == FUNC) { 1021 if (t == FUNC) {
1022 /* array of function is illegal */ 1022 /* array of function is illegal */
1023 error(16); 1023 error(16);
1024 *tpp = gettyp(INT); 1024 *tpp = gettyp(INT);
1025 return; 1025 return;
1026 } else if (t == ARRAY && tp->t_dim == 0) { 1026 } else if (t == ARRAY && tp->t_dim == 0) {
1027 /* null dimension */ 1027 /* null dimension */
1028 error(17); 1028 error(17);
1029 return; 1029 return;
1030 } else if (t == VOID) { 1030 } else if (t == VOID) {
1031 /* illegal use of 'void' */ 1031 /* illegal use of 'void' */
1032 error(18); 1032 error(18);
1033 *tpp = gettyp(INT); 1033 *tpp = gettyp(INT);
1034#if 0 /* errors are produced by length() */ 1034#if 0 /* errors are produced by length() */
1035 } else if (incompl(tp)) { 1035 } else if (incompl(tp)) {
1036 /* array of incomplete type */ 1036 /* array of incomplete type */
1037 if (sflag) { 1037 if (sflag) {
1038 /* array of incomplete type */ 1038 /* array of incomplete type */
1039 error(301); 1039 error(301);
1040 } else { 1040 } else {
1041 /* array of incomplete type */ 1041 /* array of incomplete type */
1042 warning(301); 1042 warning(301);
1043 } 1043 }
1044#endif 1044#endif
1045 } 1045 }
1046 } else if (to == NOTSPEC && t == VOID) { 1046 } else if (to == NOTSPEC && t == VOID) {
1047 if (dcs->d_ctx == PARG) { 1047 if (dcs->d_ctx == PARG) {
1048 if (sym->s_scl != ABSTRACT) { 1048 if (sym->s_scl != ABSTRACT) {
1049 lint_assert(sym->s_name != unnamed); 1049 lint_assert(sym->s_name != unnamed);
1050 /* void param. cannot have name: %s */ 1050 /* void param. cannot have name: %s */
1051 error(61, sym->s_name); 1051 error(61, sym->s_name);
1052 *tpp = gettyp(INT); 1052 *tpp = gettyp(INT);
1053 } 1053 }
1054 } else if (dcs->d_ctx == ABSTRACT) { 1054 } else if (dcs->d_ctx == ABSTRACT) {
1055 /* ok */ 1055 /* ok */
1056 } else if (sym->s_scl != TYPEDEF) { 1056 } else if (sym->s_scl != TYPEDEF) {
1057 /* void type for %s */ 1057 /* void type for %s */
1058 error(19, sym->s_name); 1058 error(19, sym->s_name);
1059 *tpp = gettyp(INT); 1059 *tpp = gettyp(INT);
1060 } 1060 }
1061 } 1061 }
1062 if (t == VOID && to != PTR) { 1062 if (t == VOID && to != PTR) {
1063 if (tp->t_const || tp->t_volatile) { 1063 if (tp->t_const || tp->t_volatile) {
1064 /* inappropriate qualifiers with 'void' */ 1064 /* inappropriate qualifiers with 'void' */
1065 warning(69); 1065 warning(69);
1066 tp->t_const = tp->t_volatile = 0; 1066 tp->t_const = tp->t_volatile = 0;
1067 } 1067 }
1068 } 1068 }
1069 tpp = &tp->t_subt; 1069 tpp = &tp->t_subt;
1070 to = t; 1070 to = t;
1071 } 1071 }
1072} 1072}
1073 1073
1074/* 1074/*
1075 * Process the declarator of a struct/union element. 1075 * Process the declarator of a struct/union element.
1076 */ 1076 */
1077sym_t * 1077sym_t *
1078declarator_1_struct_union(sym_t *dsym) 1078declarator_1_struct_union(sym_t *dsym)
1079{ 1079{
1080 type_t *tp; 1080 type_t *tp;
1081 tspec_t t; 1081 tspec_t t;
1082 int sz, len; 1082 int sz, len;
1083 int o = 0; /* Appease gcc */ 1083 int o = 0; /* Appease gcc */
1084 scl_t sc; 1084 scl_t sc;
1085 1085
1086 lint_assert((sc = dsym->s_scl) == MOS || sc == MOU); 1086 lint_assert((sc = dsym->s_scl) == MOS || sc == MOU);
1087 1087
1088 if (dcs->d_rdcsym != NULL) { 1088 if (dcs->d_rdcsym != NULL) {
1089 /* should be ensured by storesym() */ 1089 /* should be ensured by storesym() */
1090 lint_assert((sc = dcs->d_rdcsym->s_scl) == MOS || sc == MOU); 1090 lint_assert((sc = dcs->d_rdcsym->s_scl) == MOS || sc == MOU);
1091 if (dsym->s_styp == dcs->d_rdcsym->s_styp) { 1091 if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
1092 /* duplicate member name: %s */ 1092 /* duplicate member name: %s */
1093 error(33, dsym->s_name); 1093 error(33, dsym->s_name);
1094 rmsym(dcs->d_rdcsym); 1094 rmsym(dcs->d_rdcsym);
1095 } 1095 }
1096 } 1096 }
1097 1097
1098 check_type(dsym); 1098 check_type(dsym);
1099 1099
1100 t = (tp = dsym->s_type)->t_tspec; 1100 t = (tp = dsym->s_type)->t_tspec;
1101 1101
1102 if (dsym->s_bitfield) { 1102 if (dsym->s_bitfield) {
1103 /* 1103 /*
1104 * only unsigned and signed int are portable bit-field types 1104 * only unsigned and signed int are portable bit-field types
1105 *(at least in ANSI C, in traditional C only unsigned int) 1105 *(at least in ANSI C, in traditional C only unsigned int)
1106 */ 1106 */
1107 if (t == CHAR || t == UCHAR || t == SCHAR || 1107 if (t == CHAR || t == UCHAR || t == SCHAR ||
1108 t == SHORT || t == USHORT || t == ENUM) { 1108 t == SHORT || t == USHORT || t == ENUM) {
1109 if (bitfieldtype_ok == 0) { 1109 if (bitfieldtype_ok == 0) {
1110 if (sflag) { 1110 if (sflag) {
1111 /* bit-field type '%s' invalid ... */ 1111 /* bit-field type '%s' invalid ... */
1112 warning(273, type_name(tp)); 1112 warning(273, type_name(tp));
1113 } else if (pflag) { 1113 } else if (pflag) {
1114 /* nonportable bit-field type */ 1114 /* nonportable bit-field type */
1115 warning(34); 1115 warning(34);
1116 } 1116 }
1117 } 1117 }
1118 } else if (t == INT && dcs->d_smod == NOTSPEC) { 1118 } else if (t == INT && dcs->d_smod == NOTSPEC) {
1119 if (pflag && bitfieldtype_ok == 0) { 1119 if (pflag && bitfieldtype_ok == 0) {
1120 /* nonportable bit-field type */ 1120 /* nonportable bit-field type */
1121 warning(34); 1121 warning(34);
1122 } 1122 }
1123 } else if (t != INT && t != UINT && t != BOOL) { 1123 } else if (t != INT && t != UINT && t != BOOL) {
1124 /* 1124 /*
1125 * Non-integer types are always illegal for 1125 * Non-integer types are always illegal for
1126 * bitfields, regardless of BITFIELDTYPE. 1126 * bitfields, regardless of BITFIELDTYPE.
1127 * Integer types not dealt with above are 1127 * Integer types not dealt with above are
1128 * okay only if BITFIELDTYPE is in effect. 1128 * okay only if BITFIELDTYPE is in effect.
1129 */ 1129 */
1130 if (bitfieldtype_ok == 0 || tspec_is_int(t) == 0) { 1130 if (bitfieldtype_ok == 0 || tspec_is_int(t) == 0) {
1131 /* illegal bit-field type */ 1131 /* illegal bit-field type */
1132 warning(35); 1132 warning(35);
1133 sz = tp->t_flen; 1133 sz = tp->t_flen;
1134 dsym->s_type = tp = duptyp(gettyp(t = INT)); 1134 dsym->s_type = tp = duptyp(gettyp(t = INT));
1135 if ((tp->t_flen = sz) > size(t)) 1135 if ((tp->t_flen = sz) > size(t))
1136 tp->t_flen = size(t); 1136 tp->t_flen = size(t);
1137 } 1137 }
1138 } 1138 }
1139 if ((len = tp->t_flen) < 0 || len > (ssize_t)size(t)) { 1139 if ((len = tp->t_flen) < 0 || len > (ssize_t)size(t)) {
1140 /* illegal bit-field size: %d */ 1140 /* illegal bit-field size: %d */
1141 error(36, len); 1141 error(36, len);
1142 tp->t_flen = size(t); 1142 tp->t_flen = size(t);
1143 } else if (len == 0 && dsym->s_name != unnamed) { 1143 } else if (len == 0 && dsym->s_name != unnamed) {
1144 /* zero size bit-field */ 1144 /* zero size bit-field */
1145 error(37); 1145 error(37);
1146 tp->t_flen = size(t); 1146 tp->t_flen = size(t);
1147 } 1147 }
1148 if (dsym->s_scl == MOU) { 1148 if (dsym->s_scl == MOU) {
1149 /* illegal use of bit-field */ 1149 /* illegal use of bit-field */
1150 error(41); 1150 error(41);
1151 dsym->s_type->t_isfield = 0; 1151 dsym->s_type->t_isfield = 0;
1152 dsym->s_bitfield = 0; 1152 dsym->s_bitfield = 0;
1153 } 1153 }
1154 } else if (t == FUNC) { 1154 } else if (t == FUNC) {
1155 /* function illegal in structure or union */ 1155 /* function illegal in structure or union */
1156 error(38); 1156 error(38);
1157 dsym->s_type = tp = incref(tp, t = PTR); 1157 dsym->s_type = tp = incref(tp, t = PTR);
1158 } 1158 }
1159 1159
1160 /* 1160 /*
1161 * bit-fields of length 0 are not warned about because length() 1161 * bit-fields of length 0 are not warned about because length()
1162 * does not return the length of the bit-field but the length 1162 * does not return the length of the bit-field but the length
1163 * of the type the bit-field is packed in (it's ok) 1163 * of the type the bit-field is packed in (it's ok)
1164 */ 1164 */
1165 if ((sz = length(dsym->s_type, dsym->s_name)) == 0) { 1165 if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
1166 if (t == ARRAY && dsym->s_type->t_dim == 0) { 1166 if (t == ARRAY && dsym->s_type->t_dim == 0) {
1167 /* zero sized array in struct is a C99 extension: %s */ 1167 /* zero sized array in struct is a C99 extension: %s */
1168 c99ism(39, dsym->s_name); 1168 c99ism(39, dsym->s_name);
1169 } 1169 }
1170 } 1170 }
1171 1171
1172 if (dcs->d_ctx == MOU) { 1172 if (dcs->d_ctx == MOU) {
1173 o = dcs->d_offset; 1173 o = dcs->d_offset;
1174 dcs->d_offset = 0; 1174 dcs->d_offset = 0;
1175 } 1175 }
1176 if (dsym->s_bitfield) { 1176 if (dsym->s_bitfield) {
1177 align(getbound(tp), tp->t_flen); 1177 align(getbound(tp), tp->t_flen);
1178 dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t); 1178 dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
1179 tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad; 1179 tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
1180 dcs->d_offset += tp->t_flen; 1180 dcs->d_offset += tp->t_flen;
1181 } else { 1181 } else {
1182 align(getbound(tp), 0); 1182 align(getbound(tp), 0);
1183 dsym->s_value.v_quad = dcs->d_offset; 1183 dsym->s_value.v_quad = dcs->d_offset;
1184 dcs->d_offset += sz; 1184 dcs->d_offset += sz;
1185 } 1185 }
1186 if (dcs->d_ctx == MOU) { 1186 if (dcs->d_ctx == MOU) {
1187 if (o > dcs->d_offset) 1187 if (o > dcs->d_offset)
1188 dcs->d_offset = o; 1188 dcs->d_offset = o;
1189 } 1189 }
1190 1190
1191 check_function_definition(dsym, 0); 1191 check_function_definition(dsym, 0);
1192 1192
1193 /* 1193 /*
1194 * Clear the BITFIELDTYPE indicator after processing each 1194 * Clear the BITFIELDTYPE indicator after processing each
1195 * structure element. 1195 * structure element.
1196 */ 1196 */
1197 bitfieldtype_ok = 0; 1197 bitfieldtype_ok = 0;
1198 1198
1199 return dsym; 1199 return dsym;
1200} 1200}
1201 1201
1202/* 1202/*
1203 * Aligns next structure element as required. 1203 * Aligns next structure element as required.
1204 * 1204 *
1205 * al contains the required alignment, len the length of a bit-field. 1205 * al contains the required alignment, len the length of a bit-field.
1206 */ 1206 */
1207static void 1207static void
1208align(int al, int len) 1208align(int al, int len)
1209{ 1209{
1210 int no; 1210 int no;
1211 1211
1212 /* 1212 /*
1213 * The alignment of the current element becomes the alignment of 1213 * The alignment of the current element becomes the alignment of
1214 * the struct/union if it is larger than the current alignment 1214 * the struct/union if it is larger than the current alignment
1215 * of the struct/union. 1215 * of the struct/union.
1216 */ 1216 */
1217 if (al > dcs->d_stralign) 1217 if (al > dcs->d_stralign)
1218 dcs->d_stralign = al; 1218 dcs->d_stralign = al;
1219 1219
1220 no = (dcs->d_offset + (al - 1)) & ~(al - 1); 1220 no = (dcs->d_offset + (al - 1)) & ~(al - 1);
1221 if (len == 0 || dcs->d_offset + len > no) 1221 if (len == 0 || dcs->d_offset + len > no)
1222 dcs->d_offset = no; 1222 dcs->d_offset = no;
1223} 1223}
1224 1224
1225/* 1225/*
1226 * Remember the width of the field in its type structure. 1226 * Remember the width of the field in its type structure.
1227 */ 1227 */
1228sym_t * 1228sym_t *
1229bitfield(sym_t *dsym, int len) 1229bitfield(sym_t *dsym, int len)
1230{ 1230{
1231 1231
1232 if (dsym == NULL) { 1232 if (dsym == NULL) {
1233 dsym = getblk(sizeof (sym_t)); 1233 dsym = getblk(sizeof (sym_t));
1234 dsym->s_name = unnamed; 1234 dsym->s_name = unnamed;
1235 dsym->s_kind = FMEMBER; 1235 dsym->s_kind = FMEMBER;
1236 dsym->s_scl = MOS; 1236 dsym->s_scl = MOS;
1237 dsym->s_type = gettyp(UINT); 1237 dsym->s_type = gettyp(UINT);
1238 dsym->s_blklev = -1; 1238 dsym->s_blklev = -1;
1239 } 1239 }
1240 dsym->s_type = duptyp(dsym->s_type); 1240 dsym->s_type = duptyp(dsym->s_type);
1241 dsym->s_type->t_isfield = 1; 1241 dsym->s_type->t_isfield = 1;
1242 dsym->s_type->t_flen = len; 1242 dsym->s_type->t_flen = len;
1243 dsym->s_bitfield = 1; 1243 dsym->s_bitfield = 1;
1244 return dsym; 1244 return dsym;
1245} 1245}
1246 1246
1247/* 1247/*
1248 * Collect information about a sequence of asterisks and qualifiers in a 1248 * Collect information about a sequence of asterisks and qualifiers in a
1249 * list of type pqinf_t. 1249 * list of type pqinf_t.
1250 * Qualifiers always refer to the left asterisk. 1250 * Qualifiers always refer to the left asterisk.
1251 * The rightmost asterisk will be at the top of the list. 1251 * The rightmost asterisk will be at the top of the list.
1252 */ 1252 */
1253pqinf_t * 1253pqinf_t *
1254merge_pointers_and_qualifiers(pqinf_t *p1, pqinf_t *p2) 1254merge_pointers_and_qualifiers(pqinf_t *p1, pqinf_t *p2)
1255{ 1255{
1256 pqinf_t *p; 1256 pqinf_t *p;
1257 1257
1258 if (p2->p_pcnt != 0) { 1258 if (p2->p_pcnt != 0) {
1259 /* left '*' at the end of the list */ 1259 /* left '*' at the end of the list */
1260 for (p = p2; p->p_next != NULL; p = p->p_next) 1260 for (p = p2; p->p_next != NULL; p = p->p_next)
1261 continue; 1261 continue;
1262 p->p_next = p1; 1262 p->p_next = p1;
1263 return p2; 1263 return p2;
1264 } else { 1264 } else {
1265 if (p2->p_const) { 1265 if (p2->p_const) {
1266 if (p1->p_const) { 1266 if (p1->p_const) {
1267 /* duplicate '%s' */ 1267 /* duplicate '%s' */
1268 warning(10, "const"); 1268 warning(10, "const");
1269 } 1269 }
1270 p1->p_const = 1; 1270 p1->p_const = 1;
1271 } 1271 }
1272 if (p2->p_volatile) { 1272 if (p2->p_volatile) {
1273 if (p1->p_volatile) { 1273 if (p1->p_volatile) {
1274 /* duplicate '%s' */ 1274 /* duplicate '%s' */
1275 warning(10, "volatile"); 1275 warning(10, "volatile");
1276 } 1276 }
1277 p1->p_volatile = 1; 1277 p1->p_volatile = 1;
1278 } 1278 }
1279 free(p2); 1279 free(p2);
1280 return p1; 1280 return p1;
1281 } 1281 }
1282} 1282}
1283 1283
1284/* 1284/*
1285 * The following 3 functions extend the type of a declarator with 1285 * The following 3 functions extend the type of a declarator with
1286 * pointer, function and array types. 1286 * pointer, function and array types.
1287 * 1287 *
1288 * The current type is the Type built by deftyp() (dcs->d_type) and 1288 * The current type is the Type built by deftyp() (dcs->d_type) and
1289 * pointer, function and array types already added for this 1289 * pointer, function and array types already added for this
1290 * declarator. The new type extension is inserted between both. 1290 * declarator. The new type extension is inserted between both.
1291 */ 1291 */
1292sym_t * 1292sym_t *
1293add_pointer(sym_t *decl, pqinf_t *pi) 1293add_pointer(sym_t *decl, pqinf_t *pi)
1294{ 1294{
1295 type_t **tpp, *tp; 1295 type_t **tpp, *tp;
1296 pqinf_t *npi; 1296 pqinf_t *npi;
1297 1297
1298 tpp = &decl->s_type; 1298 tpp = &decl->s_type;
1299 while (*tpp && *tpp != dcs->d_type) 1299 while (*tpp && *tpp != dcs->d_type)
1300 tpp = &(*tpp)->t_subt; 1300 tpp = &(*tpp)->t_subt;
1301 if (*tpp == NULL) 1301 if (*tpp == NULL)
1302 return decl; 1302 return decl;
1303 1303
1304 while (pi != NULL) { 1304 while (pi != NULL) {
1305 *tpp = tp = getblk(sizeof (type_t)); 1305 *tpp = tp = getblk(sizeof (type_t));
1306 tp->t_tspec = PTR; 1306 tp->t_tspec = PTR;
1307 tp->t_const = pi->p_const; 1307 tp->t_const = pi->p_const;
1308 tp->t_volatile = pi->p_volatile; 1308 tp->t_volatile = pi->p_volatile;
1309 *(tpp = &tp->t_subt) = dcs->d_type; 1309 *(tpp = &tp->t_subt) = dcs->d_type;
1310 npi = pi->p_next; 1310 npi = pi->p_next;
1311 free(pi); 1311 free(pi);
1312 pi = npi; 1312 pi = npi;
1313 } 1313 }
1314 return decl; 1314 return decl;
1315} 1315}
1316 1316
1317/* 1317/*
1318 * If a dimension was specified, dim is 1, otherwise 0 1318 * If a dimension was specified, dim is 1, otherwise 0
1319 * n is the specified dimension 1319 * n is the specified dimension
1320 */ 1320 */
1321sym_t * 1321sym_t *
1322add_array(sym_t *decl, int dim, int n) 1322add_array(sym_t *decl, int dim, int n)
1323{ 1323{
1324 type_t **tpp, *tp; 1324 type_t **tpp, *tp;
1325 1325
1326 tpp = &decl->s_type; 1326 tpp = &decl->s_type;
1327 while (*tpp && *tpp != dcs->d_type) 1327 while (*tpp && *tpp != dcs->d_type)
1328 tpp = &(*tpp)->t_subt; 1328 tpp = &(*tpp)->t_subt;
1329 if (*tpp == NULL) 1329 if (*tpp == NULL)
1330 return decl; 1330 return decl;
1331 1331
1332 *tpp = tp = getblk(sizeof (type_t)); 1332 *tpp = tp = getblk(sizeof (type_t));
1333 tp->t_tspec = ARRAY; 1333 tp->t_tspec = ARRAY;
1334 tp->t_subt = dcs->d_type; 1334 tp->t_subt = dcs->d_type;
1335 tp->t_dim = n; 1335 tp->t_dim = n;
1336 1336
1337 if (n < 0) { 1337 if (n < 0) {
1338 /* negative array dimension (%d) */ 1338 /* negative array dimension (%d) */
1339 error(20, n); 1339 error(20, n);
1340 n = 0; 1340 n = 0;
1341 } else if (n == 0 && dim) { 1341 } else if (n == 0 && dim) {
1342 /* zero sized array is a C99 extension */ 1342 /* zero sized array is a C99 extension */
1343 c99ism(322); 1343 c99ism(322);
1344 } else if (n == 0 && !dim) { 1344 } else if (n == 0 && !dim) {
1345 setcomplete(tp, 0); 1345 setcomplete(tp, 0);
1346 } 1346 }
1347 1347
1348 return decl; 1348 return decl;
1349} 1349}
1350 1350
1351sym_t * 1351sym_t *
1352add_function(sym_t *decl, sym_t *args) 1352add_function(sym_t *decl, sym_t *args)
1353{ 1353{
1354 type_t **tpp, *tp; 1354 type_t **tpp, *tp;
1355 1355
1356 if (dcs->d_proto) { 1356 if (dcs->d_proto) {
1357 if (tflag) 1357 if (tflag)
1358 /* function prototypes are illegal in traditional C */ 1358 /* function prototypes are illegal in traditional C */
1359 warning(270); 1359 warning(270);
1360 args = new_style_function(decl, args); 1360 args = new_style_function(decl, args);
1361 } else { 1361 } else {
1362 old_style_function(decl, args); 1362 old_style_function(decl, args);
1363 } 1363 }
1364 1364
1365 /* 1365 /*
1366 * The symbols are removed from the symbol table by popdecl() after 1366 * The symbols are removed from the symbol table by popdecl() after
1367 * add_function(). To be able to restore them if this is a function 1367 * add_function(). To be able to restore them if this is a function
1368 * definition, a pointer to the list of all symbols is stored in 1368 * definition, a pointer to the list of all symbols is stored in
1369 * dcs->d_next->d_fpsyms. Also a list of the arguments (concatenated 1369 * dcs->d_next->d_fpsyms. Also a list of the arguments (concatenated
1370 * by s_next) is stored in dcs->d_next->d_fargs. 1370 * by s_next) is stored in dcs->d_next->d_fargs.
1371 * (dcs->d_next must be used because *dcs is the declaration stack 1371 * (dcs->d_next must be used because *dcs is the declaration stack
1372 * element created for the list of params and is removed after 1372 * element created for the list of params and is removed after
1373 * add_function()) 1373 * add_function())
1374 */ 1374 */
1375 if (dcs->d_next->d_ctx == EXTERN && 1375 if (dcs->d_next->d_ctx == EXTERN &&
1376 decl->s_type == dcs->d_next->d_type) { 1376 decl->s_type == dcs->d_next->d_type) {
1377 dcs->d_next->d_fpsyms = dcs->d_dlsyms; 1377 dcs->d_next->d_fpsyms = dcs->d_dlsyms;
1378 dcs->d_next->d_fargs = args; 1378 dcs->d_next->d_fargs = args;
1379 } 1379 }
1380 1380
1381 tpp = &decl->s_type; 1381 tpp = &decl->s_type;
1382 while (*tpp && *tpp != dcs->d_next->d_type) 1382 while (*tpp && *tpp != dcs->d_next->d_type)
1383 tpp = &(*tpp)->t_subt; 1383 tpp = &(*tpp)->t_subt;
1384 if (*tpp == NULL) 1384 if (*tpp == NULL)
1385 return decl; 1385 return decl;
1386 1386
1387 *tpp = tp = getblk(sizeof (type_t)); 1387 *tpp = tp = getblk(sizeof (type_t));
1388 tp->t_tspec = FUNC; 1388 tp->t_tspec = FUNC;
1389 tp->t_subt = dcs->d_next->d_type; 1389 tp->t_subt = dcs->d_next->d_type;
1390 if ((tp->t_proto = dcs->d_proto) != 0) 1390 if ((tp->t_proto = dcs->d_proto) != 0)
1391 tp->t_args = args; 1391 tp->t_args = args;
1392 tp->t_vararg = dcs->d_vararg; 1392 tp->t_vararg = dcs->d_vararg;
1393 1393
1394 return decl; 1394 return decl;
1395} 1395}
1396 1396
1397/* 1397/*
1398 * Called for new style function declarations. 1398 * Called for new style function declarations.