Hello,

This is a fix for PR16537.  As described in the bug, the TR1 definition of POD
should be used for the purposes of layout even when in C++11 mode.  However,
when determining if a structure is PlainOldData  (i.e., when calculating
data().PlainOldData in lib/AST/DeclCXX.cpp) the method isPODType() is called
and isPODType() will call either isCXX98PODType() or isCXX11PODType depending
on LangOpts.  The effect of this is that when compiling in C++11 mode,
sometimes the TR1 definition of POD will be used and in other cases the C++11
definition of POD will be used.

The attached patch explicitly calls isCXX98PodType() which I believe is the
right thing to do.  (Note, isCXX98PodType() calls isPOD(), which just queries
data().plainOldLayout, which means that PlainOldData should not be dependent on
the LangOpts otherwise isCXX98PodType() will not always return the correct
result when compiling in C++11 mode.)

This issue introduced a C++ ABI difference between 3.1 and 3.2 which affected
how tail padding was re-used when compiling in C++11 mode.  The proposed patch
would fix the ABI, but this means there would be an ABI difference between 3.3
and 3.4.  I think a change like this would warrant a mention in the release
notes.  Should I include a patch that updates the release notes?  What is the
procedure in this type of situation?

Thanks,
Josh

http://llvm-reviews.chandlerc.com/D1181

Files:
  lib/AST/DeclCXX.cpp
  test/SemaCXX/class-layout.cpp
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -662,7 +662,7 @@
       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()) {
Index: test/SemaCXX/class-layout.cpp
===================================================================
--- test/SemaCXX/class-layout.cpp
+++ test/SemaCXX/class-layout.cpp
@@ -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++11
 // expected-no-diagnostics
 
 #define SA(n, p) int a##n[(p) ? 1 : -1]
@@ -103,3 +104,469 @@
 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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to