Skip to content

Commit 2930421

Browse files
committed
fix: Return of aggregate values in function pointer calls
Adjusted the AggregateTypeLowerer for function pointer calls
1 parent e73887c commit 2930421

File tree

6 files changed

+611
-28
lines changed

6 files changed

+611
-28
lines changed

src/codegen/tests/function_pointer_tests.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ fn function_pointer_method_with_input_output_inout() {
145145
store i16 0, i16* %localInOutVariable, align 2
146146
store void (%FbA*, i16, i16*, i16*)* @FbA__foo, void (%FbA*, i16, i16*, i16*)** %fnPtr, align 8
147147
%1 = load void (%FbA*, i16, i16*, i16*)*, void (%FbA*, i16, i16*, i16*)** %fnPtr, align 8
148-
call void %1(%FbA* %instanceFbA, i32 12345, i16* %localOutVariable, i16* %localInOutVariable)
148+
call void %1(%FbA* %instanceFbA, i16 12345, i16* %localOutVariable, i16* %localInOutVariable)
149149
%2 = load void (%FbA*, i16, i16*, i16*)*, void (%FbA*, i16, i16*, i16*)** %fnPtr, align 8
150150
%load_localInVariable = load i16, i16* %localInVariable, align 2
151151
call void %2(%FbA* %instanceFbA, i16 %load_localInVariable, i16* %localOutVariable, i16* %localInOutVariable)
@@ -591,3 +591,90 @@ fn user_defined_virtual_table_calls() {
591591
attributes #0 = { argmemonly nofree nounwind willreturn }
592592
"#);
593593
}
594+
595+
#[test]
596+
fn function_pointer_aggregate_return() {
597+
let result = codegen(
598+
r"
599+
FUNCTION_BLOCK FbA
600+
METHOD foo: STRING
601+
foo := 'aaaaa';
602+
END_METHOD
603+
END_FUNCTION_BLOCK
604+
605+
FUNCTION main
606+
VAR
607+
instanceFbA: FbA;
608+
fooPtr: POINTER TO FbA.foo;
609+
result: STRING;
610+
END_VAR
611+
612+
result := fooPtr^(instanceFbA);
613+
END_FUNCTION
614+
",
615+
);
616+
617+
filtered_assert_snapshot!(result, @r#"
618+
; ModuleID = '<internal>'
619+
source_filename = "<internal>"
620+
target datalayout = "[filtered]"
621+
target triple = "[filtered]"
622+
623+
%FbA = type {}
624+
625+
@__FbA__init = unnamed_addr constant %FbA zeroinitializer
626+
@utf08_literal_0 = private unnamed_addr constant [6 x i8] c"aaaaa\00"
627+
628+
define void @FbA(%FbA* %0) {
629+
entry:
630+
%this = alloca %FbA*, align 8
631+
store %FbA* %0, %FbA** %this, align 8
632+
ret void
633+
}
634+
635+
define void @FbA__foo(%FbA* %0, i8* %1) {
636+
entry:
637+
%this = alloca %FbA*, align 8
638+
store %FbA* %0, %FbA** %this, align 8
639+
%foo = alloca i8*, align 8
640+
store i8* %1, i8** %foo, align 8
641+
%deref = load i8*, i8** %foo, align 8
642+
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %deref, i8* align 1 getelementptr inbounds ([6 x i8], [6 x i8]* @utf08_literal_0, i32 0, i32 0), i32 6, i1 false)
643+
ret void
644+
}
645+
646+
define void @main() {
647+
entry:
648+
%instanceFbA = alloca %FbA, align 8
649+
%fooPtr = alloca void (%FbA*, [81 x i8]*)*, align 8
650+
%result = alloca [81 x i8], align 1
651+
%0 = bitcast %FbA* %instanceFbA to i8*
652+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 bitcast (%FbA* @__FbA__init to i8*), i64 ptrtoint (%FbA* getelementptr (%FbA, %FbA* null, i32 1) to i64), i1 false)
653+
store void (%FbA*, [81 x i8]*)* null, void (%FbA*, [81 x i8]*)** %fooPtr, align 8
654+
%1 = bitcast [81 x i8]* %result to i8*
655+
call void @llvm.memset.p0i8.i64(i8* align 1 %1, i8 0, i64 ptrtoint ([81 x i8]* getelementptr ([81 x i8], [81 x i8]* null, i32 1) to i64), i1 false)
656+
%__0 = alloca [81 x i8], align 1
657+
%2 = bitcast [81 x i8]* %__0 to i8*
658+
call void @llvm.memset.p0i8.i64(i8* align 1 %2, i8 0, i64 ptrtoint ([81 x i8]* getelementptr ([81 x i8], [81 x i8]* null, i32 1) to i64), i1 false)
659+
%3 = load void (%FbA*, [81 x i8]*)*, void (%FbA*, [81 x i8]*)** %fooPtr, align 8
660+
%4 = bitcast [81 x i8]* %__0 to i8*
661+
call void %3(%FbA* %instanceFbA, i8* %4)
662+
%5 = bitcast [81 x i8]* %result to i8*
663+
%6 = bitcast [81 x i8]* %__0 to i8*
664+
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %5, i8* align 1 %6, i32 80, i1 false)
665+
ret void
666+
}
667+
668+
; Function Attrs: argmemonly nofree nounwind willreturn
669+
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #0
670+
671+
; Function Attrs: argmemonly nofree nounwind willreturn
672+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
673+
674+
; Function Attrs: argmemonly nofree nounwind willreturn writeonly
675+
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
676+
677+
attributes #0 = { argmemonly nofree nounwind willreturn }
678+
attributes #1 = { argmemonly nofree nounwind willreturn writeonly }
679+
"#);
680+
}

0 commit comments

Comments
 (0)