aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2012-04-14 23:50:21 +0200
committerMichael Matz <matz@suse.de>2012-04-18 20:57:13 +0200
commit6471ec0a2bd523edd4bbc79277a33d0b853940fa (patch)
tree5a907084e0d9dc696d481e6380a53d893aad131c /tccgen.c
parentf98c2306a0857ad3f8800f91e0554a27adc7f675 (diff)
downloadtinycc-6471ec0a2bd523edd4bbc79277a33d0b853940fa.tar.gz
tinycc-6471ec0a2bd523edd4bbc79277a33d0b853940fa.tar.bz2
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.
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/tccgen.c b/tccgen.c
index 5aa21c6..b0cec4a 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -1489,7 +1489,8 @@ static inline int is_null_pointer(SValue *p)
if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
return 0;
return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
- ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
+ ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
+ ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
}
static inline int is_integer_btype(int bt)
@@ -4116,14 +4117,22 @@ static void expr_cond(void)
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
type.t |= VT_UNSIGNED;
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
- /* XXX: test pointer compatibility */
- type = type1;
+ /* If one is a null ptr constant the result type
+ is the other. */
+ if (is_null_pointer (vtop))
+ type = type1;
+ else if (is_null_pointer (&sv))
+ type = type2;
+ /* XXX: test pointer compatibility, C99 has more elaborate
+ rules here. */
+ else
+ type = type1;
} else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
/* XXX: test function pointer compatibility */
- type = type1;
+ type = bt1 == VT_FUNC ? type1 : type2;
} else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
/* XXX: test structure compatibility */
- type = type1;
+ type = bt1 == VT_STRUCT ? type1 : type2;
} else if (bt1 == VT_VOID || bt2 == VT_VOID) {
/* NOTE: as an extension, we accept void on only one side */
type.t = VT_VOID;