History

Fix handling of unevaluated subexpression of const

we were emitting error messages for something like 'static int i = 2 || 1/0', even though the exception would be in the unevaluated part. This doesn't destroy const-ness, so we must accept it. This requires splitting the nocode_wanted values a bit more, so that nocode_wanted due to const_wanted can be differentiated from nocode_wanted due to non-evaluation.

Michael Matz committed 6 years ago

Commit 4a70b2b1 parent 38776184 files · +32 −18Browse files

Unified · Split

4 files
  1. tccgen.c +5 −4
  2. tests/tcctest.c +6 −0
  3. tests/tests2/60_errors_and_warnings.c +4 −0
  4. tests/tests2/60_errors_and_warnings.expect +17 −14
tccgen.c+5−4
@@ -53,6 +53,7 @@ static SValue _vstack[1 + VSTACK_SIZE]; · 52 unmodified lines
53 53
54ST_DATA int const_wanted; /* true if constant wanted */54ST_DATA int const_wanted; /* true if constant wanted */
55ST_DATA int nocode_wanted; /* no code generation wanted */55ST_DATA int nocode_wanted; /* no code generation wanted */
56#define unevalmask 0xffff /* unevaluated subexpression */
56#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */57#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
57#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */58#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
58 59
@@ -2273,7 +2274,7 @@ static void gen_opic(int op) · 2214 unmodified lines
2273 case TOK_UMOD:2274 case TOK_UMOD:
2274 /* if division by zero, generate explicit division */2275 /* if division by zero, generate explicit division */
2275 if (l2 == 0) {2276 if (l2 == 0) {
2276 if (const_wanted)2277 if (const_wanted && !(nocode_wanted & unevalmask))
2277 tcc_error("division by zero in constant");2278 tcc_error("division by zero in constant");
2278 goto general_case;2279 goto general_case;
2279 }2280 }
@@ -5104,7 +5105,7 @@ ST_FUNC void unary(void) · 2824 unmodified lines
5104 }5105 }
5105 } else if (tok == '{') {5106 } else if (tok == '{') {
5106 int saved_nocode_wanted = nocode_wanted;5107 int saved_nocode_wanted = nocode_wanted;
5107 if (const_wanted)5108 if (const_wanted && !(nocode_wanted & unevalmask))
5108 tcc_error("expected constant");5109 tcc_error("expected constant");
5109 /* save all registers */5110 /* save all registers */
5110 save_regs(0);5111 save_regs(0);
@@ -6152,9 +6153,9 @@ ST_FUNC void gexpr(void) · 1041 unmodified lines
6152static void expr_const1(void)6153static void expr_const1(void)
6153{6154{
6154 const_wanted++;6155 const_wanted++;
6155 nocode_wanted++;6156 nocode_wanted += unevalmask + 1;
6156 expr_cond();6157 expr_cond();
6157 nocode_wanted--;6158 nocode_wanted -= unevalmask + 1;
6158 const_wanted--;6159 const_wanted--;
6159}6160}
6160 6161
tests/tcctest.c+6−0
@@ -950,6 +950,8 @@ void expr2_test() · 949 unmodified lines
950 printf("res= %d %d\n", a, b);950 printf("res= %d %d\n", a, b);
951}951}
952 952
953int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
954
953void constant_expr_test()955void constant_expr_test()
954{956{
955 int a;957 int a;
@@ -958,6 +960,7 @@ void constant_expr_test() · 2 unmodified lines
958 printf("%d\n", a * 16);960 printf("%d\n", a * 16);
959 printf("%d\n", a * 1);961 printf("%d\n", a * 1);
960 printf("%d\n", a + 0);962 printf("%d\n", a + 0);
963 printf("%d\n", sizeof(const_len_ar));
961}964}
962 965
963int tab4[10];966int tab4[10];
@@ -1845,6 +1848,8 @@ arrtype2 sinit22 = {5,6,7}; · 881 unmodified lines
1845int sinit23[2] = { "astring" ? sizeof("astring") : -1,1848int sinit23[2] = { "astring" ? sizeof("astring") : -1,
1846 &sinit23 ? 42 : -1 };1849 &sinit23 ? 42 : -1 };
1847 1850
1851int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
1852
1848extern int external_inited = 42;1853extern int external_inited = 42;
1849 1854
1850void init_test(void)1855void init_test(void)
@@ -1959,6 +1964,7 @@ void init_test(void) · 108 unmodified lines
1959 printf("arrtype6: %d\n", sizeof(arrtype2));1964 printf("arrtype6: %d\n", sizeof(arrtype2));
1960 1965
1961 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);1966 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
1967 printf("sinit24=%d\n", sinit24);
1962 printf("linit18= %d %d\n", linit18[0], linit18[1]);1968 printf("linit18= %d %d\n", linit18[0], linit18[1]);
1963}1969}
1964 1970
tests/tests2/60_errors_and_warnings.c+4−0
@@ -151,6 +151,10 @@ int ga = 0.42 { 2 }; · 150 unmodified lines
151struct S { int a, b; };151struct S { int a, b; };
152struct T { struct S x; };152struct T { struct S x; };
153struct T gt = { 42 a: 1, 43 };153struct T gt = { 42 a: 1, 43 };
154#elif defined test_invalid_4
155enum E {
156 x = 1 / 0
157};
154#elif defined test_conflicting_types158#elif defined test_conflicting_types
155int i;159int i;
156void foo(void) {160void foo(void) {
tests/tests2/60_errors_and_warnings.expect+17−14
@@ -72,37 +72,40 @@ · 71 unmodified lines
72[test_invalid_3]72[test_invalid_3]
7360_errors_and_warnings.c:153: error: ',' expected (got "a")7360_errors_and_warnings.c:153: error: ',' expected (got "a")
74 74
75[test_invalid_4]
7660_errors_and_warnings.c:157: error: division by zero in constant
77
75[test_conflicting_types]78[test_conflicting_types]
7660_errors_and_warnings.c:159: error: incompatible types for redefinition of 'i'7960_errors_and_warnings.c:163: error: incompatible types for redefinition of 'i'
77 80
78[test_nested_types]81[test_nested_types]
7960_errors_and_warnings.c:166: error: struct/union/enum already defined8260_errors_and_warnings.c:170: error: struct/union/enum already defined
80 83
81[test_vla_1]84[test_vla_1]
8260_errors_and_warnings.c:173: error: need explicit inner array size in VLAs8560_errors_and_warnings.c:177: error: need explicit inner array size in VLAs
83 86
84[test_invalid_alignas]87[test_invalid_alignas]
8560_errors_and_warnings.c:177: error: identifier expected8860_errors_and_warnings.c:181: error: identifier expected
86 89
87[test_static_assert]90[test_static_assert]
8860_errors_and_warnings.c:183: error: "ONE is not 1"9160_errors_and_warnings.c:187: error: "ONE is not 1"
89 92
90[test_void_array]93[test_void_array]
9160_errors_and_warnings.c:186: error: declaration of an array of incomplete type elements9460_errors_and_warnings.c:190: error: declaration of an array of incomplete type elements
92 95
93[test_incomplete_enum_array]96[test_incomplete_enum_array]
9460_errors_and_warnings.c:189: error: declaration of an array of incomplete type elements9760_errors_and_warnings.c:193: error: declaration of an array of incomplete type elements
95 98
96[test_incomplete_struct_array]99[test_incomplete_struct_array]
9760_errors_and_warnings.c:192: error: declaration of an array of incomplete type elements10060_errors_and_warnings.c:196: error: declaration of an array of incomplete type elements
98 101
99[test_const_fun_array]102[test_const_fun_array]
10060_errors_and_warnings.c:196: error: declaration of an array of functions10360_errors_and_warnings.c:200: error: declaration of an array of functions
101 104
102[test_incomplete_array_array]105[test_incomplete_array_array]
103 106
104[test_extern_array]107[test_extern_array]
10560_errors_and_warnings.c:212: error: incompatible types for redefinition of 'x'10860_errors_and_warnings.c:216: error: incompatible types for redefinition of 'x'
106 109
107[test_func_1]110[test_func_1]
108hello: a = 123111hello: a = 123
@@ -111,17 +114,17 @@ hello: a = 123 · 2 unmodified lines
111hello: a = 123114hello: a = 123
112 115
113[test_func_3]116[test_func_3]
11460_errors_and_warnings.c:242: warning: static storage ignored for redefinition of 'hello'11760_errors_and_warnings.c:246: warning: static storage ignored for redefinition of 'hello'
115hello: a = 123118hello: a = 123
116 119
117[test_func_4]120[test_func_4]
118hello: a = 123121hello: a = 123
119 122
120[test_func_5]123[test_func_5]
12160_errors_and_warnings.c:242: error: incompatible types for redefinition of 'hello'12460_errors_and_warnings.c:246: error: incompatible types for redefinition of 'hello'
122 125
123[test_func_6]126[test_func_6]
12460_errors_and_warnings.c:230: error: function without file scope cannot be static12760_errors_and_warnings.c:234: error: function without file scope cannot be static
125 128
126[test_var_1]129[test_var_1]
127main : 1 ; 1130main : 1 ; 1
@@ -134,6 +137,6 @@ main : 2 ; 2 · 6 unmodified lines
134bar : 3 ; 3137bar : 3 ; 3
135 138
136[test_var_3]139[test_var_3]
13760_errors_and_warnings.c:274: error: incompatible types for redefinition of 'xxx'14060_errors_and_warnings.c:278: error: incompatible types for redefinition of 'xxx'
138 141
139[test_var_4]142[test_var_4]

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