| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tree.c,v 1.260 2021/04/02 15:06:35 rillig Exp $ */ | | 1 | /* $NetBSD: tree.c,v 1.261 2021/04/02 16:17: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) && !defined(lint) | | 39 | #if defined(__RCSID) && !defined(lint) |
40 | __RCSID("$NetBSD: tree.c,v 1.260 2021/04/02 15:06:35 rillig Exp $"); | | 40 | __RCSID("$NetBSD: tree.c,v 1.261 2021/04/02 16:17: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 | #include "cgram.h" | | 51 | #include "cgram.h" |
52 | | | 52 | |
53 | static tnode_t *expr_new_integer_constant(tspec_t, int64_t); | | 53 | static tnode_t *expr_new_integer_constant(tspec_t, int64_t); |
| @@ -685,27 +685,27 @@ build(op_t op, tnode_t *ln, tnode_t *rn) | | | @@ -685,27 +685,27 @@ build(op_t op, tnode_t *ln, tnode_t *rn) |
685 | tnode_t * | | 685 | tnode_t * |
686 | cconv(tnode_t *tn) | | 686 | cconv(tnode_t *tn) |
687 | { | | 687 | { |
688 | type_t *tp; | | 688 | type_t *tp; |
689 | | | 689 | |
690 | /* | | 690 | /* |
691 | * Array-lvalue (array of type T) is converted into rvalue | | 691 | * Array-lvalue (array of type T) is converted into rvalue |
692 | * (pointer to type T) | | 692 | * (pointer to type T) |
693 | */ | | 693 | */ |
694 | if (tn->tn_type->t_tspec == ARRAY) { | | 694 | if (tn->tn_type->t_tspec == ARRAY) { |
695 | if (!tn->tn_lvalue) { | | 695 | if (!tn->tn_lvalue) { |
696 | /* XXX print correct operator */ | | 696 | /* XXX print correct operator */ |
697 | /* %soperand of '%s' must be lvalue */ | | 697 | /* %soperand of '%s' must be lvalue */ |
698 | gnuism(114, "", modtab[ADDR].m_name); | | 698 | gnuism(114, "", op_name(ADDR)); |
699 | } | | 699 | } |
700 | tn = new_tnode(ADDR, | | 700 | tn = new_tnode(ADDR, |
701 | expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); | | 701 | expr_derive_type(tn->tn_type->t_subt, PTR), tn, NULL); |
702 | } | | 702 | } |
703 | | | 703 | |
704 | /* | | 704 | /* |
705 | * Expression of type function (function with return value of type T) | | 705 | * Expression of type function (function with return value of type T) |
706 | * in rvalue-expression (pointer to function with return value | | 706 | * in rvalue-expression (pointer to function with return value |
707 | * of type T) | | 707 | * of type T) |
708 | */ | | 708 | */ |
709 | if (tn->tn_type->t_tspec == FUNC) | | 709 | if (tn->tn_type->t_tspec == FUNC) |
710 | tn = build_address(tn, true); | | 710 | tn = build_address(tn, true); |
711 | | | 711 | |
| @@ -764,44 +764,44 @@ is_typeok_bool_operand(const tnode_t *tn | | | @@ -764,44 +764,44 @@ is_typeok_bool_operand(const tnode_t *tn |
764 | tn->tn_left->tn_left->tn_type->t_tspec == ENUM && | | 764 | tn->tn_left->tn_left->tn_type->t_tspec == ENUM && |
765 | /* | | 765 | /* |
766 | * XXX: Somehow the type information got lost here. The type | | 766 | * XXX: Somehow the type information got lost here. The type |
767 | * of the enum constant on the right-hand side should still be | | 767 | * of the enum constant on the right-hand side should still be |
768 | * ENUM, but is INT. | | 768 | * ENUM, but is INT. |
769 | */ | | 769 | */ |
770 | tn->tn_right->tn_type->t_tspec == INT) | | 770 | tn->tn_right->tn_type->t_tspec == INT) |
771 | return true; | | 771 | return true; |
772 | | | 772 | |
773 | return false; | | 773 | return false; |
774 | } | | 774 | } |
775 | | | 775 | |
776 | static bool | | 776 | static bool |
777 | typeok_incdec(const mod_t *mp, const tnode_t *tn, const type_t *tp) | | 777 | typeok_incdec(op_t op, const tnode_t *tn, const type_t *tp) |
778 | { | | 778 | { |
779 | /* operand has scalar type (checked in typeok) */ | | 779 | /* operand has scalar type (checked in typeok) */ |
780 | if (!tn->tn_lvalue) { | | 780 | if (!tn->tn_lvalue) { |
781 | if (tn->tn_op == CVT && tn->tn_cast && | | 781 | if (tn->tn_op == CVT && tn->tn_cast && |
782 | tn->tn_left->tn_op == LOAD) { | | 782 | tn->tn_left->tn_op == LOAD) { |
783 | if (tn->tn_type->t_tspec == PTR) | | 783 | if (tn->tn_type->t_tspec == PTR) |
784 | return true; | | 784 | return true; |
785 | /* a cast does not yield an lvalue */ | | 785 | /* a cast does not yield an lvalue */ |
786 | error(163); | | 786 | error(163); |
787 | } | | 787 | } |
788 | /* %soperand of '%s' must be lvalue */ | | 788 | /* %soperand of '%s' must be lvalue */ |
789 | error(114, "", mp->m_name); | | 789 | error(114, "", op_name(op)); |
790 | return false; | | 790 | return false; |
791 | } else if (tp->t_const) { | | 791 | } else if (tp->t_const) { |
792 | if (!tflag) | | 792 | if (!tflag) |
793 | /* %soperand of '%s' must be modifiable lvalue */ | | 793 | /* %soperand of '%s' must be modifiable lvalue */ |
794 | warning(115, "", mp->m_name); | | 794 | warning(115, "", op_name(op)); |
795 | } | | 795 | } |
796 | return true; | | 796 | return true; |
797 | } | | 797 | } |
798 | | | 798 | |
799 | static bool | | 799 | static bool |
800 | typeok_address(const mod_t *mp, | | 800 | typeok_address(const mod_t *mp, |
801 | const tnode_t *tn, const type_t *tp, tspec_t t) | | 801 | const tnode_t *tn, const type_t *tp, tspec_t t) |
802 | { | | 802 | { |
803 | if (t == ARRAY || t == FUNC) { | | 803 | if (t == ARRAY || t == FUNC) { |
804 | /* ok, a warning comes later (in build_address()) */ | | 804 | /* ok, a warning comes later (in build_address()) */ |
805 | } else if (!tn->tn_lvalue) { | | 805 | } else if (!tn->tn_lvalue) { |
806 | if (tn->tn_op == CVT && tn->tn_cast && | | 806 | if (tn->tn_op == CVT && tn->tn_cast && |
807 | tn->tn_left->tn_op == LOAD) { | | 807 | tn->tn_left->tn_op == LOAD) { |
| @@ -1324,27 +1324,27 @@ typeok_op(op_t op, const mod_t *mp, int | | | @@ -1324,27 +1324,27 @@ typeok_op(op_t op, const mod_t *mp, int |
1324 | case ARROW: | | 1324 | case ARROW: |
1325 | if (lt != PTR && !(tflag && is_integer(lt))) { | | 1325 | if (lt != PTR && !(tflag && is_integer(lt))) { |
1326 | /* Without tflag we got already an error */ | | 1326 | /* Without tflag we got already an error */ |
1327 | if (tflag) | | 1327 | if (tflag) |
1328 | /* unacceptable operand of '%s' */ | | 1328 | /* unacceptable operand of '%s' */ |
1329 | error(111, mp->m_name); | | 1329 | error(111, mp->m_name); |
1330 | return false; | | 1330 | return false; |
1331 | } | | 1331 | } |
1332 | break; | | 1332 | break; |
1333 | case INCAFT: | | 1333 | case INCAFT: |
1334 | case DECAFT: | | 1334 | case DECAFT: |
1335 | case INCBEF: | | 1335 | case INCBEF: |
1336 | case DECBEF: | | 1336 | case DECBEF: |
1337 | if (!typeok_incdec(mp, ln, ltp)) | | 1337 | if (!typeok_incdec(op, ln, ltp)) |
1338 | return false; | | 1338 | return false; |
1339 | break; | | 1339 | break; |
1340 | case ADDR: | | 1340 | case ADDR: |
1341 | if (!typeok_address(mp, ln, ltp, lt)) | | 1341 | if (!typeok_address(mp, ln, ltp, lt)) |
1342 | return false; | | 1342 | return false; |
1343 | break; | | 1343 | break; |
1344 | case INDIR: | | 1344 | case INDIR: |
1345 | if (!typeok_star(lt)) | | 1345 | if (!typeok_star(lt)) |
1346 | return false; | | 1346 | return false; |
1347 | break; | | 1347 | break; |
1348 | case PLUS: | | 1348 | case PLUS: |
1349 | if (!typeok_plus(op, ltp, lt, rtp, rt)) | | 1349 | if (!typeok_plus(op, ltp, lt, rtp, rt)) |
1350 | return false; | | 1350 | return false; |
| @@ -2867,27 +2867,27 @@ build_colon(tnode_t *ln, tnode_t *rn) | | | @@ -2867,27 +2867,27 @@ build_colon(tnode_t *ln, tnode_t *rn) |
2867 | */ | | 2867 | */ |
2868 | if (is_arithmetic(lt) && is_arithmetic(rt)) { | | 2868 | if (is_arithmetic(lt) && is_arithmetic(rt)) { |
2869 | rtp = ln->tn_type; | | 2869 | rtp = ln->tn_type; |
2870 | } else if (lt == BOOL && rt == BOOL) { | | 2870 | } else if (lt == BOOL && rt == BOOL) { |
2871 | rtp = ln->tn_type; | | 2871 | rtp = ln->tn_type; |
2872 | } else if (lt == VOID || rt == VOID) { | | 2872 | } else if (lt == VOID || rt == VOID) { |
2873 | rtp = gettyp(VOID); | | 2873 | rtp = gettyp(VOID); |
2874 | } else if (lt == STRUCT || lt == UNION) { | | 2874 | } else if (lt == STRUCT || lt == UNION) { |
2875 | /* Both types must be identical. */ | | 2875 | /* Both types must be identical. */ |
2876 | lint_assert(rt == STRUCT || rt == UNION); | | 2876 | lint_assert(rt == STRUCT || rt == UNION); |
2877 | lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); | | 2877 | lint_assert(ln->tn_type->t_str == rn->tn_type->t_str); |
2878 | if (is_incomplete(ln->tn_type)) { | | 2878 | if (is_incomplete(ln->tn_type)) { |
2879 | /* unknown operand size, op %s */ | | 2879 | /* unknown operand size, op %s */ |
2880 | error(138, modtab[COLON].m_name); | | 2880 | error(138, op_name(COLON)); |
2881 | return NULL; | | 2881 | return NULL; |
2882 | } | | 2882 | } |
2883 | rtp = ln->tn_type; | | 2883 | rtp = ln->tn_type; |
2884 | } else if (lt == PTR && is_integer(rt)) { | | 2884 | } else if (lt == PTR && is_integer(rt)) { |
2885 | if (rt != pdt) { | | 2885 | if (rt != pdt) { |
2886 | rn = convert(NOOP, 0, gettyp(pdt), rn); | | 2886 | rn = convert(NOOP, 0, gettyp(pdt), rn); |
2887 | rt = pdt; | | 2887 | rt = pdt; |
2888 | } | | 2888 | } |
2889 | rtp = ln->tn_type; | | 2889 | rtp = ln->tn_type; |
2890 | } else if (rt == PTR && is_integer(lt)) { | | 2890 | } else if (rt == PTR && is_integer(lt)) { |
2891 | if (lt != pdt) { | | 2891 | if (lt != pdt) { |
2892 | ln = convert(NOOP, 0, gettyp(pdt), ln); | | 2892 | ln = convert(NOOP, 0, gettyp(pdt), ln); |
2893 | lt = pdt; | | 2893 | lt = pdt; |
| @@ -3173,27 +3173,27 @@ fold(tnode_t *tn) | | | @@ -3173,27 +3173,27 @@ fold(tnode_t *tn) |
3173 | break; | | 3173 | break; |
3174 | case BITOR: | | 3174 | case BITOR: |
3175 | q = utyp ? (int64_t)(ul | ur) : sl | sr; | | 3175 | q = utyp ? (int64_t)(ul | ur) : sl | sr; |
3176 | break; | | 3176 | break; |
3177 | default: | | 3177 | default: |
3178 | lint_assert(/*CONSTCOND*/false); | | 3178 | lint_assert(/*CONSTCOND*/false); |
3179 | } | | 3179 | } |
3180 | | | 3180 | |
3181 | /* XXX does not work for quads. */ | | 3181 | /* XXX does not work for quads. */ |
3182 | if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && | | 3182 | if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && |
3183 | (q & ~mask) != 0)) { | | 3183 | (q & ~mask) != 0)) { |
3184 | if (hflag) | | 3184 | if (hflag) |
3185 | /* integer overflow detected, op %s */ | | 3185 | /* integer overflow detected, op %s */ |
3186 | warning(141, modtab[tn->tn_op].m_name); | | 3186 | warning(141, op_name(tn->tn_op)); |
3187 | } | | 3187 | } |
3188 | | | 3188 | |
3189 | v->v_quad = xsign(q, t, -1); | | 3189 | v->v_quad = xsign(q, t, -1); |
3190 | | | 3190 | |
3191 | cn = expr_new_constant(tn->tn_type, v); | | 3191 | cn = expr_new_constant(tn->tn_type, v); |
3192 | if (tn->tn_left->tn_system_dependent) | | 3192 | if (tn->tn_left->tn_system_dependent) |
3193 | cn->tn_system_dependent = true; | | 3193 | cn->tn_system_dependent = true; |
3194 | if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent) | | 3194 | if (modtab[tn->tn_op].m_binary && tn->tn_right->tn_system_dependent) |
3195 | cn->tn_system_dependent = true; | | 3195 | cn->tn_system_dependent = true; |
3196 | | | 3196 | |
3197 | return cn; | | 3197 | return cn; |
3198 | } | | 3198 | } |
3199 | | | 3199 | |
| @@ -3307,27 +3307,27 @@ fold_float(tnode_t *tn) | | | @@ -3307,27 +3307,27 @@ fold_float(tnode_t *tn) |
3307 | v->v_quad = l != r ? 1 : 0; | | 3307 | v->v_quad = l != r ? 1 : 0; |
3308 | break; | | 3308 | break; |
3309 | default: | | 3309 | default: |
3310 | lint_assert(/*CONSTCOND*/false); | | 3310 | lint_assert(/*CONSTCOND*/false); |
3311 | } | | 3311 | } |
3312 | | | 3312 | |
3313 | lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == 0); | | 3313 | lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == 0); |
3314 | if (fpe != 0 || finite((double)v->v_ldbl) == 0 || | | 3314 | if (fpe != 0 || finite((double)v->v_ldbl) == 0 || |
3315 | (t == FLOAT && | | 3315 | (t == FLOAT && |
3316 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || | | 3316 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || |
3317 | (t == DOUBLE && | | 3317 | (t == DOUBLE && |
3318 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { | | 3318 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { |
3319 | /* floating point overflow detected, op %s */ | | 3319 | /* floating point overflow detected, op %s */ |
3320 | warning(142, modtab[tn->tn_op].m_name); | | 3320 | warning(142, op_name(tn->tn_op)); |
3321 | if (t == FLOAT) { | | 3321 | if (t == FLOAT) { |
3322 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; | | 3322 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; |
3323 | } else if (t == DOUBLE) { | | 3323 | } else if (t == DOUBLE) { |
3324 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; | | 3324 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; |
3325 | } else { | | 3325 | } else { |
3326 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; | | 3326 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; |
3327 | } | | 3327 | } |
3328 | fpe = 0; | | 3328 | fpe = 0; |
3329 | } | | 3329 | } |
3330 | | | 3330 | |
3331 | return expr_new_constant(tn->tn_type, v); | | 3331 | return expr_new_constant(tn->tn_type, v); |
3332 | } | | 3332 | } |
3333 | | | 3333 | |
| @@ -3868,27 +3868,27 @@ check_null_effect(const tnode_t *tn) | | | @@ -3868,27 +3868,27 @@ check_null_effect(const tnode_t *tn) |
3868 | /* | | 3868 | /* |
3869 | * Dump an expression to stdout | | 3869 | * Dump an expression to stdout |
3870 | * only used for debugging | | 3870 | * only used for debugging |
3871 | */ | | 3871 | */ |
3872 | static void | | 3872 | static void |
3873 | display_expression(const tnode_t *tn, int offs) | | 3873 | display_expression(const tnode_t *tn, int offs) |
3874 | { | | 3874 | { |
3875 | uint64_t uq; | | 3875 | uint64_t uq; |
3876 | | | 3876 | |
3877 | if (tn == NULL) { | | 3877 | if (tn == NULL) { |
3878 | (void)printf("%*s%s\n", offs, "", "NULL"); | | 3878 | (void)printf("%*s%s\n", offs, "", "NULL"); |
3879 | return; | | 3879 | return; |
3880 | } | | 3880 | } |
3881 | (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); | | 3881 | (void)printf("%*sop %s ", offs, "", op_name(tn->tn_op)); |
3882 | | | 3882 | |
3883 | if (tn->tn_op == NAME) { | | 3883 | if (tn->tn_op == NAME) { |
3884 | (void)printf("%s: %s ", | | 3884 | (void)printf("%s: %s ", |
3885 | tn->tn_sym->s_name, | | 3885 | tn->tn_sym->s_name, |
3886 | storage_class_name(tn->tn_sym->s_scl)); | | 3886 | storage_class_name(tn->tn_sym->s_scl)); |
3887 | } else if (tn->tn_op == CON && is_floating(tn->tn_type->t_tspec)) { | | 3887 | } else if (tn->tn_op == CON && is_floating(tn->tn_type->t_tspec)) { |
3888 | (void)printf("%#g ", (double)tn->tn_val->v_ldbl); | | 3888 | (void)printf("%#g ", (double)tn->tn_val->v_ldbl); |
3889 | } else if (tn->tn_op == CON && is_integer(tn->tn_type->t_tspec)) { | | 3889 | } else if (tn->tn_op == CON && is_integer(tn->tn_type->t_tspec)) { |
3890 | uq = tn->tn_val->v_quad; | | 3890 | uq = tn->tn_val->v_quad; |
3891 | (void)printf("0x %08lx %08lx ", | | 3891 | (void)printf("0x %08lx %08lx ", |
3892 | (long)(uq >> 32) & 0xffffffffl, | | 3892 | (long)(uq >> 32) & 0xffffffffl, |
3893 | (long)uq & 0xffffffffl); | | 3893 | (long)uq & 0xffffffffl); |
3894 | } else if (tn->tn_op == CON) { | | 3894 | } else if (tn->tn_op == CON) { |
| @@ -4163,73 +4163,71 @@ check_array_index(tnode_t *tn, bool ampe | | | @@ -4163,73 +4163,71 @@ check_array_index(tnode_t *tn, bool ampe |
4163 | } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { | | 4163 | } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { |
4164 | /* array subscript cannot be > %d: %ld */ | | 4164 | /* array subscript cannot be > %d: %ld */ |
4165 | warning(168, dim - 1, (long)con); | | 4165 | warning(168, dim - 1, (long)con); |
4166 | } | | 4166 | } |
4167 | } | | 4167 | } |
4168 | | | 4168 | |
4169 | /* | | 4169 | /* |
4170 | * Check for ordered comparisons of unsigned values with 0. | | 4170 | * Check for ordered comparisons of unsigned values with 0. |
4171 | */ | | 4171 | */ |
4172 | static void | | 4172 | static void |
4173 | check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) | | 4173 | check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) |
4174 | { | | 4174 | { |
4175 | tspec_t lt, rt; | | 4175 | tspec_t lt, rt; |
4176 | const mod_t *mp; | | | |
4177 | | | 4176 | |
4178 | lt = ln->tn_type->t_tspec; | | 4177 | lt = ln->tn_type->t_tspec; |
4179 | rt = rn->tn_type->t_tspec; | | 4178 | rt = rn->tn_type->t_tspec; |
4180 | mp = &modtab[op]; | | | |
4181 | | | 4179 | |
4182 | if (ln->tn_op != CON && rn->tn_op != CON) | | 4180 | if (ln->tn_op != CON && rn->tn_op != CON) |
4183 | return; | | 4181 | return; |
4184 | | | 4182 | |
4185 | if (!is_integer(lt) || !is_integer(rt)) | | 4183 | if (!is_integer(lt) || !is_integer(rt)) |
4186 | return; | | 4184 | return; |
4187 | | | 4185 | |
4188 | if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && | | 4186 | if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && |
4189 | (rn->tn_val->v_quad < 0 || | | 4187 | (rn->tn_val->v_quad < 0 || |
4190 | rn->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { | | 4188 | rn->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { |
4191 | /* nonportable character comparison, op %s */ | | 4189 | /* nonportable character comparison, op %s */ |
4192 | warning(230, mp->m_name); | | 4190 | warning(230, op_name(op)); |
4193 | return; | | 4191 | return; |
4194 | } | | 4192 | } |
4195 | if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && | | 4193 | if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && |
4196 | (ln->tn_val->v_quad < 0 || | | 4194 | (ln->tn_val->v_quad < 0 || |
4197 | ln->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { | | 4195 | ln->tn_val->v_quad > (int)~(~0U << (CHAR_SIZE - 1)))) { |
4198 | /* nonportable character comparison, op %s */ | | 4196 | /* nonportable character comparison, op %s */ |
4199 | warning(230, mp->m_name); | | 4197 | warning(230, op_name(op)); |
4200 | return; | | 4198 | return; |
4201 | } | | 4199 | } |
4202 | if (is_uinteger(lt) && !is_uinteger(rt) && | | 4200 | if (is_uinteger(lt) && !is_uinteger(rt) && |
4203 | rn->tn_op == CON && rn->tn_val->v_quad <= 0) { | | 4201 | rn->tn_op == CON && rn->tn_val->v_quad <= 0) { |
4204 | if (rn->tn_val->v_quad < 0) { | | 4202 | if (rn->tn_val->v_quad < 0) { |
4205 | /* comparison of %s with %s, op %s */ | | 4203 | /* comparison of %s with %s, op %s */ |
4206 | warning(162, type_name(ln->tn_type), | | 4204 | warning(162, type_name(ln->tn_type), |
4207 | "negative constant", mp->m_name); | | 4205 | "negative constant", op_name(op)); |
4208 | } else if (op == LT || op == GE || (hflag && op == LE)) { | | 4206 | } else if (op == LT || op == GE || (hflag && op == LE)) { |
4209 | /* comparison of %s with %s, op %s */ | | 4207 | /* comparison of %s with %s, op %s */ |
4210 | warning(162, type_name(ln->tn_type), "0", mp->m_name); | | 4208 | warning(162, type_name(ln->tn_type), "0", op_name(op)); |
4211 | } | | 4209 | } |
4212 | return; | | 4210 | return; |
4213 | } | | 4211 | } |
4214 | if (is_uinteger(rt) && !is_uinteger(lt) && | | 4212 | if (is_uinteger(rt) && !is_uinteger(lt) && |
4215 | ln->tn_op == CON && ln->tn_val->v_quad <= 0) { | | 4213 | ln->tn_op == CON && ln->tn_val->v_quad <= 0) { |
4216 | if (ln->tn_val->v_quad < 0) { | | 4214 | if (ln->tn_val->v_quad < 0) { |
4217 | /* comparison of %s with %s, op %s */ | | 4215 | /* comparison of %s with %s, op %s */ |
4218 | warning(162, "negative constant", | | 4216 | warning(162, "negative constant", |
4219 | type_name(rn->tn_type), mp->m_name); | | 4217 | type_name(rn->tn_type), op_name(op)); |
4220 | } else if (op == GT || op == LE || (hflag && op == GE)) { | | 4218 | } else if (op == GT || op == LE || (hflag && op == GE)) { |
4221 | /* comparison of %s with %s, op %s */ | | 4219 | /* comparison of %s with %s, op %s */ |
4222 | warning(162, "0", type_name(rn->tn_type), mp->m_name); | | 4220 | warning(162, "0", type_name(rn->tn_type), op_name(op)); |
4223 | } | | 4221 | } |
4224 | return; | | 4222 | return; |
4225 | } | | 4223 | } |
4226 | } | | 4224 | } |
4227 | | | 4225 | |
4228 | /* | | 4226 | /* |
4229 | * Return whether the expression can be used for static initialization. | | 4227 | * Return whether the expression can be used for static initialization. |
4230 | * | | 4228 | * |
4231 | * Constant initialization expressions must be constant or an address | | 4229 | * Constant initialization expressions must be constant or an address |
4232 | * of a static object with an optional offset. In the first case, | | 4230 | * of a static object with an optional offset. In the first case, |
4233 | * the result is returned in *offsp. In the second case, the static | | 4231 | * the result is returned in *offsp. In the second case, the static |
4234 | * object is returned in *symp and the offset in *offsp. | | 4232 | * object is returned in *symp and the offset in *offsp. |
4235 | * | | 4233 | * |