Module Name: src Committed By: rillig Date: Fri Jun 30 12:21:25 UTC 2023
Modified Files: src/usr.bin/xlint/lint1: mem1.c tree.c Log Message: lint: clean up tree.c No functional change. To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/usr.bin/xlint/lint1/mem1.c cvs rdiff -u -r1.535 -r1.536 src/usr.bin/xlint/lint1/tree.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/xlint/lint1/mem1.c diff -u src/usr.bin/xlint/lint1/mem1.c:1.65 src/usr.bin/xlint/lint1/mem1.c:1.66 --- src/usr.bin/xlint/lint1/mem1.c:1.65 Tue Apr 11 19:02:19 2023 +++ src/usr.bin/xlint/lint1/mem1.c Fri Jun 30 12:21:25 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 rillig Exp $ */ +/* $NetBSD: mem1.c,v 1.66 2023/06/30 12:21:25 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: mem1.c,v 1.65 2023/04/11 19:02:19 rillig Exp $"); +__RCSID("$NetBSD: mem1.c,v 1.66 2023/06/30 12:21:25 rillig Exp $"); #endif #include <sys/param.h> @@ -247,7 +247,7 @@ expr_zero_alloc(size_t s) } static bool -str_endswith(const char *haystack, const char *needle) +str_ends_with(const char *haystack, const char *needle) { size_t hlen = strlen(haystack); size_t nlen = strlen(needle); @@ -274,7 +274,7 @@ expr_alloc_tnode(void) */ tn->tn_sys = in_system_header || (curr_pos.p_file != csrc_pos.p_file && - str_endswith(curr_pos.p_file, ".c")); + str_ends_with(curr_pos.p_file, ".c")); return tn; } Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.535 src/usr.bin/xlint/lint1/tree.c:1.536 --- src/usr.bin/xlint/lint1/tree.c:1.535 Fri Jun 30 09:26:03 2023 +++ src/usr.bin/xlint/lint1/tree.c Fri Jun 30 12:21:25 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.535 2023/06/30 09:26:03 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.536 2023/06/30 12:21:25 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.535 2023/06/30 09:26:03 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.536 2023/06/30 12:21:25 rillig Exp $"); #endif #include <float.h> @@ -73,7 +73,7 @@ u64_fill_right(uint64_t x) } static bool -str_endswith(const char *haystack, const char *needle) +str_ends_with(const char *haystack, const char *needle) { size_t hlen = strlen(haystack); size_t nlen = strlen(needle); @@ -370,9 +370,8 @@ new_tnode(op_t op, bool sys, type_t *typ tnode_t * build_constant(type_t *tp, val_t *v) { - tnode_t *n; - n = expr_alloc_tnode(); + tnode_t *n = expr_alloc_tnode(); n->tn_op = CON; n->tn_type = tp; n->tn_val.v_tspec = tp->t_tspec; @@ -386,9 +385,8 @@ build_constant(type_t *tp, val_t *v) static tnode_t * build_integer_constant(tspec_t t, int64_t q) { - tnode_t *n; - n = expr_alloc_tnode(); + tnode_t *n = expr_alloc_tnode(); n->tn_op = CON; n->tn_type = gettyp(t); n->tn_val.v_tspec = t; @@ -459,8 +457,8 @@ static bool is_gcc_bool_builtin(const char *name) { return strncmp(name, "__builtin_", 10) == 0 && - (str_endswith(name, "_overflow") || - str_endswith(name, "_overflow_p")); + (str_ends_with(name, "_overflow") || + str_ends_with(name, "_overflow_p")); } static void @@ -475,7 +473,6 @@ build_name_call(sym_t *sym) */ if (allow_gcc && is_gcc_bool_builtin(sym->s_name)) sym->s_type = gettyp(BOOL); - } else if (allow_c99) { /* function '%s' implicitly declared to return int */ error(215, sym->s_name); @@ -492,7 +489,6 @@ build_name_call(sym_t *sym) tnode_t * build_name(sym_t *sym, bool is_funcname) { - tnode_t *n; if (sym->s_scl == NOSCL && !in_gcc_attribute) { sym->s_scl = EXTERN; @@ -505,7 +501,7 @@ build_name(sym_t *sym, bool is_funcname) lint_assert(sym->s_kind == FVFT || sym->s_kind == FMEMBER); - n = expr_alloc_tnode(); + tnode_t *n = expr_alloc_tnode(); n->tn_type = sym->s_type; if (sym->s_scl == BOOL_CONST) { n->tn_op = CON; @@ -532,19 +528,14 @@ build_name(sym_t *sym, bool is_funcname) tnode_t * build_string(strg_t *strg) { - size_t len; - tnode_t *n; - type_t *tp; - - len = strg->st_len; - - n = expr_alloc_tnode(); + size_t len = strg->st_len; - tp = expr_zero_alloc(sizeof(*tp)); + type_t *tp = expr_zero_alloc(sizeof(*tp)); tp->t_tspec = ARRAY; tp->t_subt = gettyp(strg->st_char ? CHAR : WCHAR); tp->t_dim = (int)(len + 1); + tnode_t *n = expr_alloc_tnode(); n->tn_op = STRING; n->tn_type = tp; n->tn_lvalue = true; @@ -592,10 +583,9 @@ is_out_of_char_range(const tnode_t *tn) static void check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) { - tspec_t lt, rt; - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; + tspec_t lt = ln->tn_type->t_tspec; + tspec_t rt = rn->tn_type->t_tspec; if (ln->tn_op != CON && rn->tn_op != CON) return; @@ -804,25 +794,21 @@ build_address(bool sys, tnode_t *tn, boo static tnode_t * fold(tnode_t *tn) { - val_t *v; - tspec_t t; - bool utyp, ovfl; - int64_t sl, sr = 0, q = 0, mask; - uint64_t ul, ur = 0; - tnode_t *cn; - v = xcalloc(1, sizeof(*v)); + val_t *v = xcalloc(1, sizeof(*v)); v->v_tspec = tn->tn_type->t_tspec; - t = tn->tn_left->tn_type->t_tspec; - utyp = !is_integer(t) || is_uinteger(t); - ul = sl = tn->tn_left->tn_val.v_quad; + tspec_t t = tn->tn_left->tn_type->t_tspec; + bool utyp = !is_integer(t) || is_uinteger(t); + int64_t sl = tn->tn_left->tn_val.v_quad, sr = 0; + uint64_t ul = sl, ur = 0; if (is_binary(tn)) ur = sr = tn->tn_right->tn_val.v_quad; - mask = (int64_t)value_bits(size_in_bits(t)); - ovfl = false; + int64_t mask = (int64_t)value_bits(size_in_bits(t)); + bool ovfl = false; + int64_t q; switch (tn->tn_op) { case UPLUS: q = sl; @@ -925,7 +911,7 @@ fold(tnode_t *tn) lint_assert(/*CONSTCOND*/false); } - /* XXX does not work for quads. */ + /* XXX: The overflow check does not work for 64-bit integers. */ if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) { if (hflag) @@ -935,7 +921,7 @@ fold(tnode_t *tn) v->v_quad = convert_integer(q, t, 0); - cn = build_constant(tn->tn_type, v); + tnode_t *cn = build_constant(tn->tn_type, v); if (tn->tn_left->tn_system_dependent) cn->tn_system_dependent = true; if (is_binary(tn) && tn->tn_right->tn_system_dependent) @@ -950,8 +936,6 @@ fold(tnode_t *tn) static tnode_t * build_struct_access(op_t op, bool sys, tnode_t *ln, tnode_t *rn) { - tnode_t *ntn, *ctn; - bool nolval; lint_assert(rn->tn_op == NAME); lint_assert(is_member(rn->tn_sym)); @@ -960,7 +944,7 @@ build_struct_access(op_t op, bool sys, t * Remember if the left operand is an lvalue (structure members * are lvalues if and only if the structure itself is an lvalue). */ - nolval = op == POINT && !ln->tn_lvalue; + bool nolval = op == POINT && !ln->tn_lvalue; if (op == POINT) { ln = build_address(sys, ln, true); @@ -970,11 +954,11 @@ build_struct_access(op_t op, bool sys, t ln = convert(NOOP, 0, expr_derive_type(gettyp(VOID), PTR), ln); } - ctn = build_integer_constant(PTRDIFF_TSPEC, + tnode_t *ctn = build_integer_constant(PTRDIFF_TSPEC, rn->tn_sym->u.s_member.sm_offset_in_bits / CHAR_SIZE); - ntn = new_tnode(PLUS, sys, expr_derive_type(rn->tn_type, PTR), - ln, ctn); + type_t *ptr_tp = expr_derive_type(rn->tn_type, PTR); + tnode_t *ntn = new_tnode(PLUS, sys, ptr_tp, ln, ctn); if (ln->tn_op == CON) ntn = fold(ntn); @@ -997,19 +981,17 @@ build_struct_access(op_t op, bool sys, t static tnode_t * subt_size_in_bytes(type_t *tp) { - int elem, elsz_in_bits; lint_assert(tp->t_tspec == PTR); tp = tp->t_subt; - elem = 1; - elsz_in_bits = 0; - + int elem = 1; while (tp->t_tspec == ARRAY) { elem *= tp->t_dim; tp = tp->t_subt; } + int elsz_in_bits = 0; switch (tp->t_tspec) { case FUNC: /* pointer to function is not allowed here */ @@ -1059,33 +1041,23 @@ subt_size_in_bytes(type_t *tp) static tnode_t * build_prepost_incdec(op_t op, bool sys, tnode_t *ln) { - tnode_t *cn, *ntn; lint_assert(ln != NULL); - - if (ln->tn_type->t_tspec == PTR) { - cn = subt_size_in_bytes(ln->tn_type); - } else { - cn = build_integer_constant(INT, (int64_t)1); - } - ntn = new_tnode(op, sys, ln->tn_type, ln, cn); - - return ntn; + tnode_t *cn = ln->tn_type->t_tspec == PTR + ? subt_size_in_bytes(ln->tn_type) + : build_integer_constant(INT, 1); + return new_tnode(op, sys, ln->tn_type, ln, cn); } static void check_enum_array_index(const tnode_t *ln, const tnode_t *rn) { - int max_array_index; - int64_t max_enum_value; - const struct sym *ec, *max_ec; - const type_t *lt, *rt; if (ln->tn_op != ADDR || ln->tn_left->tn_op != NAME) return; - lt = ln->tn_left->tn_type; - if (lt->t_tspec != ARRAY || lt->t_incomplete_array) + const type_t *ltp = ln->tn_left->tn_type; + if (ltp->t_tspec != ARRAY || ltp->t_incomplete_array) return; if (rn->tn_op != CVT || !rn->tn_type->t_is_enum) @@ -1093,18 +1065,18 @@ check_enum_array_index(const tnode_t *ln if (rn->tn_left->tn_op != LOAD) return; - rt = rn->tn_left->tn_type; - ec = rt->t_enum->en_first_enumerator; - max_ec = ec; + const type_t *rtp = rn->tn_left->tn_type; + const struct sym *ec = rtp->t_enum->en_first_enumerator; + const struct sym *max_ec = ec; lint_assert(ec != NULL); for (ec = ec->s_next; ec != NULL; ec = ec->s_next) if (ec->u.s_enum_constant > max_ec->u.s_enum_constant) max_ec = ec; - max_enum_value = max_ec->u.s_enum_constant; + int64_t max_enum_value = max_ec->u.s_enum_constant; lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX); - max_array_index = lt->t_dim - 1; + int max_array_index = ltp->t_dim - 1; if (max_enum_value == max_array_index) return; @@ -1121,7 +1093,7 @@ check_enum_array_index(const tnode_t *ln return; /* maximum value %d of '%s' does not match maximum array index %d */ - warning(348, (int)max_enum_value, type_name(rt), max_array_index); + warning(348, (int)max_enum_value, type_name(rtp), max_array_index); print_previous_declaration(max_ec); } @@ -1132,7 +1104,7 @@ static tnode_t * build_plus_minus(op_t op, bool sys, tnode_t *ln, tnode_t *rn) { - /* If pointer and integer, then pointer to the lhs. */ + /* If pointer and integer, move the pointer to the left. */ if (rn->tn_type->t_tspec == PTR && is_integer(ln->tn_type->t_tspec)) { tnode_t *tmp = ln; ln = rn; @@ -1204,25 +1176,23 @@ is_null_pointer(const tnode_t *tn) static type_t * merge_qualifiers(type_t *tp1, const type_t *tp2) { - type_t *ntp, *nstp; - bool c1, c2, v1, v2; lint_assert(tp1->t_tspec == PTR); lint_assert(tp2->t_tspec == PTR); - c1 = tp1->t_subt->t_const; - c2 = tp2->t_subt->t_const; - v1 = tp1->t_subt->t_volatile; - v2 = tp2->t_subt->t_volatile; + bool c1 = tp1->t_subt->t_const; + bool c2 = tp2->t_subt->t_const; + bool v1 = tp1->t_subt->t_volatile; + bool v2 = tp2->t_subt->t_volatile; if (c1 == (c1 | c2) && v1 == (v1 | v2)) return tp1; - nstp = expr_dup_type(tp1->t_subt); + type_t *nstp = expr_dup_type(tp1->t_subt); nstp->t_const |= c2; nstp->t_volatile |= v2; - ntp = expr_dup_type(tp1); + type_t *ntp = expr_dup_type(tp1); ntp->t_subt = nstp; return ntp; } @@ -1231,12 +1201,11 @@ merge_qualifiers(type_t *tp1, const type static tnode_t * build_colon(bool sys, tnode_t *ln, tnode_t *rn) { - tspec_t lt, rt; - type_t *tp; - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; + tspec_t lt = ln->tn_type->t_tspec; + tspec_t rt = rn->tn_type->t_tspec; + type_t *tp; if (is_arithmetic(lt) && is_arithmetic(rt)) { /* The operands were already balanced in build_binary. */ tp = ln->tn_type; @@ -1346,11 +1315,9 @@ is_assignment(op_t op) static tnode_t * build_assignment(op_t op, bool sys, tnode_t *ln, tnode_t *rn) { - tspec_t lt, rt; - tnode_t *ntn, *ctn; - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; + tspec_t lt = ln->tn_type->t_tspec; + tspec_t rt = rn->tn_type->t_tspec; if (any_query_enabled && is_assignment(rn->tn_op)) { /* chained assignment with '%s' and '%s' */ @@ -1359,7 +1326,7 @@ build_assignment(op_t op, bool sys, tnod if ((op == ADDASS || op == SUBASS) && lt == PTR) { lint_assert(is_integer(rt)); - ctn = subt_size_in_bytes(ln->tn_type); + tnode_t *ctn = subt_size_in_bytes(ln->tn_type); if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) rn = convert(NOOP, 0, ctn->tn_type, rn); rn = new_tnode(MULT, sys, rn->tn_type, rn, ctn); @@ -1407,9 +1374,7 @@ build_assignment(op_t op, bool sys, tnod type_name(rn->tn_left->tn_type), type_name(rn->tn_type)); } - ntn = new_tnode(op, sys, ln->tn_type, ln, rn); - - return ntn; + return new_tnode(op, sys, ln->tn_type, ln, rn); } /* @@ -1418,10 +1383,8 @@ build_assignment(op_t op, bool sys, tnod static tnode_t * build_real_imag(op_t op, bool sys, tnode_t *ln) { - tnode_t *cn, *ntn; lint_assert(ln != NULL); - if (ln->tn_op == NAME) { /* * This may be too much, but it avoids wrong warnings. @@ -1431,6 +1394,7 @@ build_real_imag(op_t op, bool sys, tnode mark_as_set(ln->tn_sym); } + tnode_t *cn; switch (ln->tn_type->t_tspec) { case LCOMPLEX: /* XXX: integer and LDOUBLE don't match. */ @@ -1450,9 +1414,9 @@ build_real_imag(op_t op, bool sys, tnode type_name(ln->tn_type)); return NULL; } - ntn = new_tnode(op, sys, cn->tn_type, ln, cn); - ntn->tn_lvalue = true; + tnode_t *ntn = new_tnode(op, sys, cn->tn_type, ln, cn); + ntn->tn_lvalue = true; return ntn; } @@ -1529,15 +1493,13 @@ check_precedence_confusion(tnode_t *tn) static tnode_t * fold_bool(tnode_t *tn) { - bool l, r; - val_t *v; - v = xcalloc(1, sizeof(*v)); + val_t *v = xcalloc(1, sizeof(*v)); v->v_tspec = tn->tn_type->t_tspec; lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL)); - l = constant_is_nonzero(tn->tn_left); - r = is_binary(tn) && constant_is_nonzero(tn->tn_right); + bool l = constant_is_nonzero(tn->tn_left); + bool r = is_binary(tn) && constant_is_nonzero(tn->tn_right); switch (tn->tn_op) { case NOT: @@ -1588,27 +1550,38 @@ floating_error_value(tspec_t t, long dou return lv < 0 ? -max : max; } +static bool +is_floating_overflow(tspec_t t, long double val) +{ + if (fpe != 0 || isfinite(val) == 0) + return true; + if (t == FLOAT && (val > FLT_MAX || val < -FLT_MAX)) + return true; + if (t == DOUBLE && (val > DBL_MAX || val < -DBL_MAX)) + return true; + return false; +} + /* * Fold constant nodes having operands with floating point type. */ static tnode_t * fold_float(tnode_t *tn) { - val_t *v; - tspec_t t; - long double lv, rv = 0; fpe = 0; - v = xcalloc(1, sizeof(*v)); - v->v_tspec = t = tn->tn_type->t_tspec; + + tspec_t t = tn->tn_type->t_tspec; + + val_t *v = xcalloc(1, sizeof(*v)); + v->v_tspec = t; lint_assert(is_floating(t)); lint_assert(t == tn->tn_left->tn_type->t_tspec); lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec); - lv = tn->tn_left->tn_val.v_ldbl; - if (is_binary(tn)) - rv = tn->tn_right->tn_val.v_ldbl; + long double lv = tn->tn_left->tn_val.v_ldbl; + long double rv = is_binary(tn) ? tn->tn_right->tn_val.v_ldbl : 0.0; switch (tn->tn_op) { case UPLUS: @@ -1664,11 +1637,7 @@ fold_float(tnode_t *tn) * complex numbers. */ fpe = 0; - } else if (fpe != 0 || isfinite(v->v_ldbl) == 0 || - (t == FLOAT && - (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || - (t == DOUBLE && - (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { + } else if (is_floating_overflow(t, v->v_ldbl)) { /* floating point overflow on operator '%s' */ warning(142, op_name(tn->tn_op)); v->v_ldbl = floating_error_value(t, v->v_ldbl); @@ -1687,11 +1656,7 @@ fold_float(tnode_t *tn) tnode_t * build_binary(tnode_t *ln, op_t op, bool sys, tnode_t *rn) { - const mod_t *mp; - tnode_t *ntn; - type_t *rettp; - - mp = &modtab[op]; + const mod_t *mp = &modtab[op]; /* If there was an error in one of the operands, return. */ if (ln == NULL || (mp->m_binary && rn == NULL)) @@ -1757,6 +1722,7 @@ build_binary(tnode_t *ln, op_t op, bool return NULL; /* And now create the node. */ + tnode_t *ntn; switch (op) { case POINT: case ARROW: @@ -1815,9 +1781,9 @@ build_binary(tnode_t *ln, op_t op, bool ntn = build_real_imag(op, sys, ln); break; default: - rettp = mp->m_returns_bool - ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; lint_assert(mp->m_binary == (rn != NULL)); + type_t *rettp = mp->m_returns_bool + ? gettyp(Tflag ? BOOL : INT) : ln->tn_type; ntn = new_tnode(op, sys, rettp, ln, rn); break; } @@ -1869,6 +1835,28 @@ build_unary(op_t op, bool sys, tnode_t * return build_binary(tn, op, sys, NULL); } +static bool +are_members_compatible(const sym_t *a, const sym_t *b) +{ + if (a->u.s_member.sm_offset_in_bits != b->u.s_member.sm_offset_in_bits) + return false; + + const type_t *atp = a->s_type; + const type_t *btp = b->s_type; + bool w = false; + if (!types_compatible(atp, btp, false, false, &w) && !w) + return false; + if (a->s_bitfield != b->s_bitfield) + return false; + if (a->s_bitfield) { + if (atp->t_bit_field_width != btp->t_bit_field_width) + return false; + if (atp->t_bit_field_offset != btp->t_bit_field_offset) + return false; + } + return true; +} + /* * Return whether all struct/union members with the same name have the same * type and offset. @@ -1885,29 +1873,10 @@ all_members_compatible(const sym_t *msym for (const sym_t *sym = csym->s_symtab_next; sym != NULL; sym = sym->s_symtab_next) { - - if (!is_member(sym)) - continue; - if (strcmp(csym->s_name, sym->s_name) != 0) - continue; - if (csym->u.s_member.sm_offset_in_bits != - sym->u.s_member.sm_offset_in_bits) - return false; - - bool w = false; - if (!types_compatible(csym->s_type, sym->s_type, - false, false, &w) && !w) - return false; - if (csym->s_bitfield != sym->s_bitfield) + if (is_member(sym) + && strcmp(csym->s_name, sym->s_name) == 0 + && !are_members_compatible(csym, sym)) return false; - if (csym->s_bitfield) { - if (csym->s_type->t_bit_field_width - != sym->s_type->t_bit_field_width) - return false; - if (csym->s_type->t_bit_field_offset - != sym->s_type->t_bit_field_offset) - return false; - } } } return true; @@ -1920,9 +1889,6 @@ all_members_compatible(const sym_t *msym static sym_t * struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) { - struct_or_union *str; - type_t *tp; - tspec_t t; /* * Remove the member if it was unknown until now, which means @@ -1948,16 +1914,12 @@ struct_or_union_member(tnode_t *tn, op_t } /* Set str to the tag of which msym is expected to be a member. */ - str = NULL; - t = (tp = tn->tn_type)->t_tspec; - if (op == POINT) { - if (is_struct_or_union(t)) - str = tp->t_sou; - } else if (op == ARROW && t == PTR) { - t = (tp = tp->t_subt)->t_tspec; - if (is_struct_or_union(t)) - str = tp->t_sou; - } + struct_or_union *str = NULL; + if (op == POINT && is_struct_or_union(tn->tn_type->t_tspec)) + str = tn->tn_type->t_sou; + if (op == ARROW && tn->tn_type->t_tspec == PTR + && is_struct_or_union(tn->tn_type->t_subt->t_tspec)) + str = tn->tn_type->t_subt->t_sou; /* * If this struct/union has a member with the name of msym, return it. @@ -2272,10 +2234,8 @@ typeok_shr(const mod_t *mp, const tnode_t *ln, tspec_t lt, const tnode_t *rn, tspec_t rt) { - tspec_t olt, ort; - - olt = before_conversion(ln)->tn_type->t_tspec; - ort = before_conversion(rn)->tn_type->t_tspec; + tspec_t olt = before_conversion(ln)->tn_type->t_tspec; + tspec_t ort = before_conversion(rn)->tn_type->t_tspec; /* operands have integer types (checked in typeok) */ if (pflag && !is_uinteger(olt)) { @@ -2580,8 +2540,8 @@ typeok_assign(op_t op, const tnode_t *ln /* %soperand of '%s' must be lvalue */ error(114, "left ", op_name(op)); return false; - } else if (ltp->t_const || (is_struct_or_union(lt) && - has_constant_member(ltp))) { + } else if (ltp->t_const + || (is_struct_or_union(lt) && has_constant_member(ltp))) { if (allow_c90) /* %soperand of '%s' must be modifiable lvalue */ warning(115, "left ", op_name(op)); @@ -2809,13 +2769,12 @@ check_assign_pointer_integer(op_t op, in const type_t *const ltp, tspec_t const lt, const type_t *const rtp, tspec_t const rt) { - const char *lx, *rx; if (!((lt == PTR && is_integer(rt)) || (is_integer(lt) && rt == PTR))) 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"; switch (op) { case INIT: @@ -3103,10 +3062,7 @@ check_bad_enum_operation(op_t op, const if (!eflag) return; - /* - * Enum as offset to a pointer is an exception (otherwise enums - * could not be used as array indices). - */ + /* Allow enum in array indices. */ if (op == PLUS && ((ln->tn_type->t_is_enum && rn->tn_type->t_tspec == PTR) || (rn->tn_type->t_is_enum && ln->tn_type->t_tspec == PTR))) { @@ -3117,9 +3073,7 @@ check_bad_enum_operation(op_t op, const warning(241, op_name(op)); } -/* - * Prints a warning if an operator is applied to two different enum types. - */ +/* Prints a warning if an operator is applied to two different enum types. */ static void check_enum_type_mismatch(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) { @@ -3216,21 +3170,14 @@ typeok_enum(op_t op, const mod_t *mp, in bool typeok(op_t op, int arg, const tnode_t *ln, const tnode_t *rn) { - tspec_t lt, rt; - type_t *ltp, *rtp; const mod_t *mp = &modtab[op]; - lint_assert((ltp = ln->tn_type) != NULL); - lt = ltp->t_tspec; + type_t *ltp = ln->tn_type; + tspec_t lt = ltp->t_tspec; - if (mp->m_binary) { - lint_assert((rtp = rn->tn_type) != NULL); - rt = rtp->t_tspec; - } else { - rtp = NULL; - rt = NO_TSPEC; - } + type_t *rtp = mp->m_binary ? rn->tn_type : NULL; + tspec_t rt = mp->m_binary ? rtp->t_tspec : NO_TSPEC; if (Tflag && !typeok_scalar_strict_bool(op, mp, arg, ln, rn)) return false; @@ -3665,13 +3612,12 @@ convert(op_t op, int arg, type_t *tp, tn } else if (is_integer(nt)) { if (ot == BOOL) { /* No further checks. */ - } else if (is_integer(ot)) { + } else if (is_integer(ot)) convert_integer_from_integer(op, arg, nt, ot, tp, tn); - } else if (is_floating(ot)) { + else if (is_floating(ot)) convert_integer_from_floating(op, tp, tn); - } else if (ot == PTR) { + else if (ot == PTR) convert_integer_from_pointer(op, nt, tp, tn); - } } else if (is_floating(nt)) { /* No further checks. */ @@ -3679,9 +3625,8 @@ convert(op_t op, int arg, type_t *tp, tn } else if (nt == PTR) { if (is_null_pointer(tn)) { /* a null pointer may be assigned to any pointer. */ - } else if (ot == PTR && op == CVT) { + } else if (ot == PTR && op == CVT) convert_pointer_from_pointer(tp, tn); - } } tnode_t *ntn = expr_alloc_tnode(); @@ -3754,21 +3699,19 @@ convert_constant_floating(op_t op, int a 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)); } v->v_ldbl = v->v_ldbl > 0 ? max : min; } - if (nt == FLOAT || nt == FCOMPLEX) { + if (nt == FLOAT || nt == FCOMPLEX) nv->v_ldbl = (float)v->v_ldbl; - } else if (nt == DOUBLE || nt == DCOMPLEX) { + else if (nt == DOUBLE || nt == DCOMPLEX) nv->v_ldbl = (double)v->v_ldbl; - } else if (nt == LDOUBLE || nt == LCOMPLEX) { + else if (nt == LDOUBLE || nt == LCOMPLEX) nv->v_ldbl = v->v_ldbl; - } else { + else nv->v_quad = (int64_t)v->v_ldbl; - } } static bool @@ -3861,55 +3804,51 @@ convert_constant_check_range_signed(op_t * i = (unsigned char)c; ** yields 128 ** */ static void -convert_constant_check_range_truncated(op_t op, int arg, const type_t *tp, - tspec_t ot) +warn_constant_check_range_truncated(op_t op, int arg, const type_t *tp, + tspec_t ot) { - if (op == ASSIGN && tp->t_bitfield) { + if (op == ASSIGN && tp->t_bitfield) /* precision lost in bit-field assignment */ warning(166); - } else if (op == ASSIGN) { + else if (op == ASSIGN) /* constant truncated by assignment */ warning(165); - } else if (op == INIT && tp->t_bitfield) { + else if (op == INIT && tp->t_bitfield) /* bit-field initializer does not fit */ warning(180); - } else if (op == INIT) { + else if (op == INIT) /* initializer does not fit */ warning(178); - } else if (op == CASE) { + else if (op == CASE) /* case label affected by conversion */ warning(196); - } else if (op == FARG) { + 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); - } else { + 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)); } static void -convert_constant_check_range_loss(op_t op, int arg, const type_t *tp, +warn_constant_check_range_loss(op_t op, int arg, const type_t *tp, tspec_t ot) { - if (op == ASSIGN && tp->t_bitfield) { + if (op == ASSIGN && tp->t_bitfield) /* precision lost in bit-field assignment */ warning(166); - } else if (op == INIT && tp->t_bitfield) { + else if (op == INIT && tp->t_bitfield) /* bit-field initializer out of range */ warning(11); - } else if (op == CASE) { + else if (op == CASE) /* case label affected by conversion */ warning(196); - } else if (op == FARG) { + 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); - } else { + else /* conversion of '%s' to '%s' is out of range */ warning(119, type_name(gettyp(ot)), type_name(tp)); - } } static void @@ -3935,15 +3874,14 @@ convert_constant_check_range(tspec_t ot, nbitsz, obitsz, xmask, nv, ot, v, tp, op); } else if ((nt != PTR && is_uinteger(nt)) && (ot != PTR && !is_uinteger(ot)) && - v->v_quad < 0) { + v->v_quad < 0) convert_constant_check_range_signed(op, arg); - } else if (nv->v_quad != v->v_quad && nbitsz <= obitsz && - (v->v_quad & xmask) != 0 && - (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) { - convert_constant_check_range_truncated(op, arg, tp, ot); - } else if (nv->v_quad != v->v_quad) { - convert_constant_check_range_loss(op, arg, tp, ot); - } + else if (nv->v_quad != v->v_quad && nbitsz <= obitsz && + (v->v_quad & xmask) != 0 && + (is_uinteger(ot) || (v->v_quad & xmsk1) != xmsk1)) + warn_constant_check_range_truncated(op, arg, tp, ot); + else if (nv->v_quad != v->v_quad) + warn_constant_check_range_loss(op, arg, tp, ot); } /* @@ -3972,9 +3910,9 @@ convert_constant(op_t op, int arg, const return; } - if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { + if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) convert_constant_floating(op, arg, ot, tp, nt, v, nv); - } else if (!convert_constant_to_floating(nt, nv, ot, v)) { + else if (!convert_constant_to_floating(nt, nv, ot, v)) { range_check = true; /* Check for lost precision. */ nv->v_quad = v->v_quad; } @@ -4017,16 +3955,14 @@ build_sizeof(const type_t *tp) tnode_t * build_offsetof(const type_t *tp, const sym_t *sym) { - unsigned int offset_in_bytes; - tnode_t *tn; if (!is_struct_or_union(tp->t_tspec)) /* unacceptable operand of '%s' */ error(111, "offsetof"); /* FIXME: Don't wrongly use the size of the whole type, use sym. */ - offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; - tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes); + unsigned int offset_in_bytes = type_size_in_bits(tp) / CHAR_SIZE; + tnode_t *tn = build_integer_constant(SIZEOF_TSPEC, offset_in_bytes); tn->tn_system_dependent = true; return tn; } @@ -4034,7 +3970,6 @@ build_offsetof(const type_t *tp, const s unsigned int type_size_in_bits(const type_t *tp) { - unsigned int elsz; unsigned int elem = 1; bool flex = false; @@ -4044,13 +3979,13 @@ type_size_in_bits(const type_t *tp) elem *= tp->t_dim; tp = tp->t_subt; } - if (elem == 0) { - if (!flex) { - /* cannot take size/alignment of incomplete type */ - error(143); - elem = 1; - } + if (elem == 0 && !flex) { + /* cannot take size/alignment of incomplete type */ + error(143); + elem = 1; } + + unsigned int elsz; switch (tp->t_tspec) { case FUNC: /* cannot take size/alignment of function type '%s' */ @@ -4092,6 +4027,7 @@ type_size_in_bits(const type_t *tp) return elem * elsz; } +/* C11 6.5.3.4, GCC */ tnode_t * build_alignof(const type_t *tp) { @@ -4154,7 +4090,6 @@ cast_to_union(tnode_t *otn, type_t *ntp) tnode_t * cast(tnode_t *tn, type_t *tp) { - tspec_t nt, ot; if (tn == NULL) return NULL; @@ -4162,8 +4097,8 @@ cast(tnode_t *tn, type_t *tp) tn = cconv(tn); lint_assert(tp != NULL); - nt = tp->t_tspec; - ot = tn->tn_type->t_tspec; + tspec_t nt = tp->t_tspec; + tspec_t ot = tn->tn_type->t_tspec; if (nt == VOID) { /* @@ -4171,15 +4106,15 @@ cast(tnode_t *tn, type_t *tp) * be cast to void. The only other allowed casts are from a * scalar type to a scalar type. */ - } else if (nt == UNION) { + } else if (nt == UNION) return cast_to_union(tn, tp); - } else if (nt == STRUCT || nt == ARRAY || nt == FUNC) { + else if (nt == STRUCT || nt == ARRAY || nt == FUNC) { /* Casting to a struct is an undocumented GCC extension. */ if (!(allow_gcc && nt == STRUCT)) goto invalid_cast; - } else if (is_struct_or_union(ot)) { + } else if (is_struct_or_union(ot)) goto invalid_cast; - } else if (ot == VOID) { + else if (ot == VOID) { /* improper cast of void expression */ error(148); return NULL; @@ -4267,39 +4202,36 @@ check_prototype_argument( static tnode_t * check_function_arguments(type_t *ftp, tnode_t *args) { - tnode_t *arg; - sym_t *asym; - tspec_t at; - int narg, npar, n, i; - - /* get # of args in the prototype */ - npar = 0; - for (asym = ftp->t_args; asym != NULL; asym = asym->s_next) + /* get # of parameters in the prototype */ + int npar = 0; + for (sym_t *asym = ftp->t_args; asym != NULL; asym = asym->s_next) npar++; - /* get # of args in function call */ - narg = 0; - for (arg = args; arg != NULL; arg = arg->tn_right) + /* get # of arguments in the function call */ + int narg = 0; + for (tnode_t *arg = args; arg != NULL; arg = arg->tn_right) narg++; - asym = ftp->t_args; + sym_t *asym = ftp->t_args; if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { /* argument mismatch: %d %s passed, %d expected */ error(150, narg, narg > 1 ? "arguments" : "argument", npar); asym = NULL; } - for (n = 1; n <= narg; n++) { + for (int n = 1; n <= narg; n++) { /* * The rightmost argument is at the top of the argument * subtree. */ - for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) + tnode_t *arg = args; + for (int i = narg; i > n; i--, arg = arg->tn_right) continue; /* some things which are always not allowed */ - if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { + tspec_t at = arg->tn_left->tn_type->t_tspec; + if (at == VOID) { /* void expressions may not be arguments, arg #%d */ error(151, n); return NULL; @@ -4321,9 +4253,8 @@ check_function_arguments(type_t *ftp, tn if (asym != NULL) { arg->tn_left = check_prototype_argument( n, asym->s_type, arg->tn_left); - } else { + } else arg->tn_left = promote(NOOP, true, arg->tn_left); - } arg->tn_type = arg->tn_left->tn_type; if (asym != NULL) @@ -4340,24 +4271,16 @@ check_function_arguments(type_t *ftp, tn tnode_t * build_function_call(tnode_t *func, bool sys, tnode_t *args) { - tnode_t *ntn; - op_t fcop; if (func == NULL) return NULL; - if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { - fcop = CALL; - } else { - fcop = ICALL; - } + op_t fcop = func->tn_op == NAME && func->tn_type->t_tspec == FUNC + ? CALL : ICALL; check_ctype_function_call(func, args); - /* - * after cconv() func will always be a pointer to a function - * if it is a valid function designator. - */ + /* Turn the function name into a pointer to the function. */ func = cconv(func); if (func->tn_type->t_tspec != PTR || @@ -4369,9 +4292,7 @@ build_function_call(tnode_t *func, bool args = check_function_arguments(func->tn_type->t_subt, args); - ntn = new_tnode(fcop, sys, func->tn_type->t_subt->t_subt, func, args); - - return ntn; + return new_tnode(fcop, sys, func->tn_type->t_subt->t_subt, func, args); } /* @@ -4557,25 +4478,28 @@ check_expr_load(const tnode_t *ln) check_array_index(ln->tn_left, false); } +/* + * If there is an asm statement in one of the compound statements around, + * there may be other side effects, so don't warn. + */ +static bool +is_asm_around(void) +{ + for (dinfo_t *di = dcs; di != NULL; di = di->d_enclosing) + if (di->d_asm) + return true; + return false; +} + static void check_expr_side_effect(const tnode_t *ln, bool szof) { - dinfo_t *di; /* XXX: Taking warn_about_unreachable into account here feels wrong. */ if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) { scl_t sc = ln->tn_sym->s_scl; - /* - * Look if there was an asm statement in one of the - * compound statements we are in. If not, we don't - * print a warning. - */ - for (di = dcs; di != NULL; di = di->d_enclosing) { - if (di->d_asm) - break; - } if (sc != EXTERN && sc != STATIC && - !ln->tn_sym->s_set && !szof && di == NULL) { + !ln->tn_sym->s_set && !szof && !is_asm_around()) { /* '%s' may be used before set */ warning(158, ln->tn_sym->s_name); mark_as_set(ln->tn_sym); @@ -4604,8 +4528,7 @@ check_expr_call(const tnode_t *tn, const { lint_assert(ln->tn_op == ADDR); lint_assert(ln->tn_left->tn_op == NAME); - if (!szof && - !is_compiler_builtin(ln->tn_left->tn_sym->s_name)) + if (!szof && !is_compiler_builtin(ln->tn_left->tn_sym->s_name)) outcall(tn, vctx || cond, retval_discarded); } @@ -4679,25 +4602,22 @@ void check_expr_misc(const tnode_t *tn, bool vctx, bool cond, bool eqwarn, bool fcall, bool retval_discarded, bool szof) { - tnode_t *ln, *rn; - const mod_t *mp; - op_t op; - bool cvctx, ccond, eq, discard; if (tn == NULL) return; - ln = tn->tn_left; - rn = tn->tn_right; - mp = &modtab[op = tn->tn_op]; + tnode_t *ln = tn->tn_left; + tnode_t *rn = tn->tn_right; + op_t op = tn->tn_op; + const mod_t *mp = &modtab[op]; if (!check_expr_op(tn, op, ln, szof, fcall, vctx, cond, retval_discarded, eqwarn)) return; - cvctx = mp->m_value_context; - ccond = mp->m_compares_with_zero; - eq = mp->m_warn_if_operand_eq && + bool cvctx = mp->m_value_context; + bool ccond = mp->m_compares_with_zero; + bool eq = mp->m_warn_if_operand_eq && !ln->tn_parenthesized && rn != NULL && !rn->tn_parenthesized; @@ -4709,7 +4629,7 @@ check_expr_misc(const tnode_t *tn, bool */ if (op == COLON && tn->tn_type->t_tspec == VOID) cvctx = ccond = false; - discard = op == CVT && tn->tn_type->t_tspec == VOID; + bool discard = op == CVT && tn->tn_type->t_tspec == VOID; check_expr_misc(ln, cvctx, ccond, eq, op == CALL, discard, szof); switch (op) {