History

Fix incorrect one-sided void handling in ?:

Also make the case when one side in ?: is a ptr and the other is neither a ptr nor a null-ptr constant fail cleanly instead of segfaulting.

Petr Skocik committed 7 years ago

Commit f7779ef1 parent 49dfb572 files · +26 −20Browse files

Unified · Split

2 files
  1. tccgen.c +8 −6
  2. tests/tests2/33_ternary_op.c +18 −14
tccgen.c+8−6
@@ -5598,7 +5598,9 @@ static void expr_cond(void) · 5597 unmodified lines
5598 5598
5599 5599
5600 /* cast operands to correct type according to ISOC rules */5600 /* cast operands to correct type according to ISOC rules */
5601 if (is_float(bt1) || is_float(bt2)) {5601 if (bt1 == VT_VOID || bt2 == VT_VOID) {
5602 type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */
5603 }else if (is_float(bt1) || is_float(bt2)) {
5602 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {5604 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5603 type.t = VT_LDOUBLE;5605 type.t = VT_LDOUBLE;
5604 5606
@@ -5625,8 +5627,11 @@ static void expr_cond(void) · 20 unmodified lines
5625 if (is_null_pointer (vtop)) type = type1;5627 if (is_null_pointer (vtop)) type = type1;
5626 else if (is_null_pointer (&sv)) type = type2;5628 else if (is_null_pointer (&sv)) type = type2;
5627 else{5629 else{
5628 int pbt1 = (pointed_type(&type1)->t&VT_BTYPE);5630 int pbt1, pbt2;
5629 int pbt2 = (pointed_type(&type2)->t&VT_BTYPE);5631 if (bt1!=bt2)
5632 tcc_error("incompatible types in conditional expressions");
5633 pbt1 = (pointed_type(&type1)->t&VT_BTYPE);
5634 pbt2 = (pointed_type(&type2)->t&VT_BTYPE);
5630 /*pointers to void get preferred, otherwise the pointed to types minus qualifs should be compatible*/5635 /*pointers to void get preferred, otherwise the pointed to types minus qualifs should be compatible*/
5631 type = (pbt1==VT_VOID) ? type1 : type2;5636 type = (pbt1==VT_VOID) ? type1 : type2;
5632 if (pbt1!=VT_VOID && pbt2!=VT_VOID){5637 if (pbt1!=VT_VOID && pbt2!=VT_VOID){
@@ -5652,9 +5657,6 @@ static void expr_cond(void) · 19 unmodified lines
5652 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {5657 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5653 /* XXX: test structure compatibility */5658 /* XXX: test structure compatibility */
5654 type = bt1 == VT_STRUCT ? type1 : type2;5659 type = bt1 == VT_STRUCT ? type1 : type2;
5655 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
5656 /* NOTE: as an extension, we accept void on only one side */
5657 type.t = VT_VOID;
5658 } else {5660 } else {
5659 /* integer operations */5661 /* integer operations */
5660 type.t = VT_INT | (VT_LONG & (t1 | t2));5662 type.t = VT_INT | (VT_LONG & (t1 | t2));
tests/tests2/33_ternary_op.c+18−14
@@ -6,20 +6,24 @@ static void f (void){} · 5 unmodified lines
6void (*fp)(void) = f;6void (*fp)(void) = f;
7void call_fp()7void call_fp()
8{8{
9 (fp?f:f)();9 (fp?f:f)();
10 (fp?fp:fp)();10 (fp?fp:fp)();
11 (fp?fp:&f)();11 (fp?fp:&f)();
12 (fp?&f:fp)();12 (fp?&f:fp)();
13 (fp?&f:&f)();13 (fp?&f:&f)();
14 _Generic(0?arr:arr, char*: (void)0);14 _Generic(0?arr:arr, char*: (void)0);
15 _Generic(0?&arr[0]:arr, char*: (void)0);15 _Generic(0?&arr[0]:arr, char*: (void)0);
16 _Generic(0?arr:&arr[0], char*: (void)0);16 _Generic(0?arr:&arr[0], char*: (void)0);
17 _Generic(1?arr:arr, char*: (void)0);17 _Generic(1?arr:arr, char*: (void)0);
18 _Generic(1?&arr[0]:arr, char*: (void)0);18 _Generic(1?&arr[0]:arr, char*: (void)0);
19 _Generic(1?arr:&arr[0], char*: (void)0);19 _Generic(1?arr:&arr[0], char*: (void)0);
20 _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0);20 _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0);
21 (fp?&f:f)();21 (fp?&f:f)();
22 (fp?f:&f)();22 (fp?f:&f)();
23 _Generic((__typeof(fp?0L:(void)0)*){0}, void*: (void)0);
24
25 //Should cleanly fail, not segfault:
26 /*(fp?f:1);*/
23}27}
24 28
25int main()29int main()

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