Tue Apr 11 19:02:19 2023 UTC ()
lint: condense code

No functional change.


(rillig)
diff -r1.64 -r1.65 src/usr.bin/xlint/lint1/mem1.c
diff -r1.508 -r1.509 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.64 -r1.65 src/usr.bin/xlint/lint1/mem1.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/mem1.c 2023/01/13 19:41:50 1.64
+++ src/usr.bin/xlint/lint1/mem1.c 2023/04/11 19:02:19 1.65
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $ */ 1/* $NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 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,27 +27,27 @@ @@ -27,27 +27,27 @@
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) 39#if defined(__RCSID)
40__RCSID("$NetBSD: mem1.c,v 1.64 2023/01/13 19:41:50 rillig Exp $"); 40__RCSID("$NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 rillig Exp $");
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46 46
47#include "lint1.h" 47#include "lint1.h"
48 48
49/* 49/*
50 * Filenames allocated by record_filename are shared and have unlimited 50 * Filenames allocated by record_filename are shared and have unlimited
51 * lifetime. 51 * lifetime.
52 */ 52 */
53struct filename { 53struct filename {
@@ -112,70 +112,68 @@ transform_filename(const char *name, siz @@ -112,70 +112,68 @@ transform_filename(const char *name, siz
112 if (r == NULL) 112 if (r == NULL)
113 return name; 113 return name;
114 (void)snprintf(buf, sizeof(buf), "%s%s", r->repl, name + r->orig_len); 114 (void)snprintf(buf, sizeof(buf), "%s%s", r->repl, name + r->orig_len);
115 return buf; 115 return buf;
116} 116}
117 117
118/* 118/*
119 * Return a copy of the filename s with unlimited lifetime. 119 * Return a copy of the filename s with unlimited lifetime.
120 * If the filename is new, write it to the output file. 120 * If the filename is new, write it to the output file.
121 */ 121 */
122const char * 122const char *
123record_filename(const char *s, size_t slen) 123record_filename(const char *s, size_t slen)
124{ 124{
125 const struct filename *existing_fn; 
126 struct filename *fn; 
127 char *name; 
128 125
129 if ((existing_fn = search_filename(s, slen)) != NULL) 126 const struct filename *existing_fn = search_filename(s, slen);
 127 if (existing_fn != NULL)
130 return existing_fn->fn_name; 128 return existing_fn->fn_name;
131 129
132 name = xmalloc(slen + 1); 130 char *name = xmalloc(slen + 1);
133 (void)memcpy(name, s, slen); 131 (void)memcpy(name, s, slen);
134 name[slen] = '\0'; 132 name[slen] = '\0';
135 133
136 fn = xmalloc(sizeof(*fn)); 134 struct filename *fn = xmalloc(sizeof(*fn));
137 fn->fn_name = name; 135 fn->fn_name = name;
138 fn->fn_len = slen; 136 fn->fn_len = slen;
139 fn->fn_id = next_filename_id++; 137 fn->fn_id = next_filename_id++;
140 fn->fn_next = filenames; 138 fn->fn_next = filenames;
141 filenames = fn; 139 filenames = fn;
142 140
143 /* Write the ID of this filename to the output file. */ 141 /* Write the ID of this filename to the output file. */
144 outclr(); 142 outclr();
145 outint(fn->fn_id); 143 outint(fn->fn_id);
146 outchar('s'); 144 outchar('s');
147 outstrg(transform_filename(fn->fn_name, fn->fn_len)); 145 outstrg(transform_filename(fn->fn_name, fn->fn_len));
148 146
149 return fn->fn_name; 147 return fn->fn_name;
150} 148}
151 149
152/* Get the ID of a filename. */ 150/* Get the ID of a filename. */
153int 151int
154get_filename_id(const char *s) 152get_filename_id(const char *s)
155{ 153{
156 const struct filename *fn; 154 const struct filename *fn;
157 155
158 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL) 156 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL)
159 return -1; 157 return -1;
160 return fn->fn_id; 158 return fn->fn_id;
161} 159}
162 160
163/* Array of memory pools, indexed by mem_block_level. */ 
164typedef struct memory_pools { 161typedef struct memory_pools {
165 struct memory_pool *pools; 162 struct memory_pool *pools;
166 size_t cap; 163 size_t cap;
167} memory_pools; 164} memory_pools;
168 165
 166/* Array of memory pools, indexed by mem_block_level. */
