mirror of
https://github.com/frida/tinycc
synced 2024-12-24 05:56:49 +03:00
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.
This commit is contained in:
parent
3877618785
commit
4a70b2bc2d
9
tccgen.c
9
tccgen.c
@ -53,6 +53,7 @@ static SValue _vstack[1 + VSTACK_SIZE];
|
||||
|
||||
ST_DATA int const_wanted; /* true if constant wanted */
|
||||
ST_DATA int nocode_wanted; /* no code generation wanted */
|
||||
#define unevalmask 0xffff /* unevaluated subexpression */
|
||||
#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
|
||||
#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
|
||||
|
||||
@ -2273,7 +2274,7 @@ static void gen_opic(int op)
|
||||
case TOK_UMOD:
|
||||
/* if division by zero, generate explicit division */
|
||||
if (l2 == 0) {
|
||||
if (const_wanted)
|
||||
if (const_wanted && !(nocode_wanted & unevalmask))
|
||||
tcc_error("division by zero in constant");
|
||||
goto general_case;
|
||||
}
|
||||
@ -5104,7 +5105,7 @@ ST_FUNC void unary(void)
|
||||
}
|
||||
} else if (tok == '{') {
|
||||
int saved_nocode_wanted = nocode_wanted;
|
||||
if (const_wanted)
|
||||
if (const_wanted && !(nocode_wanted & unevalmask))
|
||||
tcc_error("expected constant");
|
||||
/* save all registers */
|
||||
save_regs(0);
|
||||
@ -6152,9 +6153,9 @@ ST_FUNC void gexpr(void)
|
||||
static void expr_const1(void)
|
||||
{
|
||||
const_wanted++;
|
||||
nocode_wanted++;
|
||||
nocode_wanted += unevalmask + 1;
|
||||
expr_cond();
|
||||
nocode_wanted--;
|
||||
nocode_wanted -= unevalmask + 1;
|
||||
const_wanted--;
|
||||
}
|
||||
|
||||
|
@ -950,6 +950,8 @@ void expr2_test()
|
||||
printf("res= %d %d\n", a, b);
|
||||
}
|
||||
|
||||
int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
|
||||
|
||||
void constant_expr_test()
|
||||
{
|
||||
int a;
|
||||
@ -958,6 +960,7 @@ void constant_expr_test()
|
||||
printf("%d\n", a * 16);
|
||||
printf("%d\n", a * 1);
|
||||
printf("%d\n", a + 0);
|
||||
printf("%d\n", sizeof(const_len_ar));
|
||||
}
|
||||
|
||||
int tab4[10];
|
||||
@ -1845,6 +1848,8 @@ arrtype2 sinit22 = {5,6,7};
|
||||
int sinit23[2] = { "astring" ? sizeof("astring") : -1,
|
||||
&sinit23 ? 42 : -1 };
|
||||
|
||||
int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
|
||||
|
||||
extern int external_inited = 42;
|
||||
|
||||
void init_test(void)
|
||||
@ -1959,6 +1964,7 @@ void init_test(void)
|
||||
printf("arrtype6: %d\n", sizeof(arrtype2));
|
||||
|
||||
printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
|
||||
printf("sinit24=%d\n", sinit24);
|
||||
printf("linit18= %d %d\n", linit18[0], linit18[1]);
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,10 @@ int ga = 0.42 { 2 };
|
||||
struct S { int a, b; };
|
||||
struct T { struct S x; };
|
||||
struct T gt = { 42 a: 1, 43 };
|
||||
#elif defined test_invalid_4
|
||||
enum E {
|
||||
x = 1 / 0
|
||||
};
|
||||
#elif defined test_conflicting_types
|
||||
int i;
|
||||
void foo(void) {
|
||||
|
@ -72,37 +72,40 @@
|
||||
[test_invalid_3]
|
||||
60_errors_and_warnings.c:153: error: ',' expected (got "a")
|
||||
|
||||
[test_invalid_4]
|
||||
60_errors_and_warnings.c:157: error: division by zero in constant
|
||||
|
||||
[test_conflicting_types]
|
||||
60_errors_and_warnings.c:159: error: incompatible types for redefinition of 'i'
|
||||
60_errors_and_warnings.c:163: error: incompatible types for redefinition of 'i'
|
||||
|
||||
[test_nested_types]
|
||||
60_errors_and_warnings.c:166: error: struct/union/enum already defined
|
||||
60_errors_and_warnings.c:170: error: struct/union/enum already defined
|
||||
|
||||
[test_vla_1]
|
||||
60_errors_and_warnings.c:173: error: need explicit inner array size in VLAs
|
||||
60_errors_and_warnings.c:177: error: need explicit inner array size in VLAs
|
||||
|
||||
[test_invalid_alignas]
|
||||
60_errors_and_warnings.c:177: error: identifier expected
|
||||
60_errors_and_warnings.c:181: error: identifier expected
|
||||
|
||||
[test_static_assert]
|
||||
60_errors_and_warnings.c:183: error: "ONE is not 1"
|
||||
60_errors_and_warnings.c:187: error: "ONE is not 1"
|
||||
|
||||
[test_void_array]
|
||||
60_errors_and_warnings.c:186: error: declaration of an array of incomplete type elements
|
||||
60_errors_and_warnings.c:190: error: declaration of an array of incomplete type elements
|
||||
|
||||
[test_incomplete_enum_array]
|
||||
60_errors_and_warnings.c:189: error: declaration of an array of incomplete type elements
|
||||
60_errors_and_warnings.c:193: error: declaration of an array of incomplete type elements
|
||||
|
||||
[test_incomplete_struct_array]
|
||||
60_errors_and_warnings.c:192: error: declaration of an array of incomplete type elements
|
||||
60_errors_and_warnings.c:196: error: declaration of an array of incomplete type elements
|
||||
|
||||
[test_const_fun_array]
|
||||
60_errors_and_warnings.c:196: error: declaration of an array of functions
|
||||
60_errors_and_warnings.c:200: error: declaration of an array of functions
|
||||
|
||||
[test_incomplete_array_array]
|
||||
|
||||
[test_extern_array]
|
||||
60_errors_and_warnings.c:212: error: incompatible types for redefinition of 'x'
|
||||
60_errors_and_warnings.c:216: error: incompatible types for redefinition of 'x'
|
||||
|
||||
[test_func_1]
|
||||
hello: a = 123
|
||||
@ -111,17 +114,17 @@ hello: a = 123
|
||||
hello: a = 123
|
||||
|
||||
[test_func_3]
|
||||
60_errors_and_warnings.c:242: warning: static storage ignored for redefinition of 'hello'
|
||||
60_errors_and_warnings.c:246: warning: static storage ignored for redefinition of 'hello'
|
||||
hello: a = 123
|
||||
|
||||
[test_func_4]
|
||||
hello: a = 123
|
||||
|
||||
[test_func_5]
|
||||
60_errors_and_warnings.c:242: error: incompatible types for redefinition of 'hello'
|
||||
60_errors_and_warnings.c:246: error: incompatible types for redefinition of 'hello'
|
||||
|
||||
[test_func_6]
|
||||
60_errors_and_warnings.c:230: error: function without file scope cannot be static
|
||||
60_errors_and_warnings.c:234: error: function without file scope cannot be static
|
||||
|
||||
[test_var_1]
|
||||
main : 1 ; 1
|
||||
@ -134,6 +137,6 @@ main : 2 ; 2
|
||||
bar : 3 ; 3
|
||||
|
||||
[test_var_3]
|
||||
60_errors_and_warnings.c:274: error: incompatible types for redefinition of 'xxx'
|
||||
60_errors_and_warnings.c:278: error: incompatible types for redefinition of 'xxx'
|
||||
|
||||
[test_var_4]
|
||||
|
Loading…
Reference in New Issue
Block a user