[llvm-branch-commits] [clang] 088f336 - [CodeGen][ARM] Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Nov 29 02:06:14 PST 2022


Author: yronglin
Date: 2022-11-29T11:05:58+01:00
New Revision: 088f33605d8a61ff519c580a71b1dd57d16a03f8

URL: https://github.com/llvm/llvm-project/commit/088f33605d8a61ff519c580a71b1dd57d16a03f8
DIFF: https://github.com/llvm/llvm-project/commit/088f33605d8a61ff519c580a71b1dd57d16a03f8.diff

LOG: [CodeGen][ARM] Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg

Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg

Open issue: https://github.com/llvm/llvm-project/issues/58794

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D138137

(cherry picked from commit 80f444646c62ccc8b2399d60ac91e62e6e576da6)

Added: 
    clang/test/CodeGen/arm-vaarg.c

Modified: 
    clang/lib/CodeGen/TargetInfo.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 36e10e4df4c19..44743fa0206f4 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -7047,10 +7047,10 @@ Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
 
   // Empty records are ignored for parameter passing purposes.
   if (isEmptyRecord(getContext(), Ty, true)) {
-    Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
-                           getVAListElementType(CGF), SlotSize);
-    Addr = CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
-    return Addr;
+    VAListAddr = CGF.Builder.CreateElementBitCast(VAListAddr, CGF.Int8PtrTy);
+    auto *Load = CGF.Builder.CreateLoad(VAListAddr);
+    Address Addr = Address(Load, CGF.Int8Ty, SlotSize);
+    return CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
   }
 
   CharUnits TySize = getContext().getTypeSizeInChars(Ty);

diff  --git a/clang/test/CodeGen/arm-vaarg.c b/clang/test/CodeGen/arm-vaarg.c
new file mode 100644
index 0000000000000..4dab397a20de4
--- /dev/null
+++ b/clang/test/CodeGen/arm-vaarg.c
@@ -0,0 +1,23 @@
+// RUN: %clang -Xclang -no-opaque-pointers -mfloat-abi=soft -target arm-linux-gnu -emit-llvm -S -o - %s | FileCheck %s
+
+struct Empty {};
+
+struct Empty emptyvar;
+
+void take_args(int a, ...) {
+// CHECK: [[ALLOCA_VA_LIST:%[a-zA-Z0-9._]+]] = alloca %struct.__va_list, align 4
+// CHECK: call void @llvm.va_start
+// CHECK-NEXT: [[AP_ADDR:%[a-zA-Z0-9._]+]] = bitcast %struct.__va_list* [[ALLOCA_VA_LIST]] to i8**
+// CHECK-NEXT: [[LOAD_AP:%[a-zA-Z0-9._]+]] = load i8*, i8** [[AP_ADDR]], align 4
+// CHECK-NEXT: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* [[LOAD_AP]] to %struct.Empty*
+
+  // It's conceivable that EMPTY_PTR may not actually be a valid pointer
+  // (e.g. it's at the very bottom of the stack and the next page is
+  // invalid). This doesn't matter provided it's never loaded (there's no
+  // well-defined way to tell), but it becomes a problem if we do try to use it.
+// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]]
+  __builtin_va_list l;
+  __builtin_va_start(l, a);
+  emptyvar = __builtin_va_arg(l, struct Empty);
+  __builtin_va_end(l);
+}


        


More information about the llvm-branch-commits mailing list