@@ -145,7 +145,7 @@ fn function_pointer_method_with_input_output_inout() {
145
145
store i16 0, i16* %localInOutVariable, align 2
146
146
store void (%FbA*, i16, i16*, i16*)* @FbA__foo, void (%FbA*, i16, i16*, i16*)** %fnPtr, align 8
147
147
%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)
149
149
%2 = load void (%FbA*, i16, i16*, i16*)*, void (%FbA*, i16, i16*, i16*)** %fnPtr, align 8
150
150
%load_localInVariable = load i16, i16* %localInVariable, align 2
151
151
call void %2(%FbA* %instanceFbA, i16 %load_localInVariable, i16* %localOutVariable, i16* %localInOutVariable)
@@ -591,3 +591,90 @@ fn user_defined_virtual_table_calls() {
591
591
attributes #0 = { argmemonly nofree nounwind willreturn }
592
592
"# ) ;
593
593
}
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