History

Fix conversion in a?0:ptr.

(cond ? 0 : ptr)->member wasn't handled correctly. If one arm is a null pointer constant (which also can be a pointer) the result type is that of the other arm.

Michael Matz committed 14 years ago

Commit 6471ec01 parent f98c2302 files · +27 −5Browse files

Unified · Split

2 files
  1. tccgen.c +14 −5
  2. tests/tcctest.c +13 −0
tccgen.c+14−5
@@ -1489,7 +1489,8 @@ static inline int is_null_pointer(SValue *p) · 1488 unmodified lines
1489 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1489 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1490 return 0;1490 return 0;
1491 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||1491 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1492 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);1492 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1493 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1493}1494}
1494 1495
1495static inline int is_integer_btype(int bt)1496static inline int is_integer_btype(int bt)
@@ -4116,14 +4117,22 @@ static void expr_cond(void) · 2620 unmodified lines
4116 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))4117 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4117 type.t |= VT_UNSIGNED;4118 type.t |= VT_UNSIGNED;
4118 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {4119 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4119 /* XXX: test pointer compatibility */4120 /* If one is a null ptr constant the result type
4120 type = type1;4121 is the other. */
4122 if (is_null_pointer (vtop))
4123 type = type1;
4124 else if (is_null_pointer (&sv))
4125 type = type2;
4126 /* XXX: test pointer compatibility, C99 has more elaborate
4127 rules here. */
4128 else
4129 type = type1;
4121 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {4130 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4122 /* XXX: test function pointer compatibility */4131 /* XXX: test function pointer compatibility */
4123 type = type1;4132 type = bt1 == VT_FUNC ? type1 : type2;
4124 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {4133 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4125 /* XXX: test structure compatibility */4134 /* XXX: test structure compatibility */
4126 type = type1;4135 type = bt1 == VT_STRUCT ? type1 : type2;
4127 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {4136 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4128 /* NOTE: as an extension, we accept void on only one side */4137 /* NOTE: as an extension, we accept void on only one side */
4129 type.t = VT_VOID;4138 type.t = VT_VOID;
tests/tcctest.c+13−0
@@ -2486,3 +2486,16 @@ void const_warn_test(void) · 2485 unmodified lines
2486{2486{
2487 const_func(1);2487 const_func(1);
2488}2488}
2489
2490struct condstruct {
2491 int i;
2492};
2493
2494int getme (struct condstruct *s, int i)
2495{
2496 int i1 = (i == 0 ? 0 : s)->i;
2497 int i2 = (i == 0 ? s : 0)->i;
2498 int i3 = (i == 0 ? (void*)0 : s)->i;
2499 int i4 = (i == 0 ? s : (void*)0)->i;
2500 return i1 + i2 + i3 + i4;
2501}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t