summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-05-05 22:36:06 +0000
committerTim Northover <tnorthover@apple.com>2017-05-05 22:36:06 +0000
commit23bcad226c564944d2155b027b9c9fe8a2591d05 (patch)
tree8119cddf0382e65ed1af0ec1ff2f662521389d96 /clang/lib/CodeGen/TargetInfo.cpp
parentce03732ec85296f942ee6644596056ce5e577f89 (diff)
downloadbcm5719-llvm-23bcad226c564944d2155b027b9c9fe8a2591d05.tar.gz
bcm5719-llvm-23bcad226c564944d2155b027b9c9fe8a2591d05.zip
AArch64: fix weird edge case in ABI.
It turns out there are some sort-of-but-not-quite empty structs that break all the rules. For example: struct SuperEmpty { int arr[0]; }; struct SortOfEmpty { struct SuperEmpty e; }; Both of these have sizeof == 0, even in C++ mode, for GCC compatibility. The first one also doesn't occupy a register when passed by value in GNU C++ mode, unlike everything else. On Darwin, we want to ignore the lot (and especially don't want to try to use an i0 as we were). llvm-svn: 302313
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index ecd81d84b1f..4ebbef7dfb5 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -4890,10 +4890,16 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
// Empty records are always ignored on Darwin, but actually passed in C++ mode
// elsewhere for GNU compatibility.
- if (isEmptyRecord(getContext(), Ty, true)) {
+ uint64_t Size = getContext().getTypeSize(Ty);
+ bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
+ if (IsEmpty || Size == 0) {
if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
return ABIArgInfo::getIgnore();
+ // GNU C mode. The only argument that gets ignored is an empty one with size
+ // 0.
+ if (IsEmpty && Size == 0)
+ return ABIArgInfo::getIgnore();
return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
}
@@ -4906,7 +4912,6 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
}
// Aggregates <= 16 bytes are passed directly in registers or on the stack.
- uint64_t Size = getContext().getTypeSize(Ty);
if (Size <= 128) {
// On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
// same size and alignment.
@@ -4946,7 +4951,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
: ABIArgInfo::getDirect());
}
- if (isEmptyRecord(getContext(), RetTy, true))
+ uint64_t Size = getContext().getTypeSize(RetTy);
+ if (isEmptyRecord(getContext(), RetTy, true) || Size == 0)
return ABIArgInfo::getIgnore();
const Type *Base = nullptr;
@@ -4956,7 +4962,6 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
return ABIArgInfo::getDirect();
// Aggregates <= 16 bytes are returned directly in registers or on the stack.
- uint64_t Size = getContext().getTypeSize(RetTy);
if (Size <= 128) {
// On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
// same size and alignment.
OpenPOWER on IntegriCloud