r186741 - Fix bug in computing POD-for-layout.
Eli Friedman
eli.friedman at gmail.com
Fri Jul 19 18:06:31 PDT 2013
Author: efriedma
Date: Fri Jul 19 20:06:31 2013
New Revision: 186741
URL: http://llvm.org/viewvc/llvm-project?rev=186741&view=rev
Log:
Fix bug in computing POD-for-layout.
A class with a field of non-POD-for-layout type is not POD-for-layout.
This computation should not depend on whether the field is of POD type
in the language sense.
Fixes PR16537.
Patch by Josh Magee.
Modified:
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/test/SemaCXX/class-layout.cpp
Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=186741&r1=186740&r2=186741&view=diff
==============================================================================
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Fri Jul 19 20:06:31 2013
@@ -74,6 +74,10 @@ C11 Feature Support
C++ Language Changes in Clang
-----------------------------
+- Fixed an ABI regression, introduced in Clang 3.2, which affected
+ member offsets for classes inheriting from certain classes with tail padding.
+ See PR16537.
+
- ...
C++11 Feature Support
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=186741&r1=186740&r2=186741&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Jul 19 20:06:31 2013
@@ -662,7 +662,7 @@ void CXXRecordDecl::addedMember(Decl *D)
if (!Context.getLangOpts().ObjCAutoRefCount ||
T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
setHasObjectMember(true);
- } else if (!T.isPODType(Context))
+ } else if (!T.isCXX98PODType(Context))
data().PlainOldData = false;
if (T->isReferenceType()) {
Modified: cfe/trunk/test/SemaCXX/class-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class-layout.cpp?rev=186741&r1=186740&r2=186741&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class-layout.cpp (original)
+++ cfe/trunk/test/SemaCXX/class-layout.cpp Fri Jul 19 20:06:31 2013
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++98
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -fsyntax-only -verify -std=c++11
// expected-no-diagnostics
#define SA(n, p) int a##n[(p) ? 1 : -1]
@@ -103,3 +104,469 @@ struct H { G g; };
SA(0, sizeof(H) == 24);
}
+
+namespace PR16537 {
+namespace test1 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test2 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11 __attribute__((aligned(16)));
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test3 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test4 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test5 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct pod_in_11_only2 {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ pod_in_11_only2 two;
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test6 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct pod_in_11_only2 {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct second_base {
+ pod_in_11_only2 two;
+ char foo;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only, public second_base {
+ char may_go_into_tail_padding;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test7 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ pod_in_11_only pod12;
+ char tail_padding;
+ };
+
+ struct might_use_tail_padding : public tail_padded_pod_in_11_only {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 24);
+}
+
+namespace test8 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct another_layer {
+ tail_padded_pod_in_11_only pod;
+ char padding;
+ };
+
+ struct might_use_tail_padding : public another_layer {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 24);
+}
+
+namespace test9 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct tail_padded_pod_in_11_only {
+ pod_in_11_only pod11;
+ char tail_padding;
+ };
+
+ struct another_layer : tail_padded_pod_in_11_only {
+ };
+
+ struct might_use_tail_padding : public another_layer {
+ char may_go_into_tail_padding;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test10 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char b;
+ };
+
+ struct C {
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ char d;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 32);
+}
+
+namespace test11 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char b_pre;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C {
+ char c_pre;
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ char d_pre;
+ pod_in_11_only d;
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+
+ SA(0, sizeof(might_use_tail_padding) == 88);
+}
+
+namespace test12 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a __attribute__((aligned(128)));
+ };
+
+ struct B {
+ char bpad;
+ };
+
+ struct C {
+ char cpad;
+ };
+
+ struct D {
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 128);
+}
+
+namespace test13 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ };
+
+ struct C {
+ char c_pre;
+ pod_in_11_only c;
+ char cpad;
+ };
+
+ struct D {
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 40);
+}
+
+namespace test14 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct might_use_tail_padding : public A {
+ struct {
+ int : 0;
+ } x;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test15 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct might_use_tail_padding : public A {
+ struct {
+ char a:1;
+ char b:2;
+ char c:2;
+ char d:2;
+ char e:1;
+ } x;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 16);
+}
+
+namespace test16 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C : public A, public B {
+ };
+
+ struct D : public C {
+ };
+
+ struct might_use_tail_padding : public D {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 40);
+}
+
+namespace test17 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a __attribute__((aligned(512)));
+ };
+
+ struct B {
+ char bpad;
+ pod_in_11_only foo;
+ char btail;
+ };
+
+ struct C {
+ char cpad;
+ };
+
+ struct D {
+ char dpad;
+ };
+
+ struct might_use_tail_padding : public A, public B, public C, public D {
+ char a;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 512);
+}
+
+namespace test18 {
+ struct pod_in_11_only {
+ private:
+ long long x;
+ };
+
+ struct A {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct A1 {
+ pod_in_11_only a;
+ char apad;
+ };
+
+ struct B1 {
+ char bpod;
+ pod_in_11_only b;
+ char bpad;
+ };
+
+ struct C : public A, public B {
+ };
+
+ struct D : public A1, public B1 {
+ };
+
+ struct E : public D, public C {
+ };
+
+ struct F : public E {
+ };
+
+ struct might_use_tail_padding : public F {
+ char m;
+ };
+ SA(0, sizeof(might_use_tail_padding) == 80);
+}
+} // namespace PR16537
More information about the cfe-commits
mailing list