diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-29 23:02:58 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-29 23:02:58 +0000 |
commit | 272324bc881450a71873d2f4e72f17837d8998df (patch) | |
tree | 1079fd31f3d8a8c9223c61720ab58b8e05c881d0 | |
parent | c8b09a1fa2112964496f27094010bae45c97c42a (diff) |
Fix PR8796.
The problem was that we were asserting the we never added an empty class
to the same offset twice. This is not true for unions, where two members, empty
or not, can have the some offset.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122633 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 8 | ||||
-rw-r--r-- | test/CodeGenCXX/empty-classes.cpp | 13 |
2 files changed, 18 insertions, 3 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 34d4a7e586..143fc61da2 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -216,10 +216,12 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, if (!RD->isEmpty()) return; + // If we have empty structures inside an union, we can assign both + // the same offset. Just avoid pushing them twice in the list. ClassVectorTy& Classes = EmptyClassOffsets[Offset]; - assert(std::find(Classes.begin(), Classes.end(), RD) == Classes.end() && - "Duplicate empty class detected!"); - + if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end()) + return; + Classes.push_back(RD); // Update the empty class offset. diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp index 59124e3d55..1ce1dad40f 100644 --- a/test/CodeGenCXX/empty-classes.cpp +++ b/test/CodeGenCXX/empty-classes.cpp @@ -53,6 +53,19 @@ int f() { return 0; } +namespace PR8796 { + struct FreeCell { + }; + union ThingOrCell { + FreeCell t; + FreeCell cell; + }; + struct Things { + ThingOrCell things; + }; + Things x; +} + #ifdef HARNESS extern "C" void printf(const char *, ...); |