mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Regression vector ABI: npot vectors would load incorrectly from pointers and other things. #2576
105 lines
3.0 KiB
Plaintext
105 lines
3.0 KiB
Plaintext
// #target: macos-x64
|
|
module test;
|
|
import std::io;
|
|
|
|
interface VeryOptional
|
|
{
|
|
fn void do_something() @optional;
|
|
}
|
|
|
|
struct Foo (VeryOptional)
|
|
{
|
|
String name;
|
|
}
|
|
|
|
Foo foo = { "Foo" };
|
|
|
|
fn VeryOptional? get_very_optional()
|
|
{
|
|
return &foo;
|
|
}
|
|
|
|
fn void main()
|
|
{
|
|
VeryOptional? v = get_very_optional();
|
|
if (try x = &v.do_something)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
io::printfn("do_something is not implemented for Foo");
|
|
}
|
|
}
|
|
|
|
/* #expect: test.ll
|
|
|
|
define void @test.main() #0 {
|
|
entry:
|
|
%v = alloca %any, align 8
|
|
%v.f = alloca i64, align 8
|
|
%retparam = alloca %any, align 8
|
|
%x = alloca ptr, align 8
|
|
%.inlinecache = alloca ptr, align 8
|
|
%.cachedtype = alloca ptr, align 8
|
|
%retparam3 = alloca i64, align 8
|
|
store ptr null, ptr %.cachedtype, align 8
|
|
%0 = call i64 @test.get_very_optional(ptr %retparam)
|
|
%not_err = icmp eq i64 %0, 0
|
|
%1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
|
br i1 %1, label %after_check, label %assign_optional
|
|
|
|
assign_optional: ; preds = %entry
|
|
store i64 %0, ptr %v.f, align 8
|
|
br label %after_assign
|
|
|
|
after_check: ; preds = %entry
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %v, ptr align 8 %retparam, i32 16, i1 false)
|
|
store i64 0, ptr %v.f, align 8
|
|
br label %after_assign
|
|
|
|
after_assign: ; preds = %after_check, %assign_optional
|
|
store ptr null, ptr %x, align 8
|
|
%optval = load i64, ptr %v.f, align 8
|
|
%not_err1 = icmp eq i64 %optval, 0
|
|
%2 = call i1 @llvm.expect.i1(i1 %not_err1, i1 true)
|
|
br i1 %2, label %after_check2, label %catch_landing
|
|
|
|
after_check2: ; preds = %after_assign
|
|
%3 = load %any, ptr %v, align 8
|
|
%4 = extractvalue %any %3, 1
|
|
%5 = inttoptr i64 %4 to ptr
|
|
%6 = load ptr, ptr %.cachedtype, align 8
|
|
%7 = icmp eq ptr %5, %6
|
|
br i1 %7, label %cache_hit, label %cache_miss
|
|
|
|
cache_miss: ; preds = %after_check2
|
|
%8 = call ptr @.dyn_search(ptr %5, ptr @"$sel.do_something")
|
|
store ptr %8, ptr %.inlinecache, align 8
|
|
store ptr %5, ptr %.cachedtype, align 8
|
|
br label %10
|
|
|
|
cache_hit: ; preds = %after_check2
|
|
%9 = load ptr, ptr %.inlinecache, align 8
|
|
br label %10
|
|
|
|
10: ; preds = %cache_hit, %cache_miss
|
|
%fn_phi = phi ptr [ %9, %cache_hit ], [ %8, %cache_miss ]
|
|
store ptr %fn_phi, ptr %x, align 8
|
|
br label %phi_try_catch
|
|
|
|
catch_landing: ; preds = %after_assign
|
|
br label %phi_try_catch
|
|
|
|
phi_try_catch: ; preds = %catch_landing, %10
|
|
%val = phi i1 [ true, %10 ], [ false, %catch_landing ]
|
|
br i1 %val, label %if.exit, label %if.else
|
|
|
|
if.else: ; preds = %phi_try_catch
|
|
%11 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.1, i64 39, ptr null, i64 0)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.else, %phi_try_catch
|
|
ret void
|
|
}
|