169static memory_pools mpools; 167static memory_pools mpools;
170 168
171/* The pool for the current expression is independent of any block level. */ 169/* The pool for the current expression is independent of any block level. */
172static memory_pool expr_pool; 170static memory_pool expr_pool;
173 171
174static void 172static void
175mpool_add(memory_pool *pool, void *item) 173mpool_add(memory_pool *pool, void *item)
176{ 174{
177 175
178 if (pool->len >= pool->cap) { 176 if (pool->len >= pool->cap) {
179 pool->cap = 2 * pool->len + 16; 177 pool->cap = 2 * pool->len + 16;
180 pool->items = xrealloc(pool->items, 178 pool->items = xrealloc(pool->items,
181 sizeof(*pool->items) * pool->cap); 179 sizeof(*pool->items) * pool->cap);

cvs diff -r1.508 -r1.509 src/usr.bin/xlint/lint1/tree.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/tree.c 2023/04/11 00:03:42 1.508
+++ src/usr.bin/xlint/lint1/tree.c 2023/04/11 19:02:19 1.509
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tree.c,v 1.508 2023/04/11 00:03:42 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.509 2023/04/11 19:02:19 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,27 +27,27 @@ @@ -27,27 +27,27 @@
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) 39#if defined(__RCSID)
40__RCSID("$NetBSD: tree.c,v 1.508 2023/04/11 00:03:42 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.509 2023/04/11 19:02:19 rillig Exp $");
41#endif 41#endif
42 42
43#include <float.h> 43#include <float.h>
44#include <limits.h> 44#include <limits.h>
45#include <math.h> 45#include <math.h>
46#include <signal.h> 46#include <signal.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49 49
50#include "lint1.h" 50#include "lint1.h"
51 51
52 52
53typedef struct integer_constraints { 53typedef struct integer_constraints {
@@ -1493,35 +1493,36 @@ fold_bool(tnode_t *tn) @@ -1493,35 +1493,36 @@ fold_bool(tnode_t *tn)
1493 case LOGOR: 1493 case LOGOR:
1494 v->v_quad = l || r ? 1 : 0; 1494 v->v_quad = l || r ? 1 : 0;
1495 break; 1495 break;
1496 default: 1496 default:
1497 lint_assert(/*CONSTCOND*/false); 1497 lint_assert(/*CONSTCOND*/false);
1498 } 1498 }
1499 1499
1500 return build_constant(tn->tn_type, v); 1500 return build_constant(tn->tn_type, v);
1501} 1501}
1502 1502
1503static ldbl_t 1503static ldbl_t
1504floating_error_value(tspec_t t, ldbl_t lv) 1504floating_error_value(tspec_t t, ldbl_t lv)
1505{ 1505{
1506 if (t == FLOAT) { 1506 if (t == FLOAT)
1507 return lv < 0 ? -FLT_MAX : FLT_MAX; 1507 return lv < 0 ? -FLT_MAX : FLT_MAX;
1508 } else if (t == DOUBLE) { 1508 if (t == DOUBLE)
1509 return lv < 0 ? -DBL_MAX : DBL_MAX; 1509 return lv < 0 ? -DBL_MAX : DBL_MAX;
1510 } else { 1510
1511 /* LINTED 248: floating-point constant out of range */ 1511 /* FIXME: Remove the '(double)' cast near 'isfinite'. */
1512 ldbl_t max = LDBL_MAX; 1512 /* FIXME: Inlining the variable 'max' produces a wrong warning. */
1513 return lv < 0 ? -max : max; 1513 /* LINTED 248: floating-point constant out of range */
1514 } 1514 ldbl_t max = LDBL_MAX;
 1515 return lv < 0 ? -max : max;
1515} 1516}
1516 1517
1517/* 1518/*
1518 * Fold constant nodes having operands with floating point type. 1519 * Fold constant nodes having operands with floating point type.
1519 */ 1520 */
1520static tnode_t * 1521static tnode_t *
1521fold_float(tnode_t *tn) 1522fold_float(tnode_t *tn)
1522{ 1523{
1523 val_t *v; 1524 val_t *v;
1524 tspec_t t; 1525 tspec_t t;
1525 ldbl_t lv, rv = 0; 1526 ldbl_t lv, rv = 0;
1526 1527
1527 fpe = 0; 1528 fpe = 0;
@@ -1875,33 +1876,30 @@ struct_or_union_member(tnode_t *tn, op_t @@ -1875,33 +1876,30 @@ struct_or_union_member(tnode_t *tn, op_t
1875 str = tp->t_str; 1876 str = tp->t_str;
1876 } else if (op == ARROW && t == PTR) { 1877 } else if (op == ARROW && t == PTR) {
1877 t = (tp = tp->t_subt)->t_tspec; 1878 t = (tp = tp->t_subt)->t_tspec;
1878 if (is_struct_or_union(t)) 1879 if (is_struct_or_union(t))
1879 str = tp->t_str; 1880 str = tp->t_str;
1880 } 1881 }
1881 1882
1882 /* 1883 /*
1883 * If this struct/union has a member with the name of msym, return it. 1884 * If this struct/union has a member with the name of msym, return it.
1884 */ 1885 */
1885 if (str != NULL) { 1886 if (str != NULL) {
1886 for (sym_t *sym = msym; 1887 for (sym_t *sym = msym;
1887 sym != NULL; sym = sym->s_symtab_next) { 1888 sym != NULL; sym = sym->s_symtab_next) {
1888 if (!is_member(sym)) 1889 if (is_member(sym) &&
1889 continue; 1890 sym->u.s_member.sm_sou_type == str &&
1890 if (sym->u.s_member.sm_sou_type != str) 1891 strcmp(sym->s_name, msym->s_name) == 0)
1891 continue; 1892 return sym;
1892 if (strcmp(sym->s_name, msym->s_name) != 0) 
1893 continue; 
1894 return sym; 
1895 } 1893 }
1896 } 1894 }
1897 1895
1898 bool eq = all_members_compatible(msym); 1896 bool eq = all_members_compatible(msym);
1899 1897
1900 /* 1898 /*
1901 * Now handle the case in which the left operand refers really 1899 * Now handle the case in which the left operand refers really
1902 * to a struct/union, but the right operand is not member of it. 1900 * to a struct/union, but the right operand is not member of it.
1903 */ 1901 */
1904 if (str != NULL) { 1902 if (str != NULL) {
1905 if (eq && !allow_c90) { 1903 if (eq && !allow_c90) {
1906 /* illegal use of member '%s' */ 1904 /* illegal use of member '%s' */
1907 warning(102, msym->s_name); 1905 warning(102, msym->s_name);
@@ -1967,53 +1965,51 @@ build_member_access(tnode_t *ln, op_t op @@ -1967,53 +1965,51 @@ build_member_access(tnode_t *ln, op_t op
1967 * Perform class conversions. 1965 * Perform class conversions.
1968 * 1966 *
1969 * Arrays of type T are converted into pointers to type T. 1967 * Arrays of type T are converted into pointers to type T.
1970 * Functions are converted to pointers to functions. 1968 * Functions are converted to pointers to functions.
1971 * Lvalues are converted to rvalues. 1969 * Lvalues are converted to rvalues.
1972 * 1970 *
1973 * C99 6.3 "Conversions" 1971 * C99 6.3 "Conversions"
1974 * C99 6.3.2 "Other operands" 1972 * C99 6.3.2 "Other operands"
1975 * C99 6.3.2.1 "Lvalues, arrays, and function designators" 1973 * C99 6.3.2.1 "Lvalues, arrays, and function designators"
1976 */ 1974 */
1977tnode_t * 1975tnode_t *
1978cconv(tnode_t *tn) 1976cconv(tnode_t *tn)
1979{ 1977{
1980 type_t *tp; 
1981 
1982 /* 1978 /*
1983 * Array-lvalue (array of type T) is converted into rvalue 1979 * Array-lvalue (array of type T) is converted into rvalue
1984 * (pointer to type T) 1980 * (pointer to type T)
1985 */ 1981 */
1986 if (tn->tn_type->t_tspec == ARRAY) { 1982 if (tn->tn_type->t_tspec == ARRAY) {
1987 if (!tn->tn_lvalue) { 1983 if (!tn->tn_lvalue) {
1988 /* XXX print correct operator */ 1984 /* XXX print correct operator */
1989 /* %soperand of '%s' must be lvalue */ 1985 /* %soperand of '%s' must be lvalue */
1990 gnuism(114, "", op_name(ADDR)); 1986 gnuism(114, "", op_name(ADDR));
1991 } 1987 }
1992 tn = new_tnode(ADDR, tn->tn_sys, 1988 tn = new_tnode(ADDR, tn->tn_sys,
1993 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); 1989 expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL);
1994 } 1990 }
1995 1991
1996 /* 1992 /*
1997 * Expression of type function (function with return value of type T) 1993 * Expression of type function (function with return value of type T)
1998 * in rvalue-expression (pointer to function with return value 1994 * in rvalue-expression (pointer to function with return value
1999 * of type T) 1995 * of type T)
2000 */ 1996 */
2001 if (tn->tn_type->t_tspec == FUNC) 1997 if (tn->tn_type->t_tspec == FUNC)
2002 tn = build_address(tn->tn_sys, tn, true); 1998 tn = build_address(tn->tn_sys, tn, true);
2003 1999
2004 /* lvalue to rvalue */ 2000 /* lvalue to rvalue */
2005 if (tn->tn_lvalue) { 2001 if (tn->tn_lvalue) {
2006 tp = expr_dup_type(tn->tn_type); 2002 type_t *tp = expr_dup_type(tn->tn_type);
2007 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */ 2003 /* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
2008 tp->t_const = tp->t_volatile = false; 2004 tp->t_const = tp->t_volatile = false;
2009 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL); 2005 tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL);
2010 } 2006 }
2011 2007
2012 return tn; 2008 return tn;
2013} 2009}
2014 2010
2015const tnode_t * 2011const tnode_t *
2016before_conversion(const tnode_t *tn) 2012before_conversion(const tnode_t *tn)
2017{ 2013{
2018 while (tn->tn_op == CVT && !tn->tn_cast) 2014 while (tn->tn_op == CVT && !tn->tn_cast)
2019 tn = tn->tn_left; 2015 tn = tn->tn_left;
@@ -2073,30 +2069,30 @@ typeok_arrow(tspec_t lt) @@ -2073,30 +2069,30 @@ typeok_arrow(tspec_t lt)
2073static bool 2069static bool
2074typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) 2070typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp)
2075{ 2071{
2076 /* operand has scalar type (checked in typeok) */ 2072 /* operand has scalar type (checked in typeok) */
2077 if (!tn->tn_lvalue) { 2073 if (!tn->tn_lvalue) {
2078 if (tn->tn_op == CVT && tn->tn_cast && 2074 if (tn->tn_op == CVT && tn->tn_cast &&
2079 tn->tn_left->tn_op == LOAD) { 2075 tn->tn_left->tn_op == LOAD) {
2080 /* a cast does not yield an lvalue */ 2076 /* a cast does not yield an lvalue */
2081 error(163); 2077 error(163);
2082 } 2078 }
2083 /* %soperand of '%s' must be lvalue */ 2079 /* %soperand of '%s' must be lvalue */
2084 error(114, "", op_name(op)); 2080 error(114, "", op_name(op));
2085 return false; 2081 return false;
2086 } else if (tp->t_const) { 2082 }
2087 if (allow_c90) 2083 if (tp->t_const && allow_c90) {
2088 /* %soperand of '%s' must be modifiable lvalue */ 2084 /* %soperand of '%s' must be modifiable lvalue */
2089 warning(115, "", op_name(op)); 2085 warning(115, "", op_name(op));
2090 } 2086 }
2091 return true; 2087 return true;
2092} 2088}
2093 2089
2094static bool 2090static bool
2095typeok_address(const mod_t *mp, 2091typeok_address(const mod_t *mp,
2096 const tnode_t *tn, const type_t *tp, tspec_t t) 2092 const tnode_t *tn, const type_t *tp, tspec_t t)
2097{ 2093{
2098 if (t == ARRAY || t == FUNC) { 2094 if (t == ARRAY || t == FUNC) {
2099 /* ok, a warning comes later (in build_address()) */ 2095 /* ok, a warning comes later (in build_address()) */
2100 } else if (!tn->tn_lvalue) { 2096 } else if (!tn->tn_lvalue) {
2101 if (tn->tn_op == CVT && tn->tn_cast && 2097 if (tn->tn_op == CVT && tn->tn_cast &&
2102 tn->tn_left->tn_op == LOAD) { 2098 tn->tn_left->tn_op == LOAD) {
@@ -2127,38 +2123,32 @@ typeok_address(const mod_t *mp, @@ -2127,38 +2123,32 @@ typeok_address(const mod_t *mp,
2127 2123
2128static bool 2124static bool
2129typeok_indir(const type_t *tp, tspec_t t) 2125typeok_indir(const type_t *tp, tspec_t t)
2130{ 2126{
2131 2127
2132 if (t != PTR) { 2128 if (t != PTR) {
2133 /* cannot dereference non-pointer type '%s' */ 2129 /* cannot dereference non-pointer type '%s' */
2134 error(96, type_name(tp)); 2130 error(96, type_name(tp));
2135 return false; 2131 return false;
2136 } 2132 }
2137 return true; 2133 return true;
2138} 2134}
2139 2135
2140/* 
2141 * Called if incompatible types were detected. 
2142 * Prints a appropriate warning. 
2143 */ 
2144static void 2136static void
2145warn_incompatible_types(op_t op, 2137warn_incompatible_types(op_t op,
2146 const type_t *ltp, tspec_t lt, 2138 const type_t *ltp, tspec_t lt,
2147 const type_t *rtp, tspec_t rt) 2139 const type_t *rtp, tspec_t rt)
2148{ 2140{
2149 const mod_t *mp; 2141 const mod_t *mp = &modtab[op];
2150 
2151 mp = &modtab[op]; 
2152 2142
2153 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2143 if (lt == VOID || (mp->m_binary && rt == VOID)) {
2154 /* void type illegal in expression */ 2144 /* void type illegal in expression */
2155 error(109); 2145 error(109);
2156 } else if (op == ASSIGN) { 2146 } else if (op == ASSIGN) {
2157 /* cannot assign to '%s' from '%s' */ 2147 /* cannot assign to '%s' from '%s' */
2158 error(171, type_name(ltp), type_name(rtp)); 2148 error(171, type_name(ltp), type_name(rtp));
2159 } else if (mp->m_binary) { 2149 } else if (mp->m_binary) {
2160 /* operands of '%s' have incompatible types '%s' and '%s' */ 2150 /* operands of '%s' have incompatible types '%s' and '%s' */
2161 error(107, mp->m_name, tspec_name(lt), tspec_name(rt)); 2151 error(107, mp->m_name, tspec_name(lt), tspec_name(rt));
2162 } else { 2152 } else {
2163 lint_assert(rt == NOTSPEC); 2153 lint_assert(rt == NOTSPEC);
2164 /* operand of '%s' has invalid type '%s' */ 2154 /* operand of '%s' has invalid type '%s' */
@@ -2180,32 +2170,30 @@ typeok_plus(op_t op, @@ -2180,32 +2170,30 @@ typeok_plus(op_t op,
2180} 2170}
2181 2171
2182static bool 2172static bool
2183typeok_minus(op_t op, 2173typeok_minus(op_t op,
2184 const type_t *ltp, tspec_t lt, 2174 const type_t *ltp, tspec_t lt,
2185 const type_t *rtp, tspec_t rt) 2175 const type_t *rtp, tspec_t rt)
2186{ 2176{
2187 /* operands have scalar types (checked in typeok) */ 2177 /* operands have scalar types (checked in typeok) */
2188 if ((lt == PTR && rt != PTR && !is_integer(rt)) || 2178 if ((lt == PTR && rt != PTR && !is_integer(rt)) ||
2189 (lt != PTR && rt == PTR)) { 2179 (lt != PTR && rt == PTR)) {
2190 warn_incompatible_types(op, ltp, lt, rtp, rt); 2180 warn_incompatible_types(op, ltp, lt, rtp, rt);
2191 return false; 2181 return false;
2192 } 2182 }
2193 if (lt == PTR && rt == PTR) { 2183 if (lt == PTR && rt == PTR &&
2194 if (!types_compatible(ltp->t_subt, rtp->t_subt, 2184 !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2195 true, false, NULL)) { 2185 /* illegal pointer subtraction */
2196 /* illegal pointer subtraction */ 2186 error(116);
2197 error(116); 
2198 } 
2199 } 2187 }
2200 return true; 2188 return true;
2201} 2189}
2202 2190
2203static void 2191static void
2204typeok_shr(const mod_t *mp, 2192typeok_shr(const mod_t *mp,
2205 const tnode_t *ln, tspec_t lt, 2193 const tnode_t *ln, tspec_t lt,
2206 const tnode_t *rn, tspec_t rt) 2194 const tnode_t *rn, tspec_t rt)
2207{ 2195{
2208 tspec_t olt, ort; 2196 tspec_t olt, ort;
2209 2197
2210 olt = before_conversion(ln)->tn_type->t_tspec; 2198 olt = before_conversion(ln)->tn_type->t_tspec;
2211 ort = before_conversion(rn)->tn_type->t_tspec; 2199 ort = before_conversion(rn)->tn_type->t_tspec;
@@ -2219,30 +2207,27 @@ typeok_shr(const mod_t *mp, @@ -2219,30 +2207,27 @@ typeok_shr(const mod_t *mp,
2219 /* 2207 /*
2220 * The left operand is signed. This means that 2208 * The left operand is signed. This means that
2221 * the operation is (possibly) nonportable. 2209 * the operation is (possibly) nonportable.
2222 */ 2210 */
2223 if (ln->tn_op != CON) { 2211 if (ln->tn_op != CON) {
2224 /* bitwise '%s' on signed value possibly nonportable */ 2212 /* bitwise '%s' on signed value possibly nonportable */
2225 warning(117, mp->m_name); 2213 warning(117, mp->m_name);
2226 } else if (ln->tn_val->v_quad < 0) { 2214 } else if (ln->tn_val->v_quad < 0) {
2227 /* bitwise '%s' on signed value nonportable */ 2215 /* bitwise '%s' on signed value nonportable */
2228 warning(120, mp->m_name); 2216 warning(120, mp->m_name);
2229 } 2217 }
2230 } else if (allow_trad && allow_c90 && 2218 } else if (allow_trad && allow_c90 &&
2231 !is_uinteger(olt) && is_uinteger(ort)) { 2219 !is_uinteger(olt) && is_uinteger(ort)) {
2232 /* 2220 /* The left operand would become unsigned in traditional C. */
2233 * The left operand would become unsigned in 
2234 * traditional C. 
2235 */ 
2236 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2221 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2237 /* semantics of '%s' change in ANSI C; use ... */ 2222 /* semantics of '%s' change in ANSI C; use ... */
2238 warning(118, mp->m_name); 2223 warning(118, mp->m_name);
2239 } 2224 }
2240 } else if (allow_trad && allow_c90 && 2225 } else if (allow_trad && allow_c90 &&
2241 !is_uinteger(olt) && !is_uinteger(ort) && 2226 !is_uinteger(olt) && !is_uinteger(ort) &&
2242 portable_size_in_bits(lt) < portable_size_in_bits(rt)) { 2227 portable_size_in_bits(lt) < portable_size_in_bits(rt)) {
2243 /* 2228 /*
2244 * In traditional C the left operand would be extended 2229 * In traditional C the left operand would be extended
2245 * (possibly sign-extended) and then shifted. 2230 * (possibly sign-extended) and then shifted.
2246 */ 2231 */
2247 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 2232 if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
2248 /* semantics of '%s' change in ANSI C; use ... */ 2233 /* semantics of '%s' change in ANSI C; use ... */
@@ -2303,112 +2288,105 @@ is_typeok_eq(const tnode_t *ln, tspec_t  @@ -2303,112 +2288,105 @@ is_typeok_eq(const tnode_t *ln, tspec_t
2303 if (rt == PTR && is_null_pointer(ln)) 2288 if (rt == PTR && is_null_pointer(ln))
2304 return true; 2289 return true;
2305 return false; 2290 return false;
2306} 2291}
2307 2292
2308/* 2293/*
2309 * Called if incompatible pointer types are detected. 2294 * Called if incompatible pointer types are detected.
2310 * Print an appropriate warning. 2295 * Print an appropriate warning.
2311 */ 2296 */
2312static void 2297static void
2313warn_incompatible_pointers(const mod_t *mp, 2298warn_incompatible_pointers(const mod_t *mp,
2314 const type_t *ltp, const type_t *rtp) 2299 const type_t *ltp, const type_t *rtp)
2315{ 2300{
2316 tspec_t lt, rt; 
2317 
2318 lint_assert(ltp->t_tspec == PTR); 2301 lint_assert(ltp->t_tspec == PTR);
2319 lint_assert(rtp->t_tspec == PTR); 2302 lint_assert(rtp->t_tspec == PTR);
2320 2303
2321 lt = ltp->t_subt->t_tspec; 2304 tspec_t lt = ltp->t_subt->t_tspec;
2322 rt = rtp->t_subt->t_tspec; 2305 tspec_t rt = rtp->t_subt->t_tspec;
2323 2306
2324 if (is_struct_or_union(lt) && is_struct_or_union(rt)) { 2307 if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
2325 if (mp == NULL) { 2308 if (mp == NULL) {
2326 /* illegal structure pointer combination */ 2309 /* illegal structure pointer combination */
2327 warning(244); 2310 warning(244);
2328 } else { 2311 } else {
2329 /* incompatible structure pointers: '%s' '%s' '%s' */ 2312 /* incompatible structure pointers: '%s' '%s' '%s' */
2330 warning(245, type_name(ltp), mp->m_name, type_name(rtp)); 2313 warning(245, type_name(ltp), mp->m_name, type_name(rtp));
2331 } 2314 }
2332 } else { 2315 } else {
2333 if (mp == NULL) { 2316 if (mp == NULL) {
2334 /* illegal combination of '%s' and '%s' */ 2317 /* illegal combination of '%s' and '%s' */
2335 warning(184, type_name(ltp), type_name(rtp)); 2318 warning(184, type_name(ltp), type_name(rtp));
2336 } else { 2319 } else {
2337 /* illegal combination of '%s' and '%s', op '%s' */ 2320 /* illegal combination of '%s' and '%s', op '%s' */
2338 warning(124, 2321 warning(124,
2339 type_name(ltp), type_name(rtp), mp->m_name); 2322 type_name(ltp), type_name(rtp), mp->m_name);
2340 } 2323 }
2341 } 2324 }
2342} 2325}
2343 2326
2344static void 2327static void
2345check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) 2328check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
2346{ 2329{
2347 type_t *ltp, *rtp; 2330 type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
2348 tspec_t lst, rst; 2331 tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
2349 const char *lsts, *rsts; 
2350 
2351 lst = (ltp = ln->tn_type)->t_subt->t_tspec; 
2352 rst = (rtp = rn->tn_type)->t_subt->t_tspec; 
2353 2332
2354 if (lst == VOID || rst == VOID) { 2333 if (lst == VOID || rst == VOID) {
2355 /* TODO: C99 behaves like C90 here. */ 2334 /* TODO: C99 behaves like C90 here. */
2356 if ((!allow_trad && !allow_c99) && 2335 if ((!allow_trad && !allow_c99) &&
2357 (lst == FUNC || rst == FUNC)) { 2336 (lst == FUNC || rst == FUNC)) {
2358 /* (void *)0 already handled in typeok() */ 2337 /* (void *)0 is already handled in typeok() */
 2338 const char *lsts, *rsts;
2359 *(lst == FUNC ? &lsts : &rsts) = "function pointer"; 2339 *(lst == FUNC ? &lsts : &rsts) = "function pointer";
2360 *(lst == VOID ? &lsts : &rsts) = "'void *'"; 2340 *(lst == VOID ? &lsts : &rsts) = "'void *'";
2361 /* ANSI C forbids comparison of %s with %s */ 2341 /* ANSI C forbids comparison of %s with %s */
2362 warning(274, lsts, rsts); 2342 warning(274, lsts, rsts);
2363 } 2343 }
2364 return; 2344 return;
2365 } 2345 }
2366 2346
2367 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) { 2347 if (!types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
2368 warn_incompatible_pointers(&modtab[op], ltp, rtp); 2348 warn_incompatible_pointers(&modtab[op], ltp, rtp);
2369 return; 2349 return;
2370 } 2350 }
2371 2351
2372 if (lst == FUNC && rst == FUNC) { 2352 if (lst == FUNC && rst == FUNC) {
2373 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */ 2353 /* TODO: C99 behaves like C90 here, see C99 6.5.8p2. */
2374 if ((!allow_trad && !allow_c99) && op != EQ && op != NE) 2354 if ((!allow_trad && !allow_c99) && op != EQ && op != NE)
2375 /* ANSI C forbids ordered comparisons of ... */ 2355 /* ANSI C forbids ordered comparisons of ... */
2376 warning(125); 2356 warning(125);
2377 } 2357 }
2378} 2358}
2379 2359
2380static bool 2360static bool
2381typeok_compare(op_t op, 2361typeok_compare(op_t op,
2382 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2362 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2383 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2363 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2384{ 2364{
2385 const char *lx, *rx; 
2386 
2387 if (lt == PTR && rt == PTR) { 2365 if (lt == PTR && rt == PTR) {
2388 check_pointer_comparison(op, ln, rn); 2366 check_pointer_comparison(op, ln, rn);
2389 return true; 2367 return true;
2390 } 2368 }
2391 2369
2392 if (lt != PTR && rt != PTR) 2370 if (lt != PTR && rt != PTR)
2393 return true; 2371 return true;
2394 2372
2395 if (!is_integer(lt) && !is_integer(rt)) { 2373 if (!is_integer(lt) && !is_integer(rt)) {
2396 warn_incompatible_types(op, ltp, lt, rtp, rt); 2374 warn_incompatible_types(op, ltp, lt, rtp, rt);
2397 return false; 2375 return false;
2398 } 2376 }
2399 2377
2400 lx = lt == PTR ? "pointer" : "integer"; 2378 const char *lx = lt == PTR ? "pointer" : "integer";
2401 rx = rt == PTR ? "pointer" : "integer"; 2379 const char *rx = rt == PTR ? "pointer" : "integer";
2402 /* illegal combination of %s '%s' and %s '%s', op '%s' */ 2380 /* illegal combination of %s '%s' and %s '%s', op '%s' */
2403 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op)); 2381 warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
2404 return true; 2382 return true;
2405} 2383}
2406 2384
2407static bool 2385static bool
2408typeok_quest(tspec_t lt, const tnode_t *rn) 2386typeok_quest(tspec_t lt, const tnode_t *rn)
2409{ 2387{
2410 if (!is_scalar(lt)) { 2388 if (!is_scalar(lt)) {
2411 /* first operand must have scalar type, op ? : */ 2389 /* first operand must have scalar type, op ? : */
2412 error(170); 2390 error(170);
2413 return false; 2391 return false;
2414 } 2392 }
@@ -2484,31 +2462,30 @@ typeok_colon(const mod_t *mp, @@ -2484,31 +2462,30 @@ typeok_colon(const mod_t *mp,
2484 2462
2485 /* incompatible types '%s' and '%s' in conditional */ 2463 /* incompatible types '%s' and '%s' in conditional */
2486 error(126, type_name(ltp), type_name(rtp)); 2464 error(126, type_name(ltp), type_name(rtp));
2487 return false; 2465 return false;
2488} 2466}
2489 2467
2490/* 2468/*
2491 * Returns true if the given structure or union has a constant member 2469 * Returns true if the given structure or union has a constant member
2492 * (maybe recursively). 2470 * (maybe recursively).
2493 */ 2471 */
2494static bool 2472static bool
2495has_constant_member(const type_t *tp) 2473has_constant_member(const type_t *tp)
2496{ 2474{
2497 sym_t *m; 
2498 
2499 lint_assert(is_struct_or_union(tp->t_tspec)); 2475 lint_assert(is_struct_or_union(tp->t_tspec));
2500 2476
2501 for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { 2477 for (sym_t *m = tp->t_str->sou_first_member;
 2478 m != NULL; m = m->s_next) {
2502 const type_t *mtp = m->s_type; 2479 const type_t *mtp = m->s_type;
2503 if (mtp->t_const) 2480 if (mtp->t_const)
2504 return true; 2481 return true;
2505 if (is_struct_or_union(mtp->t_tspec) && 2482 if (is_struct_or_union(mtp->t_tspec) &&
2506 has_constant_member(mtp)) 2483 has_constant_member(mtp))
2507 return true; 2484 return true;
2508 } 2485 }
2509 return false; 2486 return false;
2510} 2487}
2511 2488
2512static bool 2489static bool
2513typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt) 2490typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt)
2514{ 2491{
@@ -2562,37 +2539,37 @@ typeok_scalar(op_t op, const mod_t *mp, @@ -2562,37 +2539,37 @@ typeok_scalar(op_t op, const mod_t *mp,
2562 (mp->m_binary && !is_arithmetic(rt))) { 2539 (mp->m_binary && !is_arithmetic(rt))) {
2563 warn_incompatible_types(op, ltp, lt, rtp, rt); 2540 warn_incompatible_types(op, ltp, lt, rtp, rt);
2564 return false; 2541 return false;
2565 } 2542 }
2566 } 2543 }
2567 return true; 2544 return true;
2568} 2545}
2569 2546
2570static void 2547static void
2571check_assign_void_pointer(op_t op, int arg, 2548check_assign_void_pointer(op_t op, int arg,
2572 tspec_t lt, tspec_t lst, 2549 tspec_t lt, tspec_t lst,
2573 tspec_t rt, tspec_t rst) 2550 tspec_t rt, tspec_t rst)
2574{ 2551{
2575 const char *lts, *rts; 
2576 2552
2577 if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID))) 2553 if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID)))
2578 return; 2554 return;
2579 /* two pointers, at least one pointer to void */ 2555 /* two pointers, at least one pointer to void */
2580 2556
2581 /* TODO: C99 behaves like C90 here. */ 2557 /* TODO: C99 behaves like C90 here. */
2582 if (!((!allow_trad && !allow_c99) && (lst == FUNC || rst == FUNC))) 2558 if (!((!allow_trad && !allow_c99) && (lst == FUNC || rst == FUNC)))
2583 return; 2559 return;
2584 /* comb. of ptr to func and ptr to void */ 2560 /* comb. of ptr to func and ptr to void */
2585 2561
 2562 const char *lts, *rts;
2586 *(lst == FUNC ? &lts : &rts) = "function pointer"; 2563 *(lst == FUNC ? &lts : &rts) = "function pointer";
2587 *(lst == VOID ? &lts : &rts) = "'void *'"; 2564 *(lst == VOID ? &lts : &rts) = "'void *'";
2588 2565
2589 switch (op) { 2566 switch (op) {
2590 case INIT: 2567 case INIT:
2591 case RETURN: 2568 case RETURN:
2592 /* ANSI C forbids conversion of %s to %s */ 2569 /* ANSI C forbids conversion of %s to %s */
2593 warning(303, rts, lts); 2570 warning(303, rts, lts);
2594 break; 2571 break;
2595 case FARG: 2572 case FARG:
2596 /* ANSI C forbids conversion of %s to %s, arg #%d */ 2573 /* ANSI C forbids conversion of %s to %s, arg #%d */
2597 warning(304, rts, lts, arg); 2574 warning(304, rts, lts, arg);
2598 break; 2575 break;
@@ -2620,79 +2597,71 @@ static bool @@ -2620,79 +2597,71 @@ static bool
2620is_unconst_function(const char *name) 2597is_unconst_function(const char *name)
2621{ 2598{
2622 2599
2623 return strcmp(name, "memchr") == 0 || 2600 return strcmp(name, "memchr") == 0 ||
2624 strcmp(name, "strchr") == 0 || 2601 strcmp(name, "strchr") == 0 ||
2625 strcmp(name, "strpbrk") == 0 || 2602 strcmp(name, "strpbrk") == 0 ||
2626 strcmp(name, "strrchr") == 0 || 2603 strcmp(name, "strrchr") == 0 ||
2627 strcmp(name, "strstr") == 0; 2604 strcmp(name, "strstr") == 0;
2628} 2605}
2629 2606
2630static bool 2607static bool
2631is_const_char_pointer(const tnode_t *tn) 2608is_const_char_pointer(const tnode_t *tn)
2632{ 2609{
2633 const type_t *tp; 
2634 
2635 /* 2610 /*
2636 * For traditional reasons, C99 6.4.5p5 defines that string literals 2611 * For traditional reasons, C99 6.4.5p5 defines that string literals
2637 * have type 'char[]'. They are often implicitly converted to 2612 * have type 'char[]'. They are often implicitly converted to
2638 * 'char *', for example when they are passed as function arguments. 2613 * 'char *', for example when they are passed as function arguments.
2639 * 2614 *
2640 * C99 6.4.5p6 further defines that modifying a string that is 2615 * C99 6.4.5p6 further defines that modifying a string that is
2641 * constructed from a string literal invokes undefined behavior. 2616 * constructed from a string literal invokes undefined behavior.
2642 * 2617 *
2643 * Out of these reasons, string literals are treated as 'effectively 2618 * Out of these reasons, string literals are treated as 'effectively
2644 * const' here. 2619 * const' here.
2645 */ 2620 */
2646 if (tn->tn_op == CVT && 2621 if (tn->tn_op == CVT &&
2647 tn->tn_left->tn_op == ADDR && 2622 tn->tn_left->tn_op == ADDR &&
2648 tn->tn_left->tn_left->tn_op == STRING) 2623 tn->tn_left->tn_left->tn_op == STRING)
2649 return true; 2624 return true;
2650 2625
2651 tp = before_conversion(tn)->tn_type; 2626 const type_t *tp = before_conversion(tn)->tn_type;
2652 return tp->t_tspec == PTR && 2627 return tp->t_tspec == PTR &&
2653 tp->t_subt->t_tspec == CHAR && 2628 tp->t_subt->t_tspec == CHAR &&
2654 tp->t_subt->t_const; 2629 tp->t_subt->t_const;
2655} 2630}
2656 2631
2657static bool 2632static bool
2658is_first_arg_const_char_pointer(const tnode_t *tn) 2633is_first_arg_const_char_pointer(const tnode_t *tn)
2659{ 2634{
2660 const tnode_t *an; 2635 const tnode_t *an = tn->tn_right;
2661 
2662 an = tn->tn_right; 
2663 if (an == NULL) 2636 if (an == NULL)
2664 return false; 2637 return false;
2665 2638
2666 while (an->tn_right != NULL) 2639 while (an->tn_right != NULL)
2667 an = an->tn_right; 2640 an = an->tn_right;
2668 return is_const_char_pointer(an->tn_left); 2641 return is_const_char_pointer(an->tn_left);
2669} 2642}
2670 2643
2671static bool 2644static bool
2672is_const_pointer(const tnode_t *tn) 2645is_const_pointer(const tnode_t *tn)
2673{ 2646{
2674 const type_t *tp; 2647 const type_t *tp = before_conversion(tn)->tn_type;
2675 
2676 tp = before_conversion(tn)->tn_type; 
2677 return tp->t_tspec == PTR && tp->t_subt->t_const; 2648 return tp->t_tspec == PTR && tp->t_subt->t_const;
2678} 2649}
2679 2650
2680static bool 2651static bool
2681is_second_arg_const_pointer(const tnode_t *tn) 2652is_second_arg_const_pointer(const tnode_t *tn)
2682{ 2653{
2683 const tnode_t *an; 2654 const tnode_t *an = tn->tn_right;
2684 
2685 an = tn->tn_right; 
2686 if (an == NULL || an->tn_right == NULL) 2655 if (an == NULL || an->tn_right == NULL)
2687 return false; 2656 return false;
2688 2657
2689 while (an->tn_right->tn_right != NULL) 2658 while (an->tn_right->tn_right != NULL)
2690 an = an->tn_right; 2659 an = an->tn_right;
2691 return is_const_pointer(an->tn_left); 2660 return is_const_pointer(an->tn_left);
2692} 2661}
2693 2662
2694static void 2663static void
2695check_unconst_function(const type_t *lstp, const tnode_t *rn) 2664check_unconst_function(const type_t *lstp, const tnode_t *rn)
2696{ 2665{
2697 const char *function_name; 2666 const char *function_name;
2698 2667
@@ -2930,37 +2899,33 @@ is_local_symbol(const tnode_t *tn) @@ -2930,37 +2899,33 @@ is_local_symbol(const tnode_t *tn)
2930static bool 2899static bool
2931is_int_constant_zero(const tnode_t *tn) 2900is_int_constant_zero(const tnode_t *tn)
2932{ 2901{
2933 2902
2934 return tn->tn_op == CON && 2903 return tn->tn_op == CON &&
2935 tn->tn_type->t_tspec == INT && 2904 tn->tn_type->t_tspec == INT &&
2936 tn->tn_val->v_quad == 0; 2905 tn->tn_val->v_quad == 0;
2937} 2906}
2938 2907
2939static void 2908static void
2940check_null_effect(const tnode_t *tn) 2909check_null_effect(const tnode_t *tn)
2941{ 2910{
2942 2911
2943 if (!hflag) 2912 if (hflag &&
2944 return; 2913 !has_side_effect(tn) &&
2945 if (has_side_effect(tn)) 2914 !(is_void_cast(tn) && is_local_symbol(tn->tn_left)) &&
2946 return; 2915 !(is_void_cast(tn) && is_int_constant_zero(tn->tn_left))) {
2947 if (is_void_cast(tn) && is_local_symbol(tn->tn_left)) 2916 /* expression has null effect */
2948 return; 2917 warning(129);
2949 if (is_void_cast(tn) && is_int_constant_zero(tn->tn_left)) 2918 }
2950 return; 
2951 
2952 /* expression has null effect */ 
2953 warning(129); 
2954} 2919}
2955 2920
2956/* 2921/*
2957 * Check the types for specific operators and type combinations. 2922 * Check the types for specific operators and type combinations.
2958 * 2923 *
2959 * At this point, the operands already conform to the type requirements of 2924 * At this point, the operands already conform to the type requirements of
2960 * the operator, such as being integer, floating or scalar. 2925 * the operator, such as being integer, floating or scalar.
2961 */ 2926 */
2962static bool 2927static bool
2963typeok_op(op_t op, const mod_t *mp, int arg, 2928typeok_op(op_t op, const mod_t *mp, int arg,
2964 const tnode_t *ln, const type_t *ltp, tspec_t lt, 2929 const tnode_t *ln, const type_t *ltp, tspec_t lt,
2965 const tnode_t *rn, const type_t *rtp, tspec_t rt) 2930 const tnode_t *rn, const type_t *rtp, tspec_t rt)
2966{ 2931{
@@ -3065,29 +3030,27 @@ check_bad_enum_operation(op_t op, const  @@ -3065,29 +3030,27 @@ check_bad_enum_operation(op_t op, const
3065 return; 3030 return;
3066 } 3031 }
3067 3032
3068 /* dubious operation on enum, op '%s' */ 3033 /* dubious operation on enum, op '%s' */
3069 warning(241, op_name(op)); 3034 warning(241, op_name(op));
3070} 3035}
3071 3036
3072/* 3037/*
3073 * Prints a warning if an operator is applied to two different enum types. 3038 * Prints a warning if an operator is applied to two different enum types.
3074 */ 3039 */
3075static void 3040static void
3076check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 3041check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3077{ 3042{
3078 const mod_t *mp; 3043 const mod_t *mp = &modtab[op];
3079 
3080 mp = &modtab[op]; 
3081 3044
3082 if (ln->tn_type->t_enum != rn->tn_type->t_enum) { 3045 if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
3083 switch (op) { 3046 switch (op) {
3084 case INIT: 3047 case INIT:
3085 /* enum type mismatch between '%s' and '%s' in ... */ 3048 /* enum type mismatch between '%s' and '%s' in ... */
3086 warning(210, 3049 warning(210,
3087 type_name(ln->tn_type), type_name(rn->tn_type)); 3050 type_name(ln->tn_type), type_name(rn->tn_type));
3088 break; 3051 break;
3089 case FARG: 3052 case FARG:
3090 /* function expects '%s', passing '%s' for arg #%d */ 3053 /* function expects '%s', passing '%s' for arg #%d */
3091 warning(156, 3054 warning(156,
3092 type_name(ln->tn_type), type_name(rn->tn_type), 3055 type_name(ln->tn_type), type_name(rn->tn_type),
3093 arg); 3056 arg);
@@ -3160,31 +3123,30 @@ typeok_enum(op_t op, const mod_t *mp, in @@ -3160,31 +3123,30 @@ typeok_enum(op_t op, const mod_t *mp, in
3160 } else if (mp->m_valid_on_enum && 3123 } else if (mp->m_valid_on_enum &&
3161 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) { 3124 (ltp->t_is_enum && rtp != NULL && rtp->t_is_enum)) {
3162 check_enum_type_mismatch(op, arg, ln, rn); 3125 check_enum_type_mismatch(op, arg, ln, rn);
3163 } else if (mp->m_valid_on_enum && 3126 } else if (mp->m_valid_on_enum &&
3164 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) { 3127 (ltp->t_is_enum || (rtp != NULL && rtp->t_is_enum))) {
3165 check_enum_int_mismatch(op, arg, ln, rn); 3128 check_enum_int_mismatch(op, arg, ln, rn);
3166 } 3129 }
3167} 3130}
3168 3131
3169/* Perform most type checks. Return whether the types are ok. */ 3132/* Perform most type checks. Return whether the types are ok. */
3170bool 3133bool
3171typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) 3134typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
3172{ 3135{
3173 const mod_t *mp; 
3174 tspec_t lt, rt; 3136 tspec_t lt, rt;
3175 type_t *ltp, *rtp; 3137 type_t *ltp, *rtp;
3176 3138
3177 mp = &modtab[op]; 3139 const mod_t *mp = &modtab[op];
3178 3140
3179 lint_assert((ltp = ln->tn_type) != NULL); 3141 lint_assert((ltp = ln->tn_type) != NULL);
3180 lt = ltp->t_tspec; 3142 lt = ltp->t_tspec;
3181 3143
3182 if (mp->m_binary) { 3144 if (mp->m_binary) {
3183 lint_assert((rtp = rn->tn_type) != NULL); 3145 lint_assert((rtp = rn->tn_type) != NULL);
3184 rt = rtp->t_tspec; 3146 rt = rtp->t_tspec;
3185 } else { 3147 } else {
3186 rtp = NULL; 3148 rtp = NULL;
3187 rt = NOTSPEC; 3149 rt = NOTSPEC;
3188 } 3150 }
3189 3151
3190 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn)) 3152 if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn))
@@ -3329,42 +3291,41 @@ should_warn_about_prototype_conversion(t @@ -3329,42 +3291,41 @@ should_warn_about_prototype_conversion(t
3329 3291
3330/* 3292/*
3331 * Warn if a prototype causes a type conversion that is different from what 3293 * Warn if a prototype causes a type conversion that is different from what
3332 * would happen to the same argument in the absence of a prototype. This 3294 * would happen to the same argument in the absence of a prototype. This
3333 * check is intended for code that needs to stay compatible with pre-C90 C. 3295 * check is intended for code that needs to stay compatible with pre-C90 C.
3334 * 3296 *
3335 * Errors/warnings about illegal type combinations are already printed 3297 * Errors/warnings about illegal type combinations are already printed
3336 * in check_assign_types_compatible(). 3298 * in check_assign_types_compatible().
3337 */ 3299 */
3338static void 3300static void
3339check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp, 3301check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
3340 tnode_t *tn) 3302 tnode_t *tn)
3341{ 3303{
3342 tnode_t *ptn; 
3343 3304
3344 if (!is_arithmetic(nt) || !is_arithmetic(ot)) 3305 if (!is_arithmetic(nt) || !is_arithmetic(ot))
3345 return; 3306 return;
3346 3307
3347 /* 3308 /*
3348 * If the type of the formal parameter is char/short, a warning 3309 * If the type of the formal parameter is char/short, a warning
3349 * would be useless, because functions declared the old style 3310 * would be useless, because functions declared the old style
3350 * can't expect char/short arguments. 3311 * can't expect char/short arguments.
3351 */ 3312 */
3352 if (nt == CHAR || nt == SCHAR || nt == UCHAR || 3313 if (nt == CHAR || nt == SCHAR || nt == UCHAR ||
3353 nt == SHORT || nt == USHORT) 3314 nt == SHORT || nt == USHORT)
3354 return; 3315 return;
3355 3316
3356 /* apply the default promotion */ 3317 /* apply the default promotion */
3357 ptn = promote(NOOP, true, tn); 3318 tnode_t *ptn = promote(NOOP, true, tn);
3358 ot = ptn->tn_type->t_tspec; 3319 ot = ptn->tn_type->t_tspec;
3359 3320
3360 if (should_warn_about_prototype_conversion(nt, ot, ptn)) { 3321 if (should_warn_about_prototype_conversion(nt, ot, ptn)) {
3361 /* argument #%d is converted from '%s' to '%s' ... */ 3322 /* argument #%d is converted from '%s' to '%s' ... */
3362 warning(259, arg, type_name(tn->tn_type), type_name(tp)); 3323 warning(259, arg, type_name(tn->tn_type), type_name(tp));
3363 } 3324 }
3364} 3325}
3365 3326
3366/* 3327/*
3367 * When converting a large integer type to a small integer type, in some 3328 * When converting a large integer type to a small integer type, in some
3368 * cases the value of the actual expression is further restricted than the 3329 * cases the value of the actual expression is further restricted than the
3369 * type bounds, such as in (expr & 0xFF) or (expr % 100) or (expr >> 24). 3330 * type bounds, such as in (expr & 0xFF) or (expr % 100) or (expr >> 24).
3370 */ 3331 */
@@ -3515,49 +3476,47 @@ should_warn_about_pointer_cast(const typ @@ -3515,49 +3476,47 @@ should_warn_about_pointer_cast(const typ
3515 if (nmem == NULL && omem == NULL) 3476 if (nmem == NULL && omem == NULL)
3516 return false; 3477 return false;
3517 } 3478 }
3518 3479
3519 if (is_struct_or_union(nst) && nstp->t_str != ostp->t_str) 3480 if (is_struct_or_union(nst) && nstp->t_str != ostp->t_str)
3520 return true; 3481 return true;
3521 3482
3522 return portable_size_in_bits(nst) != portable_size_in_bits(ost); 3483 return portable_size_in_bits(nst) != portable_size_in_bits(ost);
3523} 3484}
3524 3485
3525static void 3486static void
3526convert_pointer_from_pointer(type_t *ntp, tnode_t *tn) 3487convert_pointer_from_pointer(type_t *ntp, tnode_t *tn)
3527{ 3488{
3528 const type_t *nstp, *otp, *ostp; 3489 const type_t *nstp = ntp->t_subt;
3529 tspec_t nst, ost; 3490 const type_t *otp = tn->tn_type;
3530 const char *nts, *ots; 3491 const type_t *ostp = otp->t_subt;
3531 3492 tspec_t nst = nstp->t_tspec;
3532 nstp = ntp->t_subt; 3493 tspec_t ost = ostp->t_tspec;
3533 otp = tn->tn_type; 
3534 ostp = otp->t_subt; 
3535 nst = nstp->t_tspec; 
3536 ost = ostp->t_tspec; 
3537 3494
3538 if (nst == VOID || ost == VOID) { 3495 if (nst == VOID || ost == VOID) {
3539 /* TODO: C99 behaves like C90 here. */ 3496 /* TODO: C99 behaves like C90 here. */
3540 if ((!allow_trad && !allow_c99) && (nst == FUNC || ost == FUNC)) { 3497 if ((!allow_trad && !allow_c99) && (nst == FUNC || ost == FUNC)) {
 3498 const char *nts, *ots;
3541 /* null pointers are already handled in convert() */ 3499 /* null pointers are already handled in convert() */
3542 *(nst == FUNC ? &nts : &ots) = "function pointer"; 3500 *(nst == FUNC ? &nts : &ots) = "function pointer";
3543 *(nst == VOID ? &nts : &ots) = "'void *'"; 3501 *(nst == VOID ? &nts : &ots) = "'void *'";
3544 /* ANSI C forbids conversion of %s to %s */ 3502 /* ANSI C forbids conversion of %s to %s */
3545 warning(303, ots, nts); 3503 warning(303, ots, nts);
3546 } 3504 }
3547 return; 3505 return;
3548 } else if (nst == FUNC && ost == FUNC) { 3506 }
 3507 if (nst == FUNC && ost == FUNC)
3549 return; 3508 return;
3550 } else if (nst == FUNC || ost == FUNC) { 3509 if (nst == FUNC || ost == FUNC) {
3551 /* converting '%s' to '%s' is questionable */ 3510 /* converting '%s' to '%s' is questionable */
3552 warning(229, type_name(otp), type_name(ntp)); 3511 warning(229, type_name(otp), type_name(ntp));
3553 return; 3512 return;
3554 } 3513 }
3555 3514
3556 if (hflag && alignment_in_bits(nstp) > alignment_in_bits(ostp) && 3515 if (hflag && alignment_in_bits(nstp) > alignment_in_bits(ostp) &&
3557 ost != CHAR && ost != UCHAR && 3516 ost != CHAR && ost != UCHAR &&
3558 !is_incomplete(ostp)) { 3517 !is_incomplete(ostp)) {
3559 /* converting '%s' to '%s' increases alignment ... */ 3518 /* converting '%s' to '%s' increases alignment ... */
3560 warning(135, type_name(otp), type_name(ntp), 3519 warning(135, type_name(otp), type_name(ntp),
3561 alignment_in_bits(ostp) / CHAR_SIZE, 3520 alignment_in_bits(ostp) / CHAR_SIZE,
3562 alignment_in_bits(nstp) / CHAR_SIZE); 3521 alignment_in_bits(nstp) / CHAR_SIZE);
3563 } 3522 }
@@ -3574,31 +3533,28 @@ convert_pointer_from_pointer(type_t *ntp @@ -3574,31 +3533,28 @@ convert_pointer_from_pointer(type_t *ntp
3574 * 3533 *
3575 * Possible values for 'op': 3534 * Possible values for 'op':
3576 * CVT a cast-expression 3535 * CVT a cast-expression
3577 * binary integer promotion for one of the operands, or a usual 3536 * binary integer promotion for one of the operands, or a usual
3578 * arithmetic conversion 3537 * arithmetic conversion
3579 * binary plain or compound assignments to bit-fields 3538 * binary plain or compound assignments to bit-fields
3580 * FARG 'arg' is the number of the argument (used for warnings) 3539 * FARG 'arg' is the number of the argument (used for warnings)
3581 * NOOP several other implicit conversions 3540 * NOOP several other implicit conversions
3582 * ... 3541 * ...
3583 */ 3542 */
3584tnode_t * 3543tnode_t *
3585convert(op_t op, int arg, type_t *tp, tnode_t *tn) 3544convert(op_t op, int arg, type_t *tp, tnode_t *tn)
3586{ 3545{
3587 tnode_t *ntn; 3546 tspec_t nt = tp->t_tspec;
3588 tspec_t nt, ot; 3547 tspec_t ot = tn->tn_type->t_tspec;
3589 
3590 nt = tp->t_tspec; 
3591 ot = tn->tn_type->t_tspec; 
3592 3548
3593 if (allow_trad && allow_c90 && op == FARG) 3549 if (allow_trad && allow_c90 && op == FARG)
3594 check_prototype_conversion(arg, nt, ot, tp, tn); 3550 check_prototype_conversion(arg, nt, ot, tp, tn);
3595 3551
3596 if (nt == BOOL) { 3552 if (nt == BOOL) {
3597 /* No further checks. */ 3553 /* No further checks. */
3598 3554
3599 } else if (is_integer(nt)) { 3555 } else if (is_integer(nt)) {
3600 if (ot == BOOL) { 3556 if (ot == BOOL) {
3601 /* No further checks. */ 3557 /* No further checks. */
3602 } else if (is_integer(ot)) { 3558 } else if (is_integer(ot)) {
3603 convert_integer_from_integer(op, arg, nt, ot, tp, tn); 3559 convert_integer_from_integer(op, arg, nt, ot, tp, tn);
3604 } else if (is_floating(ot)) { 3560 } else if (is_floating(ot)) {
@@ -3608,49 +3564,49 @@ convert(op_t op, int arg, type_t *tp, tn @@ -3608,49 +3564,49 @@ convert(op_t op, int arg, type_t *tp, tn
3608 } 3564 }
3609 3565
3610 } else if (is_floating(nt)) { 3566 } else if (is_floating(nt)) {
3611 /* No further checks. */ 3567 /* No further checks. */
3612 3568
3613 } else if (nt == PTR) { 3569 } else if (nt == PTR) {
3614 if (is_null_pointer(tn)) { 3570 if (is_null_pointer(tn)) {
3615 /* a null pointer may be assigned to any pointer. */ 3571 /* a null pointer may be assigned to any pointer. */
3616 } else if (ot == PTR && op == CVT) { 3572 } else if (ot == PTR && op == CVT) {
3617 convert_pointer_from_pointer(tp, tn); 3573 convert_pointer_from_pointer(tp, tn);
3618 } 3574 }
3619 } 3575 }
3620 3576
3621 ntn = expr_alloc_tnode(); 3577 tnode_t *ntn = expr_alloc_tnode();
3622 ntn->tn_op = CVT; 3578 ntn->tn_op = CVT;
3623 ntn->tn_type = tp; 3579 ntn->tn_type = tp;
3624 ntn->tn_cast = op == CVT; 3580 ntn->tn_cast = op == CVT;
3625 ntn->tn_sys |= tn->tn_sys; 3581 ntn->tn_sys |= tn->tn_sys;
3626 ntn->tn_right = NULL; 3582 ntn->tn_right = NULL;
3627 if (tn->tn_op != CON || nt == VOID) { 3583 if (tn->tn_op != CON || nt == VOID) {
3628 ntn->tn_left = tn; 3584 ntn->tn_left = tn;
3629 } else { 3585 } else {
3630 ntn->tn_op = CON; 3586 ntn->tn_op = CON;
3631 ntn->tn_val = expr_zero_alloc(sizeof(*ntn->tn_val)); 3587 ntn->tn_val = expr_zero_alloc(sizeof(*ntn->tn_val));
3632 convert_constant(op, arg, ntn->tn_type, ntn->tn_val, 3588 convert_constant(op, arg, ntn->tn_type, ntn->tn_val,
3633 tn->tn_val); 3589 tn->tn_val);
3634 } 3590 }
3635 3591
3636 return ntn; 3592 return ntn;
3637} 3593}
3638 3594
3639static void 3595static void
3640convert_constant_floating(op_t op, int arg, tspec_t ot, const type_t *tp, 3596convert_constant_floating(op_t op, int arg, tspec_t ot, const type_t *tp,
3641 tspec_t nt, val_t *v, val_t *nv) 3597 tspec_t nt, val_t *v, val_t *nv)
3642{ 3598{
3643 ldbl_t max = 0.0, min = 0.0; 3599 ldbl_t max = 0.0, min = 0.0;
3644 3600
3645 switch (nt) { 3601 switch (nt) {
3646 case CHAR: 3602 case CHAR:
3647 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break; 3603 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break;
3648 case UCHAR: 3604 case UCHAR:
3649 max = TARG_UCHAR_MAX; min = 0; break; 3605 max = TARG_UCHAR_MAX; min = 0; break;
3650 case SCHAR: 3606 case SCHAR:
3651 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break; 3607 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break;
3652 case SHORT: 3608 case SHORT:
3653 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break; 3609 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break;
3654 case USHORT: 3610 case USHORT:
3655 max = TARG_USHRT_MAX; min = 0; break; 3611 max = TARG_USHRT_MAX; min = 0; break;
3656 case ENUM: 3612 case ENUM:
@@ -3774,37 +3730,33 @@ convert_constant_check_range_signed(op_t @@ -3774,37 +3730,33 @@ convert_constant_check_range_signed(op_t
3774 warning(221); 3730 warning(221);
3775 } else if (op == FARG) { 3731 } else if (op == FARG) {
3776 /* conversion of negative constant to unsigned type, ... */ 3732 /* conversion of negative constant to unsigned type, ... */
3777 warning(296, arg); 3733 warning(296, arg);
3778 } else if (modtab[op].m_comparison) { 3734 } else if (modtab[op].m_comparison) {
3779 /* handled by check_integer_comparison() */ 3735 /* handled by check_integer_comparison() */
3780 } else { 3736 } else {
3781 /* conversion of negative constant to unsigned type */ 3737 /* conversion of negative constant to unsigned type */
3782 warning(222); 3738 warning(222);
3783 } 3739 }
3784} 3740}
3785 3741
3786/* 3742/*
3787 * Loss of significant bit(s). All truncated bits 3743 * Loss of significant bit(s). All truncated bits of unsigned types or all
3788 * of unsigned types or all truncated bits plus the 3744 * truncated bits plus the msb of the target for signed types are considered
3789 * msb of the target for signed types are considered 3745 * to be significant bits. Loss of significant bits means that at least one
3790 * to be significant bits. Loss of significant bits 3746 * of the bits was set in an unsigned type or that at least one but not all
3791 * means that at least one of the bits was set in an 3747 * of the bits was set in a signed type. Loss of significant bits means that
3792 * unsigned type or that at least one but not all of 3748 * it is not possible, also not with necessary casts, to convert back to the
3793 * the bits was set in a signed type. 3749 * original type. A example for a necessary cast is:
3794 * Loss of significant bits means that it is not 
3795 * possible, also not with necessary casts, to convert 
3796 * back to the original type. A example for a 
3797 * necessary cast is: 
3798 * char c; int i; c = 128; 3750 * char c; int i; c = 128;
3799 * i = c; ** yields -128 ** 3751 * i = c; ** yields -128 **
3800 * i = (unsigned char)c; ** yields 128 ** 3752 * i = (unsigned char)c; ** yields 128 **
3801 */ 3753 */
3802static void 3754static void
3803convert_constant_check_range_truncated(op_t op, int arg, const type_t *tp, 3755convert_constant_check_range_truncated(op_t op, int arg, const type_t *tp,
3804 tspec_t ot) 3756 tspec_t ot)
3805{ 3757{
3806 if (op == ASSIGN && tp->t_bitfield) { 3758 if (op == ASSIGN && tp->t_bitfield) {
3807 /* precision lost in bit-field assignment */ 3759 /* precision lost in bit-field assignment */
3808 warning(166); 3760 warning(166);
3809 } else if (op == ASSIGN) { 3761 } else if (op == ASSIGN) {
3810 /* constant truncated by assignment */ 3762 /* constant truncated by assignment */
@@ -3834,32 +3786,30 @@ convert_constant_check_range_loss(op_t o @@ -3834,32 +3786,30 @@ convert_constant_check_range_loss(op_t o
3834 tspec_t ot) 3786 tspec_t ot)
3835{ 3787{
3836 if (op == ASSIGN && tp->t_bitfield) { 3788 if (op == ASSIGN && tp->t_bitfield) {
3837 /* precision lost in bit-field assignment */ 3789 /* precision lost in bit-field assignment */
3838 warning(166); 3790 warning(166);
3839 } else if (op == INIT && tp->t_bitfield) { 3791 } else if (op == INIT && tp->t_bitfield) {
3840 /* bit-field initializer out of range */ 3792 /* bit-field initializer out of range */
3841 warning(11); 3793 warning(11);
3842 } else if (op == CASE) { 3794 } else if (op == CASE) {
3843 /* case label affected by conversion */ 3795 /* case label affected by conversion */
3844 warning(196); 3796 warning(196);
3845 } else if (op == FARG) { 3797 } else if (op == FARG) {
3846 /* conversion of '%s' to '%s' is out of range, arg #%d */ 3798 /* conversion of '%s' to '%s' is out of range, arg #%d */
3847 warning(295, 3799 warning(295, type_name(gettyp(ot)), type_name(tp), arg);
3848 type_name(gettyp(ot)), type_name(tp), arg); 
3849 } else { 3800 } else {
3850 /* conversion of '%s' to '%s' is out of range */ 3801 /* conversion of '%s' to '%s' is out of range */
3851 warning(119, 3802 warning(119, type_name(gettyp(ot)), type_name(tp));
3852 type_name(gettyp(ot)), type_name(tp)); 
3853 } 3803 }
3854} 3804}
3855 3805
3856static void 3806static void
3857convert_constant_check_range(tspec_t ot, const type_t *tp, tspec_t nt, 3807convert_constant_check_range(tspec_t ot, const type_t *tp, tspec_t nt,
3858 op_t op, int arg, const val_t *v, val_t *nv) 3808 op_t op, int arg, const val_t *v, val_t *nv)
3859{ 3809{
3860 unsigned int obitsz, nbitsz; 3810 unsigned int obitsz, nbitsz;
3861 uint64_t xmask, xmsk1; 3811 uint64_t xmask, xmsk1;
3862 3812
3863 obitsz = size_in_bits(ot); 3813 obitsz = size_in_bits(ot);
3864 nbitsz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt); 3814 nbitsz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt);
3865 xmask = value_bits(nbitsz) ^ value_bits(obitsz); 3815 xmask = value_bits(nbitsz) ^ value_bits(obitsz);
@@ -3889,63 +3839,59 @@ convert_constant_check_range(tspec_t ot, @@ -3889,63 +3839,59 @@ convert_constant_check_range(tspec_t ot,
3889 3839
3890/* 3840/*
3891 * Converts a typed constant to a constant of another type. 3841 * Converts a typed constant to a constant of another type.
3892 * 3842 *
3893 * op operator which requires conversion 3843 * op operator which requires conversion
3894 * arg if op is FARG, # of argument 3844 * arg if op is FARG, # of argument
3895 * tp type in which to convert the constant 3845 * tp type in which to convert the constant
3896 * nv new constant 3846 * nv new constant
3897 * v old constant 3847 * v old constant
3898 */ 3848 */
3899void 3849void
3900convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v) 3850convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v)
3901{ 3851{
3902 tspec_t ot, nt; 
3903 unsigned int sz; 
3904 bool range_check; 
3905 
3906 /* 3852 /*
3907 * TODO: make 'v' const; the name of this function does not suggest 3853 * TODO: make 'v' const; the name of this function does not suggest
3908 * that it modifies 'v'. 3854 * that it modifies 'v'.
3909 */ 3855 */
3910 ot = v->v_tspec; 3856 tspec_t ot = v->v_tspec;
3911 nt = nv->v_tspec = tp->t_tspec; 3857 tspec_t nt = nv->v_tspec = tp->t_tspec;
3912 range_check = false; 3858 bool range_check = false;
3913 3859
3914 if (nt == BOOL) { /* C99 6.3.1.2 */ 3860 if (nt == BOOL) { /* C99 6.3.1.2 */
3915 nv->v_unsigned_since_c90 = false; 3861 nv->v_unsigned_since_c90 = false;
3916 nv->v_quad = is_nonzero_val(v) ? 1 : 0; 3862 nv->v_quad = is_nonzero_val(v) ? 1 : 0;
3917 return; 3863 return;
3918 } 3864 }
3919 3865
3920 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { 3866 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
3921 convert_constant_floating(op, arg, ot, tp, nt, v, nv); 3867 convert_constant_floating(op, arg, ot, tp, nt, v, nv);
3922 } else if (!convert_constant_to_floating(nt, nv, ot, v)) { 3868 } else if (!convert_constant_to_floating(nt, nv, ot, v)) {
3923 range_check = true; /* Check for lost precision. */ 3869 range_check = true; /* Check for lost precision. */
3924 nv->v_quad = v->v_quad; 3870 nv->v_quad = v->v_quad;
3925 } 3871 }
3926 3872
3927 if (allow_trad && allow_c90 && v->v_unsigned_since_c90 && 3873 if (allow_trad && allow_c90 && v->v_unsigned_since_c90 &&
3928 (is_floating(nt) || ( 3874 (is_floating(nt) || (
3929 (is_integer(nt) && !is_uinteger(nt) && 3875 (is_integer(nt) && !is_uinteger(nt) &&
3930 portable_size_in_bits(nt) > portable_size_in_bits(ot))))) { 3876 portable_size_in_bits(nt) > portable_size_in_bits(ot))))) {
3931 /* ANSI C treats constant as unsigned */ 3877 /* ANSI C treats constant as unsigned */
3932 warning(157); 3878 warning(157);
3933 v->v_unsigned_since_c90 = false; 3879 v->v_unsigned_since_c90 = false;
3934 } 3880 }
3935 3881
3936 if (is_integer(nt)) { 3882 if (is_integer(nt)) {
3937 sz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt); 3883 nv->v_quad = convert_integer(nv->v_quad, nt,
3938 nv->v_quad = convert_integer(nv->v_quad, nt, sz); 3884 tp->t_bitfield ? tp->t_flen : size_in_bits(nt));
3939 } 3885 }
3940 3886
3941 if (range_check && op != CVT) 3887 if (range_check && op != CVT)
3942 convert_constant_check_range(ot, tp, nt, op, arg, v, nv); 3888 convert_constant_check_range(ot, tp, nt, op, arg, v, nv);
3943} 3889}
3944 3890
3945/* 3891/*
3946 * Create a constant node for sizeof. 3892 * Create a constant node for sizeof.
3947 */ 3893 */
3948tnode_t * 3894tnode_t *
3949build_sizeof(const type_t *tp) 3895build_sizeof(const type_t *tp)
3950{ 3896{
3951 unsigned int size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; 3897 unsigned int size_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
@@ -3969,31 +3915,30 @@ build_offsetof(const type_t *tp, const s @@ -3969,31 +3915,30 @@ build_offsetof(const type_t *tp, const s
3969 /* unacceptable operand of '%s' */ 3915 /* unacceptable operand of '%s' */
3970 error(111, "offsetof"); 3916 error(111, "offsetof");
3971 3917
3972 /* FIXME: Don't wrongly use the size of the whole type, use sym. */ 3918 /* FIXME: Don't wrongly use the size of the whole type, use sym. */
3973 offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; 3919 offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE;
3974 tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes); 3920 tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes);
3975 tn->tn_system_dependent = true; 3921 tn->tn_system_dependent = true;
3976 return tn; 3922 return tn;
3977} 3923}
3978 3924
3979unsigned int 3925unsigned int
3980type_size_in_bits(const type_t *tp) 3926type_size_in_bits(const type_t *tp)
3981{ 3927{
3982 unsigned int elem, elsz; 3928 unsigned int elsz;
3983 bool flex; 
3984 3929
3985 elem = 1; 3930 unsigned int elem = 1;
3986 flex = false; 3931 bool flex = false;
3987 lint_assert(tp != NULL); 3932 lint_assert(tp != NULL);
3988 while (tp->t_tspec == ARRAY) { 3933 while (tp->t_tspec == ARRAY) {
3989 flex = true; /* allow c99 flex arrays [] [0] */ 3934 flex = true; /* allow c99 flex arrays [] [0] */
3990 elem *= tp->t_dim; 3935 elem *= tp->t_dim;
3991 tp = tp->t_subt; 3936 tp = tp->t_subt;
3992 } 3937 }
3993 if (elem == 0) { 3938 if (elem == 0) {
3994 if (!flex) { 3939 if (!flex) {
3995 /* cannot take size/alignment of incomplete type */ 3940 /* cannot take size/alignment of incomplete type */
3996 error(143); 3941 error(143);
3997 elem = 1; 3942 elem = 1;
3998 } 3943 }
3999 } 3944 }
@@ -4195,33 +4140,31 @@ build_function_argument(tnode_t *args, t @@ -4195,33 +4140,31 @@ build_function_argument(tnode_t *args, t
4195 4140
4196/* 4141/*
4197 * Compare the type of an argument with the corresponding type of a 4142 * Compare the type of an argument with the corresponding type of a
4198 * prototype parameter. If it is a valid combination, but both types 4143 * prototype parameter. If it is a valid combination, but both types
4199 * are not the same, insert a conversion to convert the argument into 4144 * are not the same, insert a conversion to convert the argument into
4200 * the type of the parameter. 4145 * the type of the parameter.
4201 */ 4146 */
4202static tnode_t * 4147static tnode_t *
4203check_prototype_argument( 4148check_prototype_argument(
4204 int n, /* pos of arg */ 4149 int n, /* pos of arg */
4205 type_t *tp, /* expected type (from prototype) */ 4150 type_t *tp, /* expected type (from prototype) */
4206 tnode_t *tn) /* argument */ 4151 tnode_t *tn) /* argument */
4207{ 4152{
4208 tnode_t *ln; 4153 tnode_t *ln = xcalloc(1, sizeof(*ln));
4209 bool dowarn; 
4210 
4211 ln = xcalloc(1, sizeof(*ln)); 
4212 ln->tn_type = expr_unqualified_type(tp); 4154 ln->tn_type = expr_unqualified_type(tp);
4213 ln->tn_lvalue = true; 4155 ln->tn_lvalue = true;
4214 if (typeok(FARG, n, ln, tn)) { 4156 if (typeok(FARG, n, ln, tn)) {
 4157 bool dowarn;
4215 if (!types_compatible(tp, tn->tn_type, 4158 if (!types_compatible(tp, tn->tn_type,
4216 true, false, (dowarn = false, &dowarn)) || dowarn) 4159 true, false, (dowarn = false, &dowarn)) || dowarn)
4217 tn = convert(FARG, n, tp, tn); 4160 tn = convert(FARG, n, tp, tn);
4218 } 4161 }
4219 free(ln); 4162 free(ln);
4220 return tn; 4163 return tn;
4221} 4164}
4222 4165
4223/* 4166/*
4224 * Check types of all function arguments and insert conversions, 4167 * Check types of all function arguments and insert conversions,
4225 * if necessary. 4168 * if necessary.
4226 */ 4169 */
4227static tnode_t * 4170static tnode_t *
@@ -4332,34 +4275,33 @@ build_function_call(tnode_t *func, bool  @@ -4332,34 +4275,33 @@ build_function_call(tnode_t *func, bool
4332 ntn = new_tnode(fcop, sys, func->tn_type->t_subt->t_subt, func, args); 4275 ntn = new_tnode(fcop, sys, func->tn_type->t_subt->t_subt, func, args);
4333 4276
4334 return ntn; 4277 return ntn;
4335} 4278}
4336 4279
4337/* 4280/*
4338 * Return the value of an integral constant expression. 4281 * Return the value of an integral constant expression.
4339 * If the expression is not constant or its type is not an integer 4282 * If the expression is not constant or its type is not an integer
4340 * type, an error message is printed. 4283 * type, an error message is printed.
4341 */ 4284 */
4342val_t * 4285val_t *
4343constant(tnode_t *tn, bool required) 4286constant(tnode_t *tn, bool required)
4344{ 4287{
4345 val_t *v; 
4346 4288
4347 if (tn != NULL) 4289 if (tn != NULL)
4348 tn = cconv(tn); 4290 tn = cconv(tn);
4349 if (tn != NULL) 4291 if (tn != NULL)
4350 tn = promote(NOOP, false, tn); 4292 tn = promote(NOOP, false, tn);
4351 4293
4352 v = xcalloc(1, sizeof(*v)); 4294 val_t *v = xcalloc(1, sizeof(*v));
4353 4295
4354 if (tn == NULL) { 4296 if (tn == NULL) {
4355 lint_assert(nerr != 0); 4297 lint_assert(nerr != 0);
4356 debug_step("constant node is null; returning 1 instead"); 4298 debug_step("constant node is null; returning 1 instead");
4357 v->v_tspec = INT; 4299 v->v_tspec = INT;
4358 v->v_quad = 1; 4300 v->v_quad = 1;
4359 return v; 4301 return v;
4360 } 4302 }
4361 4303
4362 v->v_tspec = tn->tn_type->t_tspec; 4304 v->v_tspec = tn->tn_type->t_tspec;
4363 4305
4364 if (tn->tn_op == CON) { 4306 if (tn->tn_op == CON) {
4365 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec); 4307 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec);
@@ -4442,66 +4384,62 @@ expr(tnode_t *tn, bool vctx, bool cond,  @@ -4442,66 +4384,62 @@ expr(tnode_t *tn, bool vctx, bool cond,
4442 if (dofreeblk) 4384 if (dofreeblk)
4443 expr_free_all(); 4385 expr_free_all();
4444} 4386}
4445 4387
4446/* 4388/*
4447 * Checks the range of array indices, if possible. 4389 * Checks the range of array indices, if possible.
4448 * amper is set if only the address of the element is used. This 4390 * amper is set if only the address of the element is used. This
4449 * means that the index is allowed to refer to the first element 4391 * means that the index is allowed to refer to the first element
4450 * after the array. 4392 * after the array.
4451 */ 4393 */
4452static void 4394static void
4453check_array_index(tnode_t *tn, bool amper) 4395check_array_index(tnode_t *tn, bool amper)
4454{ 4396{
4455 int dim; 4397 const tnode_t *ln = tn->tn_left;
4456 tnode_t *ln, *rn; 4398 const tnode_t *rn = tn->tn_right;
4457 int elsz; 
4458 int64_t con; 
4459 
4460 ln = tn->tn_left; 
4461 rn = tn->tn_right; 
4462 4399
4463 /* We can only check constant indices. */ 4400 /* We can only check constant indices. */
4464 if (rn->tn_op != CON) 4401 if (rn->tn_op != CON)
4465 return; 4402 return;
4466 4403
4467 /* Return if the left node does not stem from an array. */ 4404 /* Return if the left node does not stem from an array. */
4468 if (ln->tn_op != ADDR) 4405 if (ln->tn_op != ADDR)
4469 return; 4406 return;
4470 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 4407 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
4471 return; 4408 return;
4472 if (ln->tn_left->tn_type->t_tspec != ARRAY) 4409 if (ln->tn_left->tn_type->t_tspec != ARRAY)
4473 return; 4410 return;
4474 4411
4475 /* 4412 /*
4476 * For incomplete array types, we can print a warning only if 4413 * For incomplete array types, we can print a warning only if
4477 * the index is negative. 4414 * the index is negative.
4478 */ 4415 */
4479 if (is_incomplete(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 4416 if (is_incomplete(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
4480 return; 4417 return;
4481 4418
4482 /* Get the size of one array element */ 4419 /* Get the size of one array element */
4483 if ((elsz = length_in_bits(ln->tn_type->t_subt, NULL)) == 0) 4420 int elsz = length_in_bits(ln->tn_type->t_subt, NULL);
 4421 if (elsz == 0)
4484 return; 4422 return;
4485 elsz /= CHAR_SIZE; 4423 elsz /= CHAR_SIZE;
4486 4424
4487 /* Change the unit of the index from bytes to element size. */ 4425 /* Change the unit of the index from bytes to element size. */
4488 if (is_uinteger(rn->tn_type->t_tspec)) { 4426 int64_t con;
 4427 if (is_uinteger(rn->tn_type->t_tspec))
4489 con = (uint64_t)rn->tn_val->v_quad / elsz; 4428 con = (uint64_t)rn->tn_val->v_quad / elsz;
4490 } else { 4429 else
4491 con = rn->tn_val->v_quad / elsz; 4430 con = rn->tn_val->v_quad / elsz;
4492 } 
4493 4431
4494 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 4432 int dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
4495 4433
4496 if (!is_uinteger(rn->tn_type->t_tspec) && con < 0) { 4434 if (!is_uinteger(rn->tn_type->t_tspec) && con < 0) {
4497 /* array subscript cannot be negative: %ld */ 4435 /* array subscript cannot be negative: %ld */
4498 warning(167, (long)con); 4436 warning(167, (long)con);
4499 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { 4437 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) {
4500 /* array subscript cannot be > %d: %ld */ 4438 /* array subscript cannot be > %d: %ld */
4501 warning(168, dim - 1, (long)con); 4439 warning(168, dim - 1, (long)con);
4502 } 4440 }
4503} 4441}
4504 4442
4505static void 4443static void
4506check_expr_addr(const tnode_t *ln, bool szof, bool fcall) 4444check_expr_addr(const tnode_t *ln, bool szof, bool fcall)
4507{ 4445{
@@ -4517,32 +4455,31 @@ check_expr_addr(const tnode_t *ln, bool  @@ -4517,32 +4455,31 @@ check_expr_addr(const tnode_t *ln, bool
4517} 4455}
4518 4456
4519static void 4457static void
4520check_expr_load(const tnode_t *ln) 4458check_expr_load(const tnode_t *ln)
4521{ 4459{
4522 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) 4460 if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
4523 /* check the range of array indices */ 4461 /* check the range of array indices */
4524 check_array_index(ln->tn_left, false); 4462 check_array_index(ln->tn_left, false);
4525} 4463}
4526 4464
4527static void 4465static void
4528check_expr_side_effect(const tnode_t *ln, bool szof) 4466check_expr_side_effect(const tnode_t *ln, bool szof)
4529{ 4467{
4530 scl_t sc; 
4531 dinfo_t *di; 4468 dinfo_t *di;
4532 4469
4533 /* XXX: Taking warn_about_unreachable into account here feels wrong. */ 4470 /* XXX: Taking warn_about_unreachable into account here feels wrong. */
4534 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) { 4471 if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
4535 sc = ln->tn_sym->s_scl; 4472 scl_t sc = ln->tn_sym->s_scl;
4536 /* 4473 /*
4537 * Look if there was a asm statement in one of the 4474 * Look if there was a asm statement in one of the
4538 * compound statements we are in. If not, we don't 4475 * compound statements we are in. If not, we don't
4539 * print a warning. 4476 * print a warning.
4540 */ 4477 */
4541 for (di = dcs; di != NULL; di = di->d_enclosing) { 4478 for (di = dcs; di != NULL; di = di->d_enclosing) {
4542 if (di->d_asm) 4479 if (di->d_asm)
4543 break; 4480 break;
4544 } 4481 }
4545 if (sc != EXTERN && sc != STATIC && 4482 if (sc != EXTERN && sc != STATIC &&
4546 !ln->tn_sym->s_set && !szof && di == NULL) { 4483 !ln->tn_sym->s_set && !szof && di == NULL) {
4547 /* '%s' may be used before set */ 4484 /* '%s' may be used before set */
4548 warning(158, ln->tn_sym->s_name); 4485 warning(158, ln->tn_sym->s_name);