Files
c3c/test/test_suite/functions/test_regression.c3t
Christoffer Lerno fc849c1440 0.6.0: init_new/init_temp removed. LinkedList API rewritten. List "pop" and "remove" function now return Optionals. RingBuffer API rewritten. Allocator interface changed. Deprecated Allocator, DString and mem functions removed. "identity" functions are now constants for Matrix and Complex numbers. @default implementations for interfaces removed. any* => any, same for interfaces. Emit local/private globals as "private" in LLVM, following C "static". Updated enum syntax. Add support [rgba] properties in vectors. Improved checks of aliased "void". Subarray -> slice. Fix of llvm codegen enum check. Improved alignment handling. Add --output-dir #1155. Removed List/Object append. GenericList renamed AnyList. Remove unused "unwrap". Fixes to cond. Optimize output in dead branches. Better checking of operator methods. Disallow any from implementing dynamic methods. Check for operator mismatch. Remove unnecessary bitfield. Remove numbering in --list* commands Old style enum declaration for params/type, but now the type is optional. Add note on #1086. Allow making distinct types out of "void", "typeid", "anyfault" and faults. Remove system linker build options. "Try" expressions must be simple expressions. Add optimized build to Mac tests. Register int. assert(false) only allowed in unused branches or in tests. Compile time failed asserts is a compile time error. Remove current_block_is_target. Bug when assigning an optional from an optional. Remove unused emit_zstring. Simplify phi code. Remove unnecessary unreachable blocks and remove unnecessary current_block NULL assignments. Proper handling of '.' and Win32 '//server' paths. Unify expression and macro blocks in the middle end. Add "no discard" to expression blocks with a return value. Detect "unsigned >= 0" as errors. Fix issue with distinct void as a member #1147. Improve callstack debug information #1184. Fix issue with absolute output-dir paths. Lambdas were not type checked thoroughly #1185. Fix compilation warning #1187. Request jump table using @jump for switches. Path normalization - fix possible null terminator out of bounds. Improved error messages on inlined macros.
2024-05-22 18:22:04 +02:00

608 lines
17 KiB
C

