summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2015-04-26 04:43:26 +0000
committerJohn McCall <rjmccall@apple.com>2015-04-26 04:43:26 +0000
commit9fc700e76d74e1bc57e709ca7b096c7dc7025950 (patch)
treee6427a0bbb36d95f06c24283643502f48df06a82 /clang
parentf26c748b1b0ac9544a09c8cd5f4423cc604fa7b4 (diff)
downloadbcm5719-llvm-9fc700e76d74e1bc57e709ca7b096c7dc7025950.tar.gz
bcm5719-llvm-9fc700e76d74e1bc57e709ca7b096c7dc7025950.zip
Correctly handle zero-sized but non-empty base classes in IRGen.
Fixes rdar://20621065. A more elegant fix would preclude this case by defining the rules such that zero-size classes are always formally empty. I believe the only extensions which create zero-size classes right now are flexible arrays and zero-length arrays; it's not abstractly unreasonable to say that those don't count as members for the purposes of emptiness, just as zero-width bitfields don't count. But that's an ABI-affecting change and requires further discussion; in the meantime, let's not assert / miscompile. llvm-svn: 235815
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp6
-rw-r--r--clang/test/CodeGenCXX/empty-classes.cpp16
2 files changed, 21 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 202ea972f8d..c33d2d9f86d 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -438,8 +438,12 @@ void CGRecordLowering::accumulateBases() {
for (const auto &Base : RD->bases()) {
if (Base.isVirtual())
continue;
+
+ // Bases can be zero-sized even if not technically empty if they
+ // contain only a trailing array member.
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
- if (!BaseDecl->isEmpty())
+ if (!BaseDecl->isEmpty() &&
+ !Context.getASTRecordLayout(BaseDecl).getSize().isZero())
Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl),
MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
}
diff --git a/clang/test/CodeGenCXX/empty-classes.cpp b/clang/test/CodeGenCXX/empty-classes.cpp
index 8491480bcf5..e27a961e123 100644
--- a/clang/test/CodeGenCXX/empty-classes.cpp
+++ b/clang/test/CodeGenCXX/empty-classes.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+// CHECK: %"struct.rdar20621065::B" = type { float, float }
+
struct Empty { };
struct A {
@@ -80,3 +82,17 @@ int main() {
return result;
}
#endif
+
+namespace rdar20621065 {
+ struct A {
+ float array[0];
+ };
+
+ struct B : A {
+ float left;
+ float right;
+ };
+
+ // Type checked at the top of the file.
+ B b;
+};
OpenPOWER on IntegriCloud