diff options
| author | Tim Northover <tnorthover@apple.com> | 2017-05-05 22:36:06 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2017-05-05 22:36:06 +0000 |
| commit | 23bcad226c564944d2155b027b9c9fe8a2591d05 (patch) | |
| tree | 8119cddf0382e65ed1af0ec1ff2f662521389d96 /clang/lib/CodeGen/TargetInfo.cpp | |
| parent | ce03732ec85296f942ee6644596056ce5e577f89 (diff) | |
| download | bcm5719-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.cpp | 13 |
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. |

