2017-07-21 04:21:27 +08:00
|
|
|
#if defined test_56_btype_excess_1
|
|
|
|
struct A {} int i;
|
|
|
|
|
|
|
|
#elif defined test_57_btype_excess_2
|
|
|
|
char int i;
|
|
|
|
|
|
|
|
#elif defined test_58_function_redefinition
|
|
|
|
int f(void) { return 0; }
|
|
|
|
int f(void) { return 1; }
|
|
|
|
|
|
|
|
#elif defined test_global_redefinition
|
|
|
|
int xxx = 1;
|
|
|
|
int xxx;
|
|
|
|
int xxx = 2;
|
|
|
|
|
|
|
|
#elif defined test_59_function_array
|
|
|
|
int (*fct)[42](int x);
|
|
|
|
|
|
|
|
#elif defined test_60_enum_redefinition
|
|
|
|
enum color { RED, GREEN, BLUE };
|
|
|
|
enum color { R, G, B };
|
|
|
|
enum color c;
|
|
|
|
|
|
|
|
#elif defined test_62_enumerator_redefinition
|
|
|
|
enum color { RED, GREEN, BLUE };
|
|
|
|
enum rgb { RED, G, B};
|
|
|
|
enum color c = RED;
|
|
|
|
|
|
|
|
#elif defined test_63_local_enumerator_redefinition
|
|
|
|
enum {
|
|
|
|
FOO,
|
|
|
|
BAR
|
|
|
|
};
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
FOO = 2,
|
|
|
|
BAR
|
|
|
|
};
|
|
|
|
|
|
|
|
return BAR - FOO;
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined test_61_undefined_enum
|
|
|
|
enum rgb3 c = 42;
|
|
|
|
|
|
|
|
#elif defined test_74_non_const_init
|
|
|
|
int i = i++;
|
|
|
|
|
2018-06-01 05:52:07 +08:00
|
|
|
#elif defined test_pointer_assignment
|
|
|
|
|
|
|
|
void (*f1)(void);
|
|
|
|
void f2(void) {}
|
|
|
|
|
|
|
|
struct s1 *ps1;
|
|
|
|
struct s2 *ps2;
|
|
|
|
|
|
|
|
void *v1, **v2, ***v3;
|
|
|
|
|
|
|
|
enum e1 { a = 4 } e10, *e11, *e12;
|
|
|
|
enum e2 { b = -4 } e20, *e21;
|
|
|
|
enum e3 { c = 5000000000LL } e30;
|
|
|
|
|
|
|
|
int *ip;
|
|
|
|
unsigned int *up;
|
|
|
|
long *lp;
|
|
|
|
long long *llp;
|
|
|
|
|
|
|
|
char **c1;
|
|
|
|
char const **c2;
|
|
|
|
unsigned char **u1;
|
|
|
|
|
|
|
|
int no_main ()
|
|
|
|
{
|
|
|
|
// function
|
|
|
|
f1 = f2;
|
|
|
|
// struct
|
|
|
|
ps1 = ps2;
|
|
|
|
// void*
|
|
|
|
v1 = v3;
|
|
|
|
v2 = v3;
|
|
|
|
|
|
|
|
// enum
|
|
|
|
e11 = e12;
|
|
|
|
e11 = e21;
|
|
|
|
e11 = &e10;
|
|
|
|
ip = &e10;
|
|
|
|
ip = &e20;
|
|
|
|
up = &e10;
|
|
|
|
up = &e20;
|
|
|
|
up = &e30;
|
|
|
|
|
|
|
|
lp = ip;
|
|
|
|
lp = llp;
|
|
|
|
|
|
|
|
// constness
|
|
|
|
c1 = c2;
|
|
|
|
*c1 = *c2;
|
|
|
|
**c1 = **c2;
|
|
|
|
|
|
|
|
// unsigned = signed
|
|
|
|
u1 = c2;
|
|
|
|
*u1 = *c2;
|
|
|
|
**u1 = **c2;
|
|
|
|
|
|
|
|
c2 = c1;
|
|
|
|
*c2 = *c1;
|
|
|
|
**c2 = **c1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined test_enum_compat
|
|
|
|
enum e4;
|
|
|
|
enum e5;
|
|
|
|
void f3(enum e4 e);
|
|
|
|
void f3(enum e5 e);
|
|
|
|
|
2020-06-05 22:02:08 +08:00
|
|
|
#elif defined test_enum_compat_2
|
|
|
|
enum e6 { E1 = -1, E0 };
|
|
|
|
void f3(enum e6);
|
|
|
|
void f3(int); // should work as int and e6 are compatible
|
|
|
|
void f4(enum e6 e);
|
|
|
|
void f4(unsigned e); // should error as unsigned and e6 are incompatible
|
|
|
|
|
2018-11-13 00:11:24 +08:00
|
|
|
#elif defined test_ptr_to_str
|
|
|
|
void f() { _Generic((int const *[]){0}, int:0); }
|
|
|
|
#elif defined test_fnptr_to_str
|
|
|
|
void f() { _Generic((int (*(*)(float,char))(double,int)){0}, int:0); }
|
|
|
|
#elif defined test_array_to_str
|
|
|
|
void f() { _Generic((int(*)[3]){0}, int:0); }
|
2019-03-09 00:58:25 +08:00
|
|
|
#elif defined test_duplicate_def_1
|
|
|
|
static enum myenum { L = -1 } L;
|
|
|
|
#elif defined test_duplicate_def_2
|
|
|
|
void foo(void) {
|
|
|
|
static enum myenum { L = -1 } L;
|
|
|
|
}
|
2019-03-13 00:27:15 +08:00
|
|
|
#elif defined test_abstract_decls
|
|
|
|
int bar(const char *()); // abstract declarator here is okay
|
|
|
|
int bar (const char *(*g)()) // should match this 'g' argument
|
|
|
|
{
|
|
|
|
g();
|
|
|
|
return 42;
|
|
|
|
}
|
|
|
|
int foo(int ()) // abstract decl is wrong in definitions
|
|
|
|
{
|
|
|
|
return 0;
|
2019-03-18 10:26:19 +08:00
|
|
|
#elif defined test_invalid_1
|
|
|
|
void f(char*);
|
|
|
|
void g(void) {
|
|
|
|
f((char[]){1, ,});
|
2019-03-13 00:27:15 +08:00
|
|
|
}
|
2019-03-18 10:26:19 +08:00
|
|
|
#elif defined test_invalid_2
|
|
|
|
int ga = 0.42 { 2 };
|
|
|
|
#elif defined test_invalid_3
|
|
|
|
struct S { int a, b; };
|
|
|
|
struct T { struct S x; };
|
|
|
|
struct T gt = { 42 a: 1, 43 };
|
2020-01-16 06:32:40 +08:00
|
|
|
#elif defined test_invalid_4
|
|
|
|
enum E {
|
|
|
|
x = 1 / 0
|
|
|
|
};
|
2019-03-18 12:53:03 +08:00
|
|
|
#elif defined test_conflicting_types
|
|
|
|
int i;
|
|
|
|
void foo(void) {
|
|
|
|
int i;
|
|
|
|
{
|
|
|
|
extern double i;
|
|
|
|
i = 42.2;
|
|
|
|
}
|
|
|
|
}
|
2019-04-07 09:15:05 +08:00
|
|
|
#elif defined test_nested_types
|
|
|
|
union u {
|
|
|
|
union u {
|
|
|
|
int i;
|
|
|
|
} m;
|
|
|
|
};
|
2019-04-07 10:09:25 +08:00
|
|
|
#elif defined test_vla_1
|
|
|
|
int X=1;
|
|
|
|
|
|
|
|
int main(void) {
|
|
|
|
int t[][][X];
|
|
|
|
}
|
2019-04-09 02:58:49 +08:00
|
|
|
#elif defined test_invalid_alignas
|
|
|
|
/* _Alignas is no type qualifier */
|
|
|
|
void * _Alignas(16) p1;
|
2019-04-28 14:27:33 +08:00
|
|
|
|
|
|
|
#elif defined test_static_assert
|
|
|
|
|
|
|
|
#define ONE 0
|
2019-05-03 06:22:35 +08:00
|
|
|
_Static_assert(ONE == 0, "don't show me this");
|
2022-12-10 08:12:44 +08:00
|
|
|
struct x{ _Static_assert(ONE == 1, "ONE is not 1"); };
|
2019-04-28 14:27:33 +08:00
|
|
|
|
2020-02-29 08:24:35 +08:00
|
|
|
#elif defined test_static_assert_2
|
|
|
|
_Static_assert(1, "1"" is 1");
|
2022-12-10 08:12:44 +08:00
|
|
|
struct y { _Static_assert(0, "0"" is 0"); };
|
2020-02-29 08:24:35 +08:00
|
|
|
|
2020-02-29 08:55:11 +08:00
|
|
|
#elif defined test_static_assert_c2x
|
|
|
|
_Static_assert(1);
|
2022-12-10 08:12:44 +08:00
|
|
|
struct z { _Static_assert(0); }
|
2020-02-29 08:55:11 +08:00
|
|
|
|
2022-11-30 02:45:05 +08:00
|
|
|
#elif defined test_static_assert_empty_string
|
|
|
|
_Static_assert(0,"");
|
|
|
|
|
2019-06-24 16:28:36 +08:00
|
|
|
#elif defined test_void_array
|
|
|
|
void t[3];
|
|
|
|
|
|
|
|
#elif defined test_incomplete_enum_array
|
|
|
|
enum e t[3];
|
|
|
|
|
|
|
|
#elif defined test_incomplete_struct_array
|
|
|
|
struct s t[3];
|
|
|
|
|
|
|
|
#elif defined test_const_fun_array
|
|
|
|
typedef void f(void);
|
|
|
|
const f t[3];
|
|
|
|
|
|
|
|
#elif defined test_incomplete_array_array
|
2019-06-22 10:00:52 +08:00
|
|
|
int t[][3]; // gr: not an error, see below
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_extern_array
|
|
|
|
int iii[] = { 1,2,3 };
|
|
|
|
extern int iii[];
|
|
|
|
int x[];
|
|
|
|
int x[2];
|
|
|
|
int x[];
|
|
|
|
int x[2];
|
|
|
|
int x[];
|
|
|
|
extern int x[2];
|
|
|
|
extern int x[];
|
|
|
|
int x[3];
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_func_1 \
|
|
|
|
|| defined test_func_2 \
|
|
|
|
|| defined test_func_3 \
|
|
|
|
|| defined test_func_4 \
|
2019-12-16 13:54:18 +08:00
|
|
|
|| defined test_func_5 \
|
|
|
|
|| defined test_func_6
|
2019-06-22 10:00:52 +08:00
|
|
|
#if defined test_func_1
|
|
|
|
int hello(int);
|
|
|
|
#elif defined test_func_4
|
|
|
|
static int hello(int);
|
|
|
|
#endif
|
|
|
|
int main () {
|
2019-12-16 13:54:18 +08:00
|
|
|
#if defined test_func_6
|
2019-06-22 10:00:52 +08:00
|
|
|
static
|
|
|
|
#endif
|
|
|
|
int hello(int);
|
|
|
|
hello(123);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int printf(const char*, ...);
|
|
|
|
#if defined test_func_3
|
|
|
|
static int hello(int a)
|
|
|
|
#elif defined test_func_5
|
|
|
|
int hello(int a, int b)
|
|
|
|
#else
|
|
|
|
int hello(int a)
|
|
|
|
#endif
|
|
|
|
{ printf("%s: a = %d\n", __FUNCTION__, a); return 0; }
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_var_1 \
|
|
|
|
|| defined test_var_2 \
|
|
|
|
|| defined test_var_3
|
|
|
|
#define P(n,v) printf("%-5s: %d ; %d\n", __FUNCTION__, n, v)
|
|
|
|
#if defined test_var_1
|
|
|
|
int xxx[];
|
|
|
|
#endif
|
|
|
|
int bar();
|
|
|
|
int printf(const char*, ...);
|
|
|
|
int main ()
|
|
|
|
{
|
|
|
|
#if !defined test_var_3
|
|
|
|
int xxx = 2;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
extern int xxx[
|
|
|
|
#if defined test_var_3
|
|
|
|
2
|
|
|
|
#endif
|
|
|
|
];
|
|
|
|
P(1, xxx[0]);
|
|
|
|
xxx[0] += 2;
|
|
|
|
}
|
|
|
|
#if !defined test_var_3
|
|
|
|
P(2, xxx);
|
|
|
|
#endif
|
|
|
|
bar(123);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int xxx[1] = {1};
|
|
|
|
int bar() { P(3, xxx[0]); return 0; }
|
2019-06-24 16:28:36 +08:00
|
|
|
|
2019-07-16 23:30:04 +08:00
|
|
|
#elif defined test_var_4
|
|
|
|
struct yyy { int y; };
|
|
|
|
struct zzz;
|
|
|
|
void f1() {
|
|
|
|
extern char *x;
|
|
|
|
extern char **xx;
|
|
|
|
extern struct yyy y;
|
|
|
|
extern struct yyy *yy;
|
|
|
|
extern struct zzz z;
|
|
|
|
extern struct zzz *zz;
|
|
|
|
}
|
|
|
|
void f2() {
|
|
|
|
extern char *x;
|
|
|
|
extern char **xx;
|
|
|
|
extern struct yyy y;
|
|
|
|
extern struct yyy *yy;
|
|
|
|
extern struct zzz z;
|
|
|
|
extern struct zzz *zz;
|
|
|
|
}
|
|
|
|
struct yyy y, *yy;
|
|
|
|
struct zzz { int z; } z, *zz;
|
|
|
|
|
2020-02-23 07:11:03 +08:00
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_long_double_type_for_win32
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
double *a = 0;
|
|
|
|
long double *b = a;
|
|
|
|
int n = _Generic(*a, double:0, long double:1);
|
|
|
|
}
|
|
|
|
|
2020-06-04 00:38:11 +08:00
|
|
|
#elif defined test_stray_backslash
|
|
|
|
#define x \a
|
|
|
|
x
|
2020-05-14 05:52:48 +08:00
|
|
|
|
|
|
|
#elif defined test_stray_backslash2
|
|
|
|
int printf(const char*, ...);
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
#define _S(x) #x
|
|
|
|
#define S(x) _S(x)
|
|
|
|
printf("%sn\n", S(\\));
|
|
|
|
}
|
|
|
|
|
2019-06-22 10:00:52 +08:00
|
|
|
/******************************************************************/
|
2020-07-05 20:01:50 +08:00
|
|
|
#elif defined test_var_array
|
|
|
|
|
|
|
|
static struct var_len { int i; const char str[]; } var_array[] =
|
|
|
|
{ { 1, "abcdefghijklmnopqrstuvwxyz" },
|
|
|
|
{ 2, "longlonglonglonglong" },
|
|
|
|
{ 3, "tst3" } };
|
|
|
|
|
tccgen: flex arrays etc.
Fixes potential writes past the allocated space with mostly
illegal flex array initializers. (60_errors_and_warnings.c
:test_var_array)
In exchange suspicious precautions such as section_reserve
or checks with sec->data_allocated were removed. (There is
an hard check 'init_assert()' for now but it's meant to be
just temporary)
Also, instead of filling holes, always memset(0) structures
& arrays on stack. Sometimes more efficient, sometimes isn't.
At least we can omit putting null initializers.
About array range inititializers: Reparsing tokens has a
small problem with sideeffects, for example
int c = 0, dd[] = { [0 ... 1] = ++c, [2 ... 3] = ++c };
Also, instead of 'squeeze_multi_relocs()', delete pre-existing
relocations in advance. This works even if secondary initializers
don't even have relocations, as with
[0 ... 7] = &stuff,
[4] = NULL
Also, in tcc.h: new macro "tcc_internal_error()"
2020-09-23 18:03:59 +08:00
|
|
|
#elif defined test_var_array2
|
|
|
|
|
|
|
|
struct c1 { int a; int b[]; };
|
|
|
|
struct c1 c1 = { 1, { 2, 3, 4 } };
|
|
|
|
|
|
|
|
struct c2 { int c; struct c1 c1; };
|
|
|
|
struct c2 c2 = { 1, { 2, { 3, 4, 5 }}};
|
|
|
|
|
2021-02-16 06:58:18 +08:00
|
|
|
#elif defined test_var_array3
|
|
|
|
/* similar to test_var_array2 but with string initializers */
|
|
|
|
struct A { int a; char b[]; };
|
|
|
|
struct A a = { 1, "1" };
|
|
|
|
struct B { struct A a; };
|
|
|
|
struct B b = { { 1, "1" } };
|
2020-10-24 03:38:53 +08:00
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_default_int_type
|
|
|
|
n; // warn
|
|
|
|
f(); // don't warn
|
|
|
|
|
|
|
|
#elif defined test_invalid_global_stmtexpr
|
|
|
|
n[sizeof({3;})]; // crashed in block() due to missing local scope
|
|
|
|
|
|
|
|
#elif defined test_invalid_tokckill
|
|
|
|
f(){"12"3;} // second const token killed the value of the first
|
|
|
|
|
tccgen: flex arrays etc.
Fixes potential writes past the allocated space with mostly
illegal flex array initializers. (60_errors_and_warnings.c
:test_var_array)
In exchange suspicious precautions such as section_reserve
or checks with sec->data_allocated were removed. (There is
an hard check 'init_assert()' for now but it's meant to be
just temporary)
Also, instead of filling holes, always memset(0) structures
& arrays on stack. Sometimes more efficient, sometimes isn't.
At least we can omit putting null initializers.
About array range inititializers: Reparsing tokens has a
small problem with sideeffects, for example
int c = 0, dd[] = { [0 ... 1] = ++c, [2 ... 3] = ++c };
Also, instead of 'squeeze_multi_relocs()', delete pre-existing
relocations in advance. This works even if secondary initializers
don't even have relocations, as with
[0 ... 7] = &stuff,
[4] = NULL
Also, in tcc.h: new macro "tcc_internal_error()"
2020-09-23 18:03:59 +08:00
|
|
|
/******************************************************************/
|
2020-12-03 14:53:44 +08:00
|
|
|
#elif defined test_duplicate_member
|
|
|
|
struct S {
|
|
|
|
int a, a;
|
|
|
|
};
|
|
|
|
#elif defined test_duplicate_member_anon
|
|
|
|
struct S1 {
|
|
|
|
int b;
|
|
|
|
struct {
|
|
|
|
int b;
|
|
|
|
} c;
|
|
|
|
};
|
|
|
|
struct S2 {
|
|
|
|
int d;
|
|
|
|
struct {
|
|
|
|
int d;
|
|
|
|
};
|
|
|
|
};
|
2021-02-14 10:37:25 +08:00
|
|
|
|
|
|
|
/******************************************************************/
|
|
|
|
#elif defined test_conflicting_array_definition
|
|
|
|
extern int array[2];
|
|
|
|
int array[] = { 1, 2, 3 };
|
2021-01-27 05:25:53 +08:00
|
|
|
|
2023-02-23 00:59:31 +08:00
|
|
|
#elif defined test_incompatible_local_redef
|
|
|
|
void foo (void)
|
|
|
|
{
|
|
|
|
typedef int localfunctype (int);
|
|
|
|
extern localfunctype func2;
|
|
|
|
typedef void localfunctype (int, int);
|
|
|
|
}
|
|
|
|
|
2021-01-27 05:25:53 +08:00
|
|
|
#elif defined test_cast_from_void
|
|
|
|
void v() {}
|
|
|
|
int f() { return v(); }
|
|
|
|
|
2021-08-01 02:44:51 +08:00
|
|
|
#elif defined test_switch_W1 || defined test_switch_W2 \
|
|
|
|
|| defined test_switch_W3 || defined test_switch_W4
|
|
|
|
#if defined test_switch_W1
|
|
|
|
#pragma comment(option, "-Wall")
|
|
|
|
#elif defined test_switch_W2
|
|
|
|
#pragma comment(option, "-Wunsupported -Wno-implicit-function-declaration -Wstuff")
|
|
|
|
#elif defined test_switch_W3
|
|
|
|
#pragma comment(option, "-Wwrite-strings -Werror=discarded-qualifiers")
|
|
|
|
#elif defined test_switch_W4
|
|
|
|
#pragma comment(option, "-Wunsupported -Wno-error=implicit-function-declaration -Werror")
|
|
|
|
#endif
|
|
|
|
void func()
|
|
|
|
{
|
|
|
|
char *ccp = "123";
|
|
|
|
fink();
|
|
|
|
}
|
|
|
|
__attribute__((stuff)) int fink() {return 0;}
|
2022-03-02 05:00:42 +08:00
|
|
|
|
|
|
|
#elif defined test_invalid_funcparam_1
|
|
|
|
void func(int a, int b, int a);
|
|
|
|
|
|
|
|
#elif defined test_invalid_funcparam_2
|
|
|
|
void func(int a, int if);
|
|
|
|
|
|
|
|
#elif defined test_array_funcparam
|
|
|
|
int amain(int argc, char *argv[static argc + 1])
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int printf(const char*, ...);
|
|
|
|
for (i = 0; i < argc; ++i)
|
|
|
|
printf("arg[%d] = \"%s\"\n", i, argv[i]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
return amain(2, (char *[]){ "X", "Y", 0 });
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined test_return_from_statement_expr
|
|
|
|
int f() { ({ return 78; }); }
|
|
|
|
int main() { return f(); }
|
|
|
|
|
|
|
|
/******************************************************************/
|
2022-05-12 17:18:37 +08:00
|
|
|
|
|
|
|
#elif defined test_illegal_unicode
|
|
|
|
int main() {
|
|
|
|
char *str = "\Uffffffff";
|
|
|
|
}
|
|
|
|
|
2022-08-18 16:43:28 +08:00
|
|
|
#elif defined test_error_string
|
|
|
|
#error \123\\
|
|
|
|
456
|
|
|
|
|
2017-07-21 04:21:27 +08:00
|
|
|
#endif
|