mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Changed how structs/unions are parsed so that recovery becomes more robust. Allow for more complex error data. Fixed recursive structs/unions. Corrected prefix precedence rules. Begin work on checking initializer constant-ness. Fixed error on failed arithmetic promotion. Added checks on constant overflow of sub/add/mult. Allow "current_module_name::x" to refer to globals. Added many tests.
This commit is contained in:
@@ -68,11 +68,11 @@ class Issues:
|
||||
print('"' + parts[3] + '"')
|
||||
if len(self.errors) > 0:
|
||||
self.set_failed()
|
||||
print("Expected errors that never occured:")
|
||||
print("Expected errors that never occurred:")
|
||||
num = 1
|
||||
for key, value in self.errors.items():
|
||||
pos = key.split(":", 2)
|
||||
print(str(num) + ". " + pos[0] + " line: " + pos[1] + " expected: " + value)
|
||||
print(str(num) + ". " + pos[0] + " line: " + pos[1] + " expected: \"" + value + "\"")
|
||||
num += 1
|
||||
|
||||
def compile(self, args):
|
||||
@@ -80,7 +80,7 @@ class Issues:
|
||||
code = subprocess.run(path + 'c3c ' + args, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if code.returncode != 0 and code.returncode != 1:
|
||||
self.set_failed()
|
||||
print("Error: " + code.stderr)
|
||||
print("Error (" + str(code.returncode) + "): " + code.stderr)
|
||||
self.has_errors = True
|
||||
return
|
||||
self.parse_result(code.stderr.splitlines(keepends=False))
|
||||
|
||||
@@ -10,4 +10,5 @@ module comments;
|
||||
func void test()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
enum EnumTestOverflow
|
||||
{
|
||||
VALUE = 0x80000000, // #error: does not fit into 'int'
|
||||
}
|
||||
|
||||
enum EnumTestErrorType : float // #error: must be an integer type not 'float'
|
||||
{
|
||||
VALUE_BOOM
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
enum EnumWithErrorWithMissingName : int (int) // #error: function parameter must be named
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
enum EnumWithErrorData : int (int // #error: end of the parameter list
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
error TheError
|
||||
{
|
||||
union // #error: A type name was expected here
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
module foo;
|
||||
|
||||
error TooBig // #error: Error type may not exceed pointer
|
||||
|
||||
|
||||
error TheError
|
||||
{
|
||||
usize a;
|
||||
char b;
|
||||
}
|
||||
|
||||
|
||||
union // #error: A type name was expected here
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,16 @@ error TheError
|
||||
int a;
|
||||
}
|
||||
|
||||
error TheError2
|
||||
{
|
||||
byte a;
|
||||
byte b;
|
||||
}
|
||||
|
||||
error TheError3
|
||||
{
|
||||
void *a;
|
||||
}
|
||||
|
||||
error OtherError;
|
||||
|
||||
|
||||
5
test/test_suite/errors/error_semantic_fails.c3
Normal file
5
test/test_suite/errors/error_semantic_fails.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
error TooBig // #error: Error type may not exceed pointer
|
||||
{
|
||||
usize a;
|
||||
char b;
|
||||
}
|
||||
@@ -35,4 +35,15 @@ func void testDiv(int a, int b)
|
||||
a = a / b;
|
||||
a /= b;
|
||||
a /= 1;
|
||||
}
|
||||
|
||||
func void testAssignment()
|
||||
{
|
||||
char x = -3 - 5;
|
||||
char c = -128;
|
||||
}
|
||||
|
||||
func byte test22()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
129
test/test_suite/expressions/arithmetics_sema_fail.c3
Normal file
129
test/test_suite/expressions/arithmetics_sema_fail.c3
Normal file
@@ -0,0 +1,129 @@
|
||||
func void test1()
|
||||
{
|
||||
double x = 2.3 +% 2; // #error: only valid for integer addition
|
||||
}
|
||||
|
||||
func void test2()
|
||||
{
|
||||
double x = 0;
|
||||
int y = x +% 4; // #error: only valid for integer addition
|
||||
}
|
||||
|
||||
func void test3()
|
||||
{
|
||||
double x = 2.3 -% 2; // #error: only valid for integer subtraction
|
||||
}
|
||||
|
||||
func void test4()
|
||||
{
|
||||
double x = 0;
|
||||
int y = x -% 4; // #error: only valid for integer subtraction
|
||||
}
|
||||
|
||||
func void test5()
|
||||
{
|
||||
double x = 2.3 *% 2; // #error: try * instead
|
||||
}
|
||||
|
||||
func void test6()
|
||||
{
|
||||
double x = 0;
|
||||
int y = x *% 4; // #error: try * instead
|
||||
}
|
||||
|
||||
func void test7()
|
||||
{
|
||||
double x = 1.2 / 0; // #error: division by zero is not allowed
|
||||
}
|
||||
|
||||
func void test8()
|
||||
{
|
||||
int y = 0 / 0; // #error: division by zero is not allowed
|
||||
}
|
||||
|
||||
func void test9()
|
||||
{
|
||||
int y = 0;
|
||||
int x = y / 0; // #error: division by zero is not allowed
|
||||
}
|
||||
|
||||
func void test10()
|
||||
{
|
||||
10 = 20; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test11()
|
||||
{
|
||||
'10' = '20'; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test12()
|
||||
{
|
||||
true = false; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test13()
|
||||
{
|
||||
"a" = "b"; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test14()
|
||||
{
|
||||
1.2 = 1.3; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test15()
|
||||
{
|
||||
nil = nil; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test16()
|
||||
{
|
||||
int a = 0;
|
||||
uint b = 2;
|
||||
ushort c = 3;
|
||||
a = a + c;
|
||||
int c = a + b; // #error: Cannot add 'int' to 'uint'
|
||||
}
|
||||
|
||||
func void test17()
|
||||
{
|
||||
byte a = 100 + 300; // #error: '300' does not fit in type 'byte'
|
||||
}
|
||||
|
||||
func void test18()
|
||||
{
|
||||
byte b = 100 + 156; // #error: Cannot fit '256' into type 'byte'
|
||||
}
|
||||
|
||||
func void test19()
|
||||
{
|
||||
char b = (-40) - 126; // #error: Cannot fit '-166' into type 'char'
|
||||
}
|
||||
|
||||
|
||||
|
||||
func void test20()
|
||||
{
|
||||
char d = ((-128 - 10) + 10) - 2; // #error: Cannot fit '-130' into type 'char'
|
||||
char c = 100 * 100; // #error: Cannot fit '10000' into type 'char'
|
||||
char e = (-138 + 30);
|
||||
char f = -138 + 30; // #error: '-138' does not fit in type 'char'
|
||||
char g = -(128);
|
||||
check(128); // #error: '128' does not fit in type 'char'
|
||||
}
|
||||
|
||||
func void check(char x) {}
|
||||
|
||||
func void test21()
|
||||
{
|
||||
int a = 0;
|
||||
int b = 2;
|
||||
a++ = b++; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func byte test22()
|
||||
{
|
||||
return 300; // #error: '300' does not fit in type 'byte'
|
||||
}
|
||||
|
||||
5
test/test_suite/expressions/assign.c3
Normal file
5
test/test_suite/expressions/assign.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
func void test1()
|
||||
{
|
||||
int* p;
|
||||
*p = 10;
|
||||
}
|
||||
33
test/test_suite/globals/global_init.c3
Normal file
33
test/test_suite/globals/global_init.c3
Normal file
@@ -0,0 +1,33 @@
|
||||
// #skip
|
||||
|
||||
// TODO string str = "hello";
|
||||
char* str2 = "hello";
|
||||
|
||||
char[] str3 = "hello";
|
||||
|
||||
func void test2()
|
||||
{
|
||||
int[2] a = { 1, 2 };
|
||||
|
||||
int[2] b = 30; // #error: Cannot implicitly cast 'compint' to 'int[2]'
|
||||
int[2] c = a;
|
||||
}
|
||||
|
||||
int[2] a1 = { 1, 2 };
|
||||
|
||||
int[2] a2 = 30; // #error: Cannot implicitly cast 'compint' to 'int[2]'
|
||||
int[2] a3 = a1;
|
||||
|
||||
// i8[] a; // @error{definition of variable with array type needs an explicit size or an initializer}
|
||||
|
||||
char ca = 0;
|
||||
char cb = 1;
|
||||
|
||||
char cc = 127;
|
||||
char cd = -128;
|
||||
|
||||
char ce = 128; // #error: '128' does not fit
|
||||
char cf = -129; // #error: '-129' does not fit
|
||||
|
||||
char cg = 70000; // #error: '70000' does not fit
|
||||
char ch = -70000; // #error: '-70000' does not fit
|
||||
73
test/test_suite/globals/incr_array.c3
Normal file
73
test/test_suite/globals/incr_array.c3
Normal file
@@ -0,0 +1,73 @@
|
||||
// #skip
|
||||
|
||||
|
||||
i32[+] a;
|
||||
|
||||
a += 10;
|
||||
|
||||
public func i32 main() {
|
||||
a += 20; // @error{cannot add values to incremental array in function scope}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const i32[+] A;
|
||||
A += 10;
|
||||
A += 20;
|
||||
A += 30;
|
||||
|
||||
i32[+] b;
|
||||
|
||||
func void test1() {
|
||||
i32[+] d; // @error{incremental arrays not allowed in function scope}
|
||||
}
|
||||
|
||||
i32[+] c;
|
||||
|
||||
func void test2()
|
||||
{
|
||||
b += 10; // @error{cannot add values to incremental array in function scope}
|
||||
}
|
||||
|
||||
i32[+] a = {} // @error{incremental array cannot have initializer}
|
||||
|
||||
|
||||
i32 g;
|
||||
i8[2] h = { 1, 2 }
|
||||
|
||||
g += 10; // @error{'a' is not an incremental array}
|
||||
|
||||
xyz += 20; // @error{module test has no symbol b}
|
||||
|
||||
h += 30; // @error{'d' is not an incremental array}
|
||||
|
||||
test2 += 20; // @error{'main' is not an incremental array}
|
||||
|
||||
i32[+] i;
|
||||
|
||||
i += xyz; // @error{use of undeclared identifier c}
|
||||
|
||||
a += test2; // @error{invalid type conversion from 'i32 ()' to 'i32'}
|
||||
|
||||
i32[+] k;
|
||||
|
||||
k += 1;
|
||||
k += 2;
|
||||
k += 3;
|
||||
|
||||
public func void test3()
|
||||
{
|
||||
i32 c = a; // @error{invalid type conversion from 'i32[3]' to 'i32'}
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
}
|
||||
|
||||
Point[+] points;
|
||||
|
||||
points += { 10, 11 }
|
||||
points += { 20, main } // @error{invalid type conversion from 'i32 ()' to 'i32'}
|
||||
points += { 30, 31 }
|
||||
|
||||
17
test/test_suite/globals/incr_enum.c3
Normal file
17
test/test_suite/globals/incr_enum.c3
Normal file
@@ -0,0 +1,17 @@
|
||||
// #skip
|
||||
|
||||
type State enum u8 {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
State += 10; // @error{expected identifier after incremental enum}
|
||||
|
||||
|
||||
type State enum u8 {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
State += C;
|
||||
State += D;
|
||||
31
test/test_suite/statements/for.c3
Normal file
31
test/test_suite/statements/for.c3
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
public func int main()
|
||||
{
|
||||
for (;;) {}
|
||||
return 0;
|
||||
}
|
||||
public func int test1()
|
||||
{
|
||||
for (int x = 0;;)
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public func int test2()
|
||||
{
|
||||
for (int x = 0; 1 ;)
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public func int test3()
|
||||
{
|
||||
for (; 1 ;2)
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
7
test/test_suite/statements/for_errors.c3
Normal file
7
test/test_suite/statements/for_errors.c3
Normal file
@@ -0,0 +1,7 @@
|
||||
func void foo() {}
|
||||
|
||||
public func int main()
|
||||
{
|
||||
for (; foo() ; ) {} // #error: Cannot implicitly cast 'void' to 'bool'
|
||||
return 0;
|
||||
}
|
||||
24
test/test_suite/statements/label_errors.c3
Normal file
24
test/test_suite/statements/label_errors.c3
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
public func int main()
|
||||
{
|
||||
do FOO:
|
||||
{
|
||||
while FOO: (1) // #error: would shadow a previous declaration
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
func void test1()
|
||||
{
|
||||
do FOO:
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
break BAR; // #error: Cannot find a labelled statement with the name 'BAR'
|
||||
}
|
||||
}
|
||||
}
|
||||
136
test/test_suite/statements/switch_errors.c3
Normal file
136
test/test_suite/statements/switch_errors.c3
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
enum Foo
|
||||
{
|
||||
A, B
|
||||
}
|
||||
|
||||
enum Bar
|
||||
{
|
||||
B
|
||||
}
|
||||
|
||||
func void test_other_enum()
|
||||
{
|
||||
Foo f = A;
|
||||
switch (f)
|
||||
{
|
||||
case Foo.A:
|
||||
break;
|
||||
case B:
|
||||
break;
|
||||
case Bar.B: // #error: Cannot implicitly cast 'Bar' to 'Foo'
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_check_nums()
|
||||
{
|
||||
Foo f = A;
|
||||
switch (f)
|
||||
{
|
||||
case 2:
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_scope(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
int a = 0;
|
||||
break;
|
||||
case 2:
|
||||
test_scope(a + 1); // #error: Identifier 'a' could not be found
|
||||
}
|
||||
}
|
||||
|
||||
func void test_duplicate_case(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 1: // #error: same case value appears
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_duplicate_case2(Foo i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case A:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case A: // #error: same case value appears
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_duplicate_case3(Foo i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case A:
|
||||
break;
|
||||
case 0: // #error: same case value appears
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum Baz
|
||||
{
|
||||
A, B, C, D
|
||||
}
|
||||
|
||||
func void test_missing_all_cases(Baz x)
|
||||
{
|
||||
switch (x) // -error: 4 enumeration values not handled in switch: A, B, C, ...
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
func void test_missing_some_cases(Baz x)
|
||||
{
|
||||
switch (x) // -error: 4 enumeration B, C and D not handled in switch
|
||||
{
|
||||
case A:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_missing_some_cases2(Baz x)
|
||||
{
|
||||
switch (x) // -error: 4 enumeration B and D not handled in switch
|
||||
{
|
||||
case C:
|
||||
case A:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_missing_some_cases3(Baz x)
|
||||
{
|
||||
switch (x) // -error: 4 enumeration B and D not handled in switch
|
||||
{
|
||||
case B:
|
||||
case C:
|
||||
case A:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_missing_no_cases(Baz x)
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
70
test/test_suite/struct/duplicate_member.c3
Normal file
70
test/test_suite/struct/duplicate_member.c3
Normal file
@@ -0,0 +1,70 @@
|
||||
// @warnings{no-unused}
|
||||
module test;
|
||||
|
||||
|
||||
struct Aa
|
||||
{
|
||||
int a;
|
||||
int a; // #error: Duplicate member name 'a'
|
||||
}
|
||||
|
||||
struct Bb
|
||||
{
|
||||
int a;
|
||||
struct a // #error: Duplicate member name 'a'
|
||||
{
|
||||
int b;
|
||||
}
|
||||
}
|
||||
|
||||
union Cc
|
||||
{
|
||||
int a;
|
||||
int a; // #error: Duplicate member name 'a'
|
||||
|
||||
struct b
|
||||
{
|
||||
int c;
|
||||
int c; // #error: Duplicate member name 'c'
|
||||
}
|
||||
}
|
||||
|
||||
struct Dd
|
||||
{
|
||||
int b;
|
||||
int a;
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
short a; // #error: Duplicate member name 'a'
|
||||
int b; // #error: Duplicate member name 'b'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
union Ee
|
||||
{
|
||||
int a;
|
||||
struct
|
||||
{
|
||||
short a; // #error: Duplicate member name 'a'
|
||||
}
|
||||
}
|
||||
|
||||
struct Ff
|
||||
{
|
||||
struct
|
||||
{
|
||||
int a;
|
||||
}
|
||||
struct b
|
||||
{
|
||||
int a;
|
||||
}
|
||||
union
|
||||
{
|
||||
int a; // #error: Duplicate member name 'a'
|
||||
}
|
||||
}
|
||||
|
||||
84
test/test_suite/struct/member_access.c3
Normal file
84
test/test_suite/struct/member_access.c3
Normal file
@@ -0,0 +1,84 @@
|
||||
module test;
|
||||
|
||||
|
||||
struct Multi
|
||||
{
|
||||
int a, b, c;
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
int a;
|
||||
struct bb
|
||||
{
|
||||
int b;
|
||||
}
|
||||
struct
|
||||
{
|
||||
int b;
|
||||
int c;
|
||||
struct
|
||||
{
|
||||
Point* p;
|
||||
}
|
||||
}
|
||||
union
|
||||
{
|
||||
int d;
|
||||
short e;
|
||||
}
|
||||
union uu {
|
||||
int d;
|
||||
ushort e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func void tester()
|
||||
{
|
||||
Multi m;
|
||||
m.a = 1;
|
||||
Point p;
|
||||
p.a = 1;
|
||||
p.bb.b = 2;
|
||||
p.b = 3;
|
||||
p.c = 4;
|
||||
p.p = nil;
|
||||
p.d = 5;
|
||||
p.e = 6;
|
||||
p.uu.d = 7;
|
||||
p.uu.e = 8;
|
||||
Point *p2 = &p;
|
||||
p2.bb.b = 3;
|
||||
p = { a = 1, bb.b = 3, e = 2 };
|
||||
}
|
||||
|
||||
struct Aa1
|
||||
{
|
||||
struct bb
|
||||
{
|
||||
int b;
|
||||
}
|
||||
struct
|
||||
{
|
||||
int c;
|
||||
}
|
||||
}
|
||||
|
||||
func void test_conversion_struct()
|
||||
{
|
||||
Aa1 a1;
|
||||
int aa = a1.bb; // #error: Cannot implicitly cast 'bb' to 'int'
|
||||
}
|
||||
|
||||
struct Struct
|
||||
{
|
||||
int a;
|
||||
}
|
||||
|
||||
func void myfunc()
|
||||
{
|
||||
Struct s;
|
||||
s.b = 10; // #error: There is no element or method 'Struct.b'
|
||||
}
|
||||
|
||||
184
test/test_suite/symbols/various.c3
Normal file
184
test/test_suite/symbols/various.c3
Normal file
@@ -0,0 +1,184 @@
|
||||
module test;
|
||||
|
||||
func void test1()
|
||||
{
|
||||
char a = 1;
|
||||
int b = 2;
|
||||
char c = b > a ? 1 : 0;
|
||||
}
|
||||
|
||||
func void test2()
|
||||
{
|
||||
char a = 1;
|
||||
char b = 2;
|
||||
char c = a + b;
|
||||
}
|
||||
|
||||
func void test3()
|
||||
{
|
||||
char a = 1;
|
||||
int b = 2;
|
||||
char c = a + b; // #error: Cannot implicitly cast 'int' to 'char'
|
||||
}
|
||||
|
||||
func void test4()
|
||||
{
|
||||
char a = 1;
|
||||
char b = 2;
|
||||
int c = a + b;
|
||||
}
|
||||
|
||||
func void test5()
|
||||
{
|
||||
char a = 1;
|
||||
int b = 2;
|
||||
int c = a + b;
|
||||
}
|
||||
|
||||
|
||||
func void test6()
|
||||
{
|
||||
char a = 1;
|
||||
char b = 2;
|
||||
char c = (b > a) ? 1 : 0 + a + b;
|
||||
}
|
||||
|
||||
func void test7()
|
||||
{
|
||||
int[100] array = { };
|
||||
int v = array[1];
|
||||
}
|
||||
|
||||
typedef int as Number;
|
||||
|
||||
func void test8()
|
||||
{
|
||||
Number a = 10;
|
||||
char c = a; // #error: implicitly cast 'Number' (int) to 'char'
|
||||
}
|
||||
|
||||
|
||||
func void test9()
|
||||
{
|
||||
const char a = 1; // TODO should be "A"
|
||||
char b = a;
|
||||
a = b; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test10()
|
||||
{
|
||||
const char a = 1;
|
||||
char* b = &a; // #error: address of values
|
||||
}
|
||||
|
||||
enum Enum : int
|
||||
{
|
||||
A = 127,
|
||||
B,
|
||||
}
|
||||
|
||||
func void test11()
|
||||
{
|
||||
int a = Enum.A;
|
||||
char b = Enum.B; // #error: Cannot implicitly convert 'Enum' with underlying type of 'int' to 'char'
|
||||
}
|
||||
|
||||
func void test12()
|
||||
{
|
||||
float f = 3.14;
|
||||
char a = f; // #error: cast 'float' to 'char'
|
||||
}
|
||||
|
||||
func void test13()
|
||||
{
|
||||
int a = 1;
|
||||
char b = a; // #error: cast 'int' to 'char'
|
||||
}
|
||||
|
||||
func void test14()
|
||||
{
|
||||
byte a = 1;
|
||||
char b = a; // #error: cast 'byte' to 'char'
|
||||
}
|
||||
|
||||
func void test15()
|
||||
{
|
||||
float f = 3.14;
|
||||
char c = 1;
|
||||
char* a = &f; // #error: cast 'float*' to 'char*'
|
||||
char* b = &c;
|
||||
}
|
||||
|
||||
func void test16()
|
||||
{
|
||||
float f = 3.14;
|
||||
int i = 1;
|
||||
|
||||
char c = 1 ? 'c' : 'd';
|
||||
char d = 1 ? 'c' : i; // #error: cast 'int' to 'char'
|
||||
char e = 1 ? i : 0; // #error: cast 'int' to 'char'
|
||||
int g = 1 ? i : f; // #error: cast 'float' to 'int'
|
||||
int a = f ? 1 : 0;
|
||||
}
|
||||
|
||||
func void test17()
|
||||
{
|
||||
int a = "test"; // #error: cast 'string' to 'int'
|
||||
}
|
||||
|
||||
func void test18()
|
||||
{
|
||||
char b = 1;
|
||||
int a = b;
|
||||
}
|
||||
|
||||
func void test19()
|
||||
{
|
||||
uint a = 1;
|
||||
int b = a; // #error: cast 'uint' to 'int'
|
||||
}
|
||||
|
||||
/*
|
||||
const i32 Num = 200;
|
||||
|
||||
func void test1() {
|
||||
i8 a = test.Num; // @error{constant value 200 out-of-bounds for type 'i8', range [-128, 127]}
|
||||
}*/
|
||||
|
||||
func void test21()
|
||||
{
|
||||
int a = 1;
|
||||
uint b = a; // #error: cast 'int' to 'uint'
|
||||
}
|
||||
|
||||
func void foo() {}
|
||||
|
||||
func void test22()
|
||||
{
|
||||
char a = foo(); // #error: cast 'void' to 'char'
|
||||
short b = foo(); // #error: cast 'void' to 'short'
|
||||
int c = foo(); // #error: cast 'void' to 'int'
|
||||
long d = foo(); // #error: cast 'void' to 'long'
|
||||
byte e = foo(); // #error: cast 'void' to 'byte'
|
||||
ushort f = foo(); // #error: cast 'void' to 'ushort'
|
||||
uint g = foo(); // #error: cast 'void' to 'uint'
|
||||
ulong h = foo(); // #error: cast 'void' to 'ulong'
|
||||
bool i = foo(); // #error: cast 'void' to 'bool'
|
||||
}
|
||||
|
||||
|
||||
int num = 10;
|
||||
|
||||
func void test23()
|
||||
{
|
||||
int a = num;
|
||||
int b = test::num;
|
||||
char c = test::num; // #error: cast 'int' to 'char'
|
||||
}
|
||||
|
||||
int[2][3] b123;
|
||||
|
||||
func void test24()
|
||||
{
|
||||
int a = b123; // #error: cast 'int[2][3]' to 'int'
|
||||
}
|
||||
34
test/test_suite/types/enum_errors.c3
Normal file
34
test/test_suite/types/enum_errors.c3
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
enum EnumTestOverflow
|
||||
{
|
||||
VALUE = 0x80000000, // #error: does not fit in type 'int'
|
||||
}
|
||||
|
||||
enum EnumTestErrorType : float // #error: must be an integer type not 'float'
|
||||
{
|
||||
VALUE_BOOM
|
||||
}
|
||||
|
||||
|
||||
enum EnumWithErrorType2 : int* // #error: must be an integer type not 'int*'
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
enum EnumTestErrorType3 : int
|
||||
{
|
||||
A = FOO // #error: Identifier 'FOO' could not be found
|
||||
}
|
||||
|
||||
func int foo()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
enum State
|
||||
{
|
||||
A = foo(), // #error: Expected a constant expression for enum
|
||||
B = "hello", // #error: Cannot implicitly cast 'string' to 'int'
|
||||
C = true, // #error: Cannot implicitly cast 'bool' to 'int'
|
||||
}
|
||||
@@ -29,3 +29,18 @@ enum EnumTestSmall : ushort
|
||||
VALUE = 0xFF,
|
||||
VALUE2 = 0xFFFF
|
||||
}
|
||||
|
||||
enum EnumWithErrorData2 : int (int bar, )
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
enum EnumTestErrorType4
|
||||
{
|
||||
}
|
||||
|
||||
enum EnumTest5
|
||||
{
|
||||
B = 0,
|
||||
C,
|
||||
}
|
||||
23
test/test_suite/types/enum_parse_errors.c3
Normal file
23
test/test_suite/types/enum_parse_errors.c3
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
enum EnumWithErrorWithMissingName : int (int) // #error: function parameter must be named
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
enum EnumWithErrorData : int (int // #error: end of the parameter list
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
enum EnumWithErrorData2 : int (int, int bar) // #error: function parameter must be named
|
||||
{
|
||||
TEST
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum EnumTestErrorType3 : int
|
||||
{
|
||||
A,
|
||||
A // #error: This enum constant is declared twice
|
||||
}
|
||||
17
test/test_suite/types/typedefs.c3
Normal file
17
test/test_suite/types/typedefs.c3
Normal file
@@ -0,0 +1,17 @@
|
||||
typedef int[4] as Arr;
|
||||
|
||||
Arr a = { 3, 4, 5, 6 };
|
||||
|
||||
func void test1()
|
||||
{
|
||||
Arr b = { 3, 4, 5, 6 };
|
||||
int c = b; // #error: cast 'Arr' (int[4]) to 'int'
|
||||
int d = a; // #error: cast 'Arr' (int[4]) to 'int'
|
||||
}
|
||||
|
||||
typedef Number1 as Number2; // #error: Recursive definition of 'Number2'
|
||||
typedef Number2 as Number1;
|
||||
|
||||
typedef Number as Number; // #error: Recursive definition of 'Number'
|
||||
|
||||
|
||||
3
test/test_suite/types/various.c3
Normal file
3
test/test_suite/types/various.c3
Normal file
@@ -0,0 +1,3 @@
|
||||
func1 a = 1; // #error: declaration before the variable
|
||||
|
||||
func void func1() {}
|
||||
Reference in New Issue
Block a user