| @@ -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 | |
53 | typedef struct integer_constraints { | | 53 | typedef 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 | |
1503 | static ldbl_t | | 1503 | static ldbl_t |
1504 | floating_error_value(tspec_t t, ldbl_t lv) | | 1504 | floating_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 | */ |
1520 | static tnode_t * | | 1521 | static tnode_t * |
1521 | fold_float(tnode_t *tn) | | 1522 | fold_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 | */ |
1977 | tnode_t * | | 1975 | tnode_t * |
1978 | cconv(tnode_t *tn) | | 1976 | cconv(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 | |
2015 | const tnode_t * | | 2011 | const tnode_t * |
2016 | before_conversion(const tnode_t *tn) | | 2012 | before_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) |
2073 | static bool | | 2069 | static bool |
2074 | typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) | | 2070 | typeok_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 | |
2094 | static bool | | 2090 | static bool |
2095 | typeok_address(const mod_t *mp, | | 2091 | typeok_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 | |
2128 | static bool | | 2124 | static bool |
2129 | typeok_indir(const type_t *tp, tspec_t t) | | 2125 | typeok_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 | */ | | | |
2144 | static void | | 2136 | static void |
2145 | warn_incompatible_types(op_t op, | | 2137 | warn_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 | |
2182 | static bool | | 2172 | static bool |
2183 | typeok_minus(op_t op, | | 2173 | typeok_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 | |
2203 | static void | | 2191 | static void |
2204 | typeok_shr(const mod_t *mp, | | 2192 | typeok_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 | */ |
2312 | static void | | 2297 | static void |
2313 | warn_incompatible_pointers(const mod_t *mp, | | 2298 | warn_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 | |
2344 | static void | | 2327 | static void |
2345 | check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn) | | 2328 | check_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 | |
2380 | static bool | | 2360 | static bool |
2381 | typeok_compare(op_t op, | | 2361 | typeok_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 | |
2407 | static bool | | 2385 | static bool |
2408 | typeok_quest(tspec_t lt, const tnode_t *rn) | | 2386 | typeok_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 | */ |
2494 | static bool | | 2472 | static bool |
2495 | has_constant_member(const type_t *tp) | | 2473 | has_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 | |
2512 | static bool | | 2489 | static bool |
2513 | typeok_assign(op_t op, const tnode_t *ln, const type_t *ltp, tspec_t lt) | | 2490 | typeok_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 | |
2570 | static void | | 2547 | static void |
2571 | check_assign_void_pointer(op_t op, int arg, | | 2548 | check_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 ? <s : &rts) = "function pointer"; | | 2563 | *(lst == FUNC ? <s : &rts) = "function pointer"; |
2587 | *(lst == VOID ? <s : &rts) = "'void *'"; | | 2564 | *(lst == VOID ? <s : &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 |
2620 | is_unconst_function(const char *name) | | 2597 | is_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 | |
2630 | static bool | | 2607 | static bool |
2631 | is_const_char_pointer(const tnode_t *tn) | | 2608 | is_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 | |
2657 | static bool | | 2632 | static bool |
2658 | is_first_arg_const_char_pointer(const tnode_t *tn) | | 2633 | is_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 | |
2671 | static bool | | 2644 | static bool |
2672 | is_const_pointer(const tnode_t *tn) | | 2645 | is_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 | |
2680 | static bool | | 2651 | static bool |
2681 | is_second_arg_const_pointer(const tnode_t *tn) | | 2652 | is_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 | |
2694 | static void | | 2663 | static void |
2695 | check_unconst_function(const type_t *lstp, const tnode_t *rn) | | 2664 | check_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) |
2930 | static bool | | 2899 | static bool |
2931 | is_int_constant_zero(const tnode_t *tn) | | 2900 | is_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 | |
2939 | static void | | 2908 | static void |
2940 | check_null_effect(const tnode_t *tn) | | 2909 | check_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 | */ |
2962 | static bool | | 2927 | static bool |
2963 | typeok_op(op_t op, const mod_t *mp, int arg, | | 2928 | typeok_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 | */ |
3075 | static void | | 3040 | static void |
3076 | check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) | | 3041 | check_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. */ |
3170 | bool | | 3133 | bool |
3171 | typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) | | 3134 | typeok(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 | */ |
3338 | static void | | 3300 | static void |
3339 | check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp, | | 3301 | check_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 | |
3525 | static void | | 3486 | static void |
3526 | convert_pointer_from_pointer(type_t *ntp, tnode_t *tn) | | 3487 | convert_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 | */ |
3584 | tnode_t * | | 3543 | tnode_t * |
3585 | convert(op_t op, int arg, type_t *tp, tnode_t *tn) | | 3544 | convert(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 | |
3639 | static void | | 3595 | static void |
3640 | convert_constant_floating(op_t op, int arg, tspec_t ot, const type_t *tp, | | 3596 | convert_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 | */ |
3802 | static void | | 3754 | static void |
3803 | convert_constant_check_range_truncated(op_t op, int arg, const type_t *tp, | | 3755 | convert_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 | |
3856 | static void | | 3806 | static void |
3857 | convert_constant_check_range(tspec_t ot, const type_t *tp, tspec_t nt, | | 3807 | convert_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 | */ |
3899 | void | | 3849 | void |
3900 | convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v) | | 3850 | convert_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 | */ |
3948 | tnode_t * | | 3894 | tnode_t * |
3949 | build_sizeof(const type_t *tp) | | 3895 | build_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 | |
3979 | unsigned int | | 3925 | unsigned int |
3980 | type_size_in_bits(const type_t *tp) | | 3926 | type_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 | */ |
4202 | static tnode_t * | | 4147 | static tnode_t * |
4203 | check_prototype_argument( | | 4148 | check_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 | */ |
4227 | static tnode_t * | | 4170 | static 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 | */ |
4342 | val_t * | | 4285 | val_t * |
4343 | constant(tnode_t *tn, bool required) | | 4286 | constant(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 | */ |
4452 | static void | | 4394 | static void |
4453 | check_array_index(tnode_t *tn, bool amper) | | 4395 | check_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 | |
4505 | static void | | 4443 | static void |
4506 | check_expr_addr(const tnode_t *ln, bool szof, bool fcall) | | 4444 | check_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 | |
4519 | static void | | 4457 | static void |
4520 | check_expr_load(const tnode_t *ln) | | 4458 | check_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 | |
4527 | static void | | 4465 | static void |
4528 | check_expr_side_effect(const tnode_t *ln, bool szof) | | 4466 | check_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); |