@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.508 2023/04/11 00:03:42 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.509 2023/04/11 19:02:19 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.508 2023/04/11 00:03:42 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.509 2023/04/11 19:02:19 rillig Exp $");
#endif
#include <float.h>
@@ -1503,15 +1503,16 @@
static ldbl_t
floating_error_value(tspec_t t, ldbl_t lv)
{
- if (t == FLOAT) {
+ if (t == FLOAT)
return lv < 0 ? -FLT_MAX : FLT_MAX;
- } else if (t == DOUBLE) {
+ if (t == DOUBLE)
return lv < 0 ? -DBL_MAX : DBL_MAX;
- } else {
- /* LINTED 248: floating-point constant out of range */
- ldbl_t max = LDBL_MAX;
- return lv < 0 ? -max : max;
- }
+
+ /* FIXME: Remove the '(double)' cast near 'isfinite'. */
+ /* FIXME: Inlining the variable 'max' produces a wrong warning. */
+ /* LINTED 248: floating-point constant out of range */
+ ldbl_t max = LDBL_MAX;
+ return lv < 0 ? -max : max;
}
/*
@@ -1885,13 +1886,10 @@
if (str != NULL) {
for (sym_t *sym = msym;
sym != NULL; sym = sym->s_symtab_next) {
- if (!is_member(sym))
- continue;
- if (sym->u.s_member.sm_sou_type != str)
- continue;
- if (strcmp(sym->s_name, msym->s_name) != 0)
- continue;
- return sym;
+ if (is_member(sym) &&
+ sym->u.s_member.sm_sou_type == str &&
+ strcmp(sym->s_name, msym->s_name) == 0)
+ return sym;
}
}
@@ -1977,8 +1975,6 @@
tnode_t *
cconv(tnode_t *tn)
{
- type_t *tp;
-
/*
* Array-lvalue (array of type T) is converted into rvalue
* (pointer to type T)
@@ -2003,7 +1999,7 @@
/* lvalue to rvalue */
if (tn->tn_lvalue) {
- tp = expr_dup_type(tn->tn_type);
+ type_t *tp = expr_dup_type(tn->tn_type);
/* C99 6.3.2.1p2 sentence 2 says to remove the qualifiers. */
tp->t_const = tp->t_volatile = false;
tn = new_tnode(LOAD, tn->tn_sys, tp, tn, NULL);
@@ -2083,11 +2079,11 @@
/* %soperand of '%s' must be lvalue */
error(114, "", op_name(op));
return false;
- } else if (tp->t_const) {
- if (allow_c90)
- /* %soperand of '%s' must be modifiable lvalue */
- warning(115, "", op_name(op));
}
+ if (tp->t_const && allow_c90) {
+ /* %soperand of '%s' must be modifiable lvalue */
+ warning(115, "", op_name(op));
+ }
return true;
}
@@ -2137,19 +2133,13 @@
return true;
}
-/*
- * Called if incompatible types were detected.
- * Prints a appropriate warning.
- */
static void
warn_incompatible_types(op_t op,
const type_t *ltp, tspec_t lt,
const type_t *rtp, tspec_t rt)
{
- const mod_t *mp;
+ const mod_t *mp = &modtab[op];
- mp = &modtab[op];
-
if (lt == VOID || (mp->m_binary && rt == VOID)) {
/* void type illegal in expression */
error(109);
@@ -2190,12 +2180,10 @@
warn_incompatible_types(op, ltp, lt, rtp, rt);
return false;
}
- if (lt == PTR && rt == PTR) {
- if (!types_compatible(ltp->t_subt, rtp->t_subt,
- true, false, NULL)) {
- /* illegal pointer subtraction */
- error(116);
- }
+ if (lt == PTR && rt == PTR &&
+ !types_compatible(ltp->t_subt, rtp->t_subt, true, false, NULL)) {
+ /* illegal pointer subtraction */
+ error(116);
}
return true;
}
@@ -2229,10 +2217,7 @@
}
} else if (allow_trad && allow_c90 &&
!is_uinteger(olt) && is_uinteger(ort)) {
- /*
- * The left operand would become unsigned in
- * traditional C.
- */
+ /* The left operand would become unsigned in traditional C. */
if (hflag && (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
/* semantics of '%s' change in ANSI C; use ... */
warning(118, mp->m_name);
@@ -2313,13 +2298,11 @@
warn_incompatible_pointers(const mod_t *mp,
const type_t *ltp, const type_t *rtp)
{
- tspec_t lt, rt;
-
lint_assert(ltp->t_tspec == PTR);
lint_assert(rtp->t_tspec == PTR);
- lt = ltp->t_subt->t_tspec;
- rt = rtp->t_subt->t_tspec;
+ tspec_t lt = ltp->t_subt->t_tspec;
+ tspec_t rt = rtp->t_subt->t_tspec;
if (is_struct_or_union(lt) && is_struct_or_union(rt)) {
if (mp == NULL) {
@@ -2344,18 +2327,15 @@
static void
check_pointer_comparison(op_t op, const tnode_t *ln, const tnode_t *rn)
{
- type_t *ltp, *rtp;
- tspec_t lst, rst;
- const char *lsts, *rsts;
+ type_t *ltp = ln->tn_type, *rtp = rn->tn_type;
+ tspec_t lst = ltp->t_subt->t_tspec, rst = rtp->t_subt->t_tspec;
- lst = (ltp = ln->tn_type)->t_subt->t_tspec;
- rst = (rtp = rn->tn_type)->t_subt->t_tspec;
-
if (lst == VOID || rst == VOID) {
/* TODO: C99 behaves like C90 here. */
if ((!allow_trad && !allow_c99) &&
(lst == FUNC || rst == FUNC)) {
- /* (void *)0 already handled in typeok() */
+ /* (void *)0 is already handled in typeok() */
+ const char *lsts, *rsts;
*(lst == FUNC ? &lsts : &rsts) = "function pointer";
*(lst == VOID ? &lsts : &rsts) = "'void *'";
/* ANSI C forbids comparison of %s with %s */
@@ -2382,8 +2362,6 @@
const tnode_t *ln, const type_t *ltp, tspec_t lt,
const tnode_t *rn, const type_t *rtp, tspec_t rt)
{
- const char *lx, *rx;
-
if (lt == PTR && rt == PTR) {
check_pointer_comparison(op, ln, rn);
return true;
@@ -2397,8 +2375,8 @@
return false;
}
- lx = lt == PTR ? "pointer" : "integer";
- rx = rt == PTR ? "pointer" : "integer";
+ const char *lx = lt == PTR ? "pointer" : "integer";
+ const char *rx = rt == PTR ? "pointer" : "integer";
/* illegal combination of %s '%s' and %s '%s', op '%s' */
warning(123, lx, type_name(ltp), rx, type_name(rtp), op_name(op));
return true;
@@ -2494,11 +2472,10 @@
static bool
has_constant_member(const type_t *tp)
{
- sym_t *m;
-
lint_assert(is_struct_or_union(tp->t_tspec));
- for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) {
+ for (sym_t *m = tp->t_str->sou_first_member;
+ m != NULL; m = m->s_next) {
const type_t *mtp = m->s_type;
if (mtp->t_const)
return true;
@@ -2572,7 +2549,6 @@
tspec_t lt, tspec_t lst,
tspec_t rt, tspec_t rst)
{
- const char *lts, *rts;
if (!(lt == PTR && rt == PTR && (lst == VOID || rst == VOID)))
return;
@@ -2583,6 +2559,7 @@
return;
/* comb. of ptr to func and ptr to void */
+ const char *lts, *rts;
*(lst == FUNC ? <s : &rts) = "function pointer";
*(lst == VOID ? <s : &rts) = "'void *'";
@@ -2630,8 +2607,6 @@
static bool
is_const_char_pointer(const tnode_t *tn)
{
- const type_t *tp;
-
/*
* For traditional reasons, C99 6.4.5p5 defines that string literals
* have type 'char[]'. They are often implicitly converted to
@@ -2648,7 +2623,7 @@
tn->tn_left->tn_left->tn_op == STRING)
return true;
- tp = before_conversion(tn)->tn_type;
+ const type_t *tp = before_conversion(tn)->tn_type;
return tp->t_tspec == PTR &&
tp->t_subt->t_tspec == CHAR &&
tp->t_subt->t_const;
@@ -2657,9 +2632,7 @@
static bool
is_first_arg_const_char_pointer(const tnode_t *tn)
{
- const tnode_t *an;
-
- an = tn->tn_right;
+ const tnode_t *an = tn->tn_right;
if (an == NULL)
return false;
@@ -2671,18 +2644,14 @@
static bool
is_const_pointer(const tnode_t *tn)
{
- const type_t *tp;
-
- tp = before_conversion(tn)->tn_type;
+ const type_t *tp = before_conversion(tn)->tn_type;
return tp->t_tspec == PTR && tp->t_subt->t_const;
}
static bool
is_second_arg_const_pointer(const tnode_t *tn)
{
- const tnode_t *an;
-
- an = tn->tn_right;
+ const tnode_t *an = tn->tn_right;
if (an == NULL || an->tn_right == NULL)
return false;
@@ -2940,17 +2909,13 @@
check_null_effect(const tnode_t *tn)
{
- if (!hflag)
- return;
- if (has_side_effect(tn))
- return;
- if (is_void_cast(tn) && is_local_symbol(tn->tn_left))
- return;
- if (is_void_cast(tn) && is_int_constant_zero(tn->tn_left))
- return;
-
- /* expression has null effect */
- warning(129);
+ if (hflag &&
+ !has_side_effect(tn) &&
+ !(is_void_cast(tn) && is_local_symbol(tn->tn_left)) &&
+ !(is_void_cast(tn) && is_int_constant_zero(tn->tn_left))) {
+ /* expression has null effect */
+ warning(129);
+ }
}
/*
@@ -3075,10 +3040,8 @@
static void
check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
{
- const mod_t *mp;
+ const mod_t *mp = &modtab[op];
- mp = &modtab[op];
-
if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
switch (op) {
case INIT:
@@ -3170,11 +3133,10 @@
bool
typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn)
{
- const mod_t *mp;
tspec_t lt, rt;
type_t *ltp, *rtp;
- mp = &modtab[op];
+ const mod_t *mp = &modtab[op];
lint_assert((ltp = ln->tn_type) != NULL);
lt = ltp->t_tspec;
@@ -3339,7 +3301,6 @@
check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
tnode_t *tn)
{
- tnode_t *ptn;
if (!is_arithmetic(nt) || !is_arithmetic(ot))
return;
@@ -3354,7 +3315,7 @@
return;
/* apply the default promotion */
- ptn = promote(NOOP, true, tn);
+ tnode_t *ptn = promote(NOOP, true, tn);
ot = ptn->tn_type->t_tspec;
if (should_warn_about_prototype_conversion(nt, ot, ptn)) {
@@ -3525,19 +3486,16 @@
static void
convert_pointer_from_pointer(type_t *ntp, tnode_t *tn)
{
- const type_t *nstp, *otp, *ostp;
- tspec_t nst, ost;
- const char *nts, *ots;
+ const type_t *nstp = ntp->t_subt;
+ const type_t *otp = tn->tn_type;
+ const type_t *ostp = otp->t_subt;
+ tspec_t nst = nstp->t_tspec;
+ tspec_t ost = ostp->t_tspec;
- nstp = ntp->t_subt;
- otp = tn->tn_type;
- ostp = otp->t_subt;
- nst = nstp->t_tspec;
- ost = ostp->t_tspec;
-
if (nst == VOID || ost == VOID) {
/* TODO: C99 behaves like C90 here. */
if ((!allow_trad && !allow_c99) && (nst == FUNC || ost == FUNC)) {
+ const char *nts, *ots;
/* null pointers are already handled in convert() */
*(nst == FUNC ? &nts : &ots) = "function pointer";
*(nst == VOID ? &nts : &ots) = "'void *'";
@@ -3545,9 +3503,10 @@
warning(303, ots, nts);
}
return;
- } else if (nst == FUNC && ost == FUNC) {
+ }
+ if (nst == FUNC && ost == FUNC)
return;
- } else if (nst == FUNC || ost == FUNC) {
+ if (nst == FUNC || ost == FUNC) {
/* converting '%s' to '%s' is questionable */
warning(229, type_name(otp), type_name(ntp));
return;
@@ -3584,12 +3543,9 @@
tnode_t *
convert(op_t op, int arg, type_t *tp, tnode_t *tn)
{
- tnode_t *ntn;
- tspec_t nt, ot;
+ tspec_t nt = tp->t_tspec;
+ tspec_t ot = tn->tn_type->t_tspec;
- nt = tp->t_tspec;
- ot = tn->tn_type->t_tspec;
-
if (allow_trad && allow_c90 && op == FARG)
check_prototype_conversion(arg, nt, ot, tp, tn);
@@ -3618,7 +3574,7 @@
}
}
- ntn = expr_alloc_tnode();
+ tnode_t *ntn = expr_alloc_tnode();
ntn->tn_op = CVT;
ntn->tn_type = tp;
ntn->tn_cast = op == CVT;
@@ -3640,7 +3596,7 @@
convert_constant_floating(op_t op, int arg, tspec_t ot, const type_t *tp,
tspec_t nt, val_t *v, val_t *nv)
{
- ldbl_t max = 0.0, min = 0.0;
+ ldbl_t max = 0.0, min = 0.0;
switch (nt) {
case CHAR:
@@ -3784,17 +3740,13 @@
}
/*
- * Loss of significant bit(s). All truncated bits
- * of unsigned types or all truncated bits plus the
- * msb of the target for signed types are considered
- * to be significant bits. Loss of significant bits
- * means that at least one of the bits was set in an
- * unsigned type or that at least one but not all of
- * the bits was set in a signed type.
- * Loss of significant bits means that it is not
- * possible, also not with necessary casts, to convert
- * back to the original type. A example for a
- * necessary cast is:
+ * Loss of significant bit(s). All truncated bits of unsigned types or all
+ * truncated bits plus the msb of the target for signed types are considered
+ * to be significant bits. Loss of significant bits means that at least one
+ * of the bits was set in an unsigned type or that at least one but not all
+ * of the bits was set in a signed type. Loss of significant bits means that
+ * it is not possible, also not with necessary casts, to convert back to the
+ * original type. A example for a necessary cast is:
* char c; int i; c = 128;
* i = c; ** yields -128 **
* i = (unsigned char)c; ** yields 128 **
@@ -3844,12 +3796,10 @@
warning(196);
} else if (op == FARG) {
/* conversion of '%s' to '%s' is out of range, arg #%d */
- warning(295,
- type_name(gettyp(ot)), type_name(tp), arg);
+ warning(295, type_name(gettyp(ot)), type_name(tp), arg);
} else {
/* conversion of '%s' to '%s' is out of range */
- warning(119,
- type_name(gettyp(ot)), type_name(tp));
+ warning(119, type_name(gettyp(ot)), type_name(tp));
}
}
@@ -3899,17 +3849,13 @@
void
convert_constant(op_t op, int arg, const type_t *tp, val_t *nv, val_t *v)
{
- tspec_t ot, nt;
- unsigned int sz;
- bool range_check;
-
/*
* TODO: make 'v' const; the name of this function does not suggest
* that it modifies 'v'.
*/
- ot = v->v_tspec;
- nt = nv->v_tspec = tp->t_tspec;
- range_check = false;
+ tspec_t ot = v->v_tspec;
+ tspec_t nt = nv->v_tspec = tp->t_tspec;
+ bool range_check = false;
if (nt == BOOL) { /* C99 6.3.1.2 */
nv->v_unsigned_since_c90 = false;
@@ -3934,8 +3880,8 @@
}
if (is_integer(nt)) {
- sz = tp->t_bitfield ? tp->t_flen : size_in_bits(nt);
- nv->v_quad = convert_integer(nv->v_quad, nt, sz);
+ nv->v_quad = convert_integer(nv->v_quad, nt,
+ tp->t_bitfield ? tp->t_flen : size_in_bits(nt));
}
if (range_check && op != CVT)
@@ -3979,11 +3925,10 @@
unsigned int
type_size_in_bits(const type_t *tp)
{
- unsigned int elem, elsz;
- bool flex;
+ unsigned int elsz;
- elem = 1;
- flex = false;
+ unsigned int elem = 1;
+ bool flex = false;
lint_assert(tp != NULL);
while (tp->t_tspec == ARRAY) {
flex = true; /* allow c99 flex arrays [] [0] */
@@ -4205,13 +4150,11 @@
type_t *tp, /* expected type (from prototype) */
tnode_t *tn) /* argument */
{
- tnode_t *ln;
- bool dowarn;
-
- ln = xcalloc(1, sizeof(*ln));
+ tnode_t *ln = xcalloc(1, sizeof(*ln));
ln->tn_type = expr_unqualified_type(tp);
ln->tn_lvalue = true;
if (typeok(FARG, n, ln, tn)) {
+ bool dowarn;
if (!types_compatible(tp, tn->tn_type,
true, false, (dowarn = false, &dowarn)) || dowarn)
tn = convert(FARG, n, tp, tn);
@@ -4342,14 +4285,13 @@
val_t *
constant(tnode_t *tn, bool required)
{
- val_t *v;
if (tn != NULL)
tn = cconv(tn);
if (tn != NULL)
tn = promote(NOOP, false, tn);
- v = xcalloc(1, sizeof(*v));
+ val_t *v = xcalloc(1, sizeof(*v));
if (tn == NULL) {
lint_assert(nerr != 0);
@@ -4452,14 +4394,9 @@
static void
check_array_index(tnode_t *tn, bool amper)
{
- int dim;
- tnode_t *ln, *rn;
- int elsz;
- int64_t con;
+ const tnode_t *ln = tn->tn_left;
+ const tnode_t *rn = tn->tn_right;
- ln = tn->tn_left;
- rn = tn->tn_right;
-
/* We can only check constant indices. */
if (rn->tn_op != CON)
return;
@@ -4480,18 +4417,19 @@
return;
/* Get the size of one array element */
- if ((elsz = length_in_bits(ln->tn_type->t_subt, NULL)) == 0)
+ int elsz = length_in_bits(ln->tn_type->t_subt, NULL);
+ if (elsz == 0)
return;
elsz /= CHAR_SIZE;
/* Change the unit of the index from bytes to element size. */
- if (is_uinteger(rn->tn_type->t_tspec)) {
+ int64_t con;
+ if (is_uinteger(rn->tn_type->t_tspec))
con = (uint64_t)rn->tn_val->v_quad / elsz;
- } else {
+ else
con = rn->tn_val->v_quad / elsz;
- }
- dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
+ int dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
if (!is_uinteger(rn->tn_type->t_tspec) && con < 0) {
/* array subscript cannot be negative: %ld */
@@ -4527,12 +4465,11 @@
static void
check_expr_side_effect(const tnode_t *ln, bool szof)
{
- scl_t sc;
dinfo_t *di;
/* XXX: Taking warn_about_unreachable into account here feels wrong. */
if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
- sc = ln->tn_sym->s_scl;
+ scl_t sc = ln->tn_sym->s_scl;
/*
* Look if there was a asm statement in one of the
* compound statements we are in. If not, we don't