// #target: macos-x64
module test;
import test2;
import std::collections::list;
import std::collections::linkedlist;
import hello_world;
extern fn int printf(char *, ...);
fn void helloWorld()
{
printf("helloWorld!\n");
}
fn int test_static()
{
static int x = 1;
x++;
printf("Test static %d\n", x);
return x;
}
struct Bobo { short b; float c; short d; short e; float f; short g; }
struct Blob { int z; int f; }
union Foor
{
long a;
char[12] b;
}
fn int helo(double d, Bobo b)
{
int[3] de = { 1, 2, 3 };
Bobo c = b;
helo(1.0, c);
return 1;
}
fn int test1(int a, int b)
{
a = a >> b;
if (b > 128) return -1;
return a;
}
struct Foo2
{
int x;
}
fn void Foo2.printme(Foo2 *foo)
{
printf("Foo is: %d\n", foo.x);
}
fn int Foo2.mutate(Foo2 *foo)
{
printf("Mutating");
return ++foo.x;
}
def oopsInt = test2::argh(<int>);
def oopsDouble = test2::argh(<int>);
def Argh = fn int(double, Bobo);
def Argh2 = fn int(double, Bobo);
fn int sum_us(int... x)
{
int sum = 0;
if (x.len == 0) return 0;
sum += x[0] + sum_us(...x[1..^1]);
return sum;
}
def Frob = long;
fn int sumd(int[] x)
{
int sum = 0;
for (int i = 0; i < x.len; i++) sum += x[i];
return sum;
}
struct Foo
{
int a;
int b;
}
def getValueInt = test2::getValue(<int>);
def getValueDouble = test2::getValue(<double>);
def IntBlob = test2::Blob(<int>);
def DoubleBlob = Blob(<double>);
def getMultInt = test2::getMult(<int>);
def getMultDouble = test2::getMult(<double>);
def IntArray = List(<int>);
def IntList = LinkedList(<int>);
enum MyEnum : int
{
HELO,
WORLD,
BYE
}
fn void main()
{
test_static();
test_static();
test_static();
hello_world::hello();
IntList list;
list.push(10);
list.push(15);
list.push(30);
for (int i = 0; i < (int)(list.len()); i++)
{
printf("Element[%d]: %d\n", i, list.get(i));
}
list.free();
printf("Elements: %d\n", (int)(MyEnum.elements));
int elements = MyEnum.elements;
printf("Hello\n");
IntArray array;
array.push(100);
array.push(200);
array.push(400);
array.push(600);
array.insert_at(2, 300);
for (int i = 0; i < (int)(array.len()); i++)
{
printf("Element[%d]: %d\n", i, array.get(i));
}
array.free();
IntBlob a = { 42 };
DoubleBlob b = { 33.3 };
printf("a was %d\n", getValueInt(a));
printf("b was %f\n", getValueDouble(b));
printf("Mult int was %d\n", getMultInt(25));
printf("Mult double was %f\n", getMultDouble(3.3));
helloWorld();
Foo ddx;
int fro = 3;
int[4] x = { 1, 2, 3, 3 };
fro += printf("1Vararg4splatA: %d\n", sum_us(...x));
printf("%d\n", fro);
int[] z = &x;
int[3] de = { 1, 2, 3 };
printf("Vararg4splatB: %d\n", sum_us(...&x));
printf("Vararg4splatC: %d\n", sum_us(...z));
printf("Vararg4: %d\n", sum_us(1, 2, 4, 5));
printf("Vararg1: %d\n", sum_us(1));
printf("Vararg0: %d\n", sum_us());
Argh a1;
Argh2 b2;
}
module hello_world;
import foo;
extern fn int printf(char *, ...);
def doubleMult = foo::check(<double>);
fn void hello()
{
printf("Hello baby\n");
printf("Mult %f\n", doubleMult(11.1));
}
module foo(<Type>);
fn Type check(Type i)
{
return i * i;
}
module test2(<Type>);
struct Blob
{
Type a;
}
fn Type getMult(Type a)
{
return a * a;
}
Type argh = 234;
fault MyErr
{
X,
Y
}
enum Hello : int
{
FOO,
BAR,
}
macro Hello wut()
{
return Hello.FOO;
}
def Bye = Hello;
def wat = wut;
def byebye = hello;
fn int hello()
{
return 1;
}
fn Type getValue(Blob blob)
{
return blob.a;
}
/* #expect: test.ll
%Blob = type { i32 }
%Blob.0 = type { double }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { %any, i64, ptr, ptr }
%any = type { ptr, i64 }
%List = type { i64, i64, %any, ptr }
%Foo = type { i32, i32 }
@"$ct.test.Bobo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Blob" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foor" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foo2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@"$ct.test.MyEnum" = linkonce global { i8, i64, ptr, i64, i64, i64, [3 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 3, [3 x %"char[]"] [%"char[]" { ptr @.enum.HELO, i64 4 }, %"char[]" { ptr @.enum.WORLD, i64 5 }, %"char[]" { ptr @.enum.BYE, i64 3 }] }, align 8
@test_static.x = internal unnamed_addr global i32 1, align 4
define void @test.Foo2.printme(ptr %0) #0 {
entry:
%1 = load i32, ptr %0, align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %1)
ret void
}
; Function Attrs:
define i32 @test.Foo2.mutate(ptr %0) #0 {
entry:
%1 = call i32 (ptr, ...) @printf(ptr @.str.22)
%2 = load i32, ptr %0, align 4
%add = add i32 %2, 1
store i32 %add, ptr %0, align 4
ret i32 %add
}
; Function Attrs:
declare i32 @printf(ptr, ...) #0
; Function Attrs:
define void @test.helloWorld() #0 {
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
}
; Function Attrs:
define i32 @test.test_static() #0 {
entry:
%0 = load i32, ptr @test_static.x, align 4
%add = add i32 %0, 1
store i32 %add, ptr @test_static.x, align 4
%1 = load i32, ptr @test_static.x, align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, i32 %1)
%3 = load i32, ptr @test_static.x, align 4
ret i32 %3
}
; Function Attrs:
define i32 @test.helo(double %0, ptr byval(%Bobo) align 8 %1) #0 {
entry:
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const, i32 12, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg, ptr align 4 %c, i32 20, i1 false)
%2 = call i32 @test.helo(double 1.000000e+00, ptr byval(%Bobo) align 8 %indirectarg)
ret i32 1
}
; Function Attrs:
define i32 @test.test1(i32 %0, i32 %1) #0 {
entry:
%a = alloca i32, align 4
store i32 %0, ptr %a, align 4
%2 = load i32, ptr %a, align 4
%ashr = ashr i32 %2, %1
%3 = freeze i32 %ashr
store i32 %3, ptr %a, align 4
%gt = icmp sgt i32 %1, 128
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 -1
if.exit: ; preds = %entry
%4 = load i32, ptr %a, align 4
ret i32 %4
}
; Function Attrs:
define i32 @test.sum_us(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
store i64 %1, ptr %ptradd, align 8
store i32 0, ptr %sum, align 4
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd1, align 8
%eq = icmp eq i64 0, %2
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 0
if.exit: ; preds = %entry
%3 = load i32, ptr %sum, align 4
%4 = load ptr, ptr %x, align 8
%5 = load i32, ptr %4, align 4
%6 = load %"int[]", ptr %x, align 8
%7 = extractvalue %"int[]" %6, 0
%8 = extractvalue %"int[]" %6, 1
%sub = sub i64 %8, 1
%9 = add i64 %sub, 1
%size = sub i64 %9, 1
%ptradd2 = getelementptr inbounds i8, ptr %7, i64 4
%10 = insertvalue %"int[]" undef, ptr %ptradd2, 0
%11 = insertvalue %"int[]" %10, i64 %size, 1
%12 = call i32 @test.sum_us(ptr %ptradd2, i64 %size)
%add = add i32 %5, %12
%add3 = add i32 %3, %add
store i32 %add3, ptr %sum, align 4
%13 = load i32, ptr %sum, align 4
ret i32 %13
}
; Function Attrs:
define i32 @test.sumd(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
store i64 %1, ptr %ptradd, align 8
store i32 0, ptr %sum, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load i32, ptr %i, align 4
%sext = sext i32 %2 to i64
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
%3 = load i64, ptr %ptradd1, align 8
%lt = icmp slt i64 %sext, %3
%check = icmp slt i64 %3, 0
%siui-lt = or i1 %check, %lt
br i1 %siui-lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%4 = load i32, ptr %sum, align 4
%5 = load ptr, ptr %x, align 8
%6 = load i32, ptr %i, align 4
%sext2 = sext i32 %6 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %sext2
%7 = load i32, ptr %ptroffset, align 4
%add = add i32 %4, %7
store i32 %add, ptr %sum, align 4
%8 = load i32, ptr %i, align 4
%add3 = add i32 %8, 1
store i32 %add3, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%9 = load i32, ptr %sum, align 4
ret i32 %9
}
; Function Attrs:
define void @test.main() #0 {
entry:
%list = alloca %LinkedList, align 8
%i = alloca i32, align 4
%elements = alloca i32, align 4
%array = alloca %List, align 8
%i1 = alloca i32, align 4
%a = alloca %Blob, align 4
%b = alloca %Blob.0, align 8
%ddx = alloca %Foo, align 4
%fro = alloca i32, align 4
%x = alloca [4 x i32], align 16
%z = alloca %"int[]", align 8
%de = alloca [3 x i32], align 4
%varargslots = alloca [4 x i32], align 16
%varargslots14 = alloca [1 x i32], align 4
%a1 = alloca ptr, align 8
%b2 = alloca ptr, align 8
%0 = call i32 @test.test_static()
%1 = call i32 @test.test_static()
%2 = call i32 @test.test_static()
call void @hello_world.hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 40, i1 false)
call void @"std.collections.linkedlist$int$.LinkedList.push"(ptr %list, i32 10)
call void @"std.collections.linkedlist$int$.LinkedList.push"(ptr %list, i32 15)
call void @"std.collections.linkedlist$int$.LinkedList.push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std.collections.linkedlist$int$.LinkedList.len"(ptr %list) #3
%trunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %trunc
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%sext = sext i32 %5 to i64
%6 = call i32 @"std.collections.linkedlist$int$.LinkedList.get"(ptr %list, i64 %sext)
%7 = load i32, ptr %i, align 4
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %7, i32 %6)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
call void @"std.collections.linkedlist$int$.LinkedList.free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 40, i1 false)
call void @"std.collections.list$int$.List.push"(ptr %array, i32 100)
call void @"std.collections.list$int$.List.push"(ptr %array, i32 200)
call void @"std.collections.list$int$.List.push"(ptr %array, i32 400)
call void @"std.collections.list$int$.List.push"(ptr %array, i32 600) #3
call void @"std.collections.list$int$.List.insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std.collections.list$int$.List.len"(ptr %array) #3
%trunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %trunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%sext6 = sext i32 %14 to i64
%15 = call i32 @"std.collections.list$int$.List.get"(ptr %array, i64 %sext6) #3
%16 = load i32, ptr %i1, align 4
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %16, i32 %15)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
store i32 %add7, ptr %i1, align 4
br label %loop.cond2
loop.exit8: ; preds = %loop.cond2
call void @"std.collections.list$int$.List.free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = load i32, ptr %a, align 4
%20 = call i32 @"test2$int$.getValue"(i32 %19)
%21 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %20)
%22 = load double, ptr %b, align 8
%23 = call double @"test2$double$.getValue"(double %22)
%24 = call i32 (ptr, ...) @printf(ptr @.str.9, double %23)
%25 = call i32 @"test2$int$.getMult"(i32 25)
%26 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %25)
%27 = call double @"test2$double$.getMult"(double 3.300000e+00)
%28 = call i32 (ptr, ...) @printf(ptr @.str.11, double %27)
call void @test.helloWorld()
store i32 0, ptr %ddx, align 4
%ptradd = getelementptr inbounds i8, ptr %ddx, i64 4
store i32 0, ptr %ptradd, align 4
store i32 3, ptr %fro, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 16 @.__const.12, i32 16, i1 false)
%29 = load i32, ptr %fro, align 4
%30 = insertvalue %"int[]" undef, ptr %x, 0
%31 = insertvalue %"int[]" %30, i64 4, 1
%32 = call i32 @test.sum_us(ptr %x, i64 4)
%33 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %32)
%add9 = add i32 %29, %33
store i32 %add9, ptr %fro, align 4
%34 = load i32, ptr %fro, align 4
%35 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %34)
%36 = insertvalue %"int[]" undef, ptr %x, 0
%37 = insertvalue %"int[]" %36, i64 4, 1
store %"int[]" %37, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%38 = insertvalue %"int[]" undef, ptr %x, 0
%39 = insertvalue %"int[]" %38, i64 4, 1
%40 = call i32 @test.sum_us(ptr %x, i64 4)
%41 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %40)
%lo = load ptr, ptr %z, align 8
%ptradd10 = getelementptr inbounds i8, ptr %z, i64 8
%hi = load i64, ptr %ptradd10, align 8
%42 = call i32 @test.sum_us(ptr %lo, i64 %hi)
%43 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %42)
store i32 1, ptr %varargslots, align 4
%ptradd11 = getelementptr inbounds i8, ptr %varargslots, i64 4
store i32 2, ptr %ptradd11, align 4
%ptradd12 = getelementptr inbounds i8, ptr %varargslots, i64 8
store i32 4, ptr %ptradd12, align 4
%ptradd13 = getelementptr inbounds i8, ptr %varargslots, i64 12
store i32 5, ptr %ptradd13, align 4
%44 = call i32 @test.sum_us(ptr %varargslots, i64 4)
%45 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %44)
store i32 1, ptr %varargslots14, align 4
%46 = call i32 @test.sum_us(ptr %varargslots14, i64 1)
%47 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %46)
%48 = call i32 @test.sum_us(ptr null, i64 0)
%49 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %48)
store ptr null, ptr %a1, align 8
store ptr null, ptr %b2, align 8
ret void
}
// #expect: hello_world.ll
define void @hello_world.hello()
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
%1 = call double @"foo$double$.check"(double 1.110000e+01)
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, double %1)
ret void
// #expect: foo.double.ll
define double @"foo$double$.check"(double %0)
entry:
%fmul = fmul double %0, %0
ret double %fmul
// #expect: test2.int.ll
%Blob = type { i32 }
@"test2$int$.argh" = local_unnamed_addr global i32 234, align 4
define i32 @"test2$int$.getMult"(i32 %0) #0 {
entry:
%mul = mul i32 %0, %0
ret i32 %mul
}
define i32 @"test2$int$.hello"() #0 {
entry:
ret i32 1
}
define i32 @"test2$int$.getValue"(i32 %0) #0 {
entry:
%blob = alloca %Blob, align 4
store i32 %0, ptr %blob, align 4
%1 = load i32, ptr %blob, align 4
ret i32 %1
}
// #expect: test2.double.ll
%Blob = type { double }
@"test2$double$.argh" = local_unnamed_addr global double 2.340000e+02, align 8
define double @"test2$double$.getMult"(double %0)
entry:
%fmul = fmul double %0, %0
ret double %fmul
define i32 @"test2$double$.hello"()
entry:
ret i32 1
define double @"test2$double$.getValue"(double %0)
entry:
%blob = alloca %Blob, align 8
store double %0, ptr %blob, align 8
%1 = load double, ptr %blob, align 8
ret double %1