]> granicus.if.org Git - clang/commitdiff
Don't forget to apply #pragma pack to partial and explicit specializations of
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 17 Aug 2012 03:20:55 +0000 (03:20 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 17 Aug 2012 03:20:55 +0000 (03:20 +0000)
class templates. This fixes misalignment issues in llvm/Support/Endian.h when
built by Clang.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162074 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaCXX/pragma-pack.cpp
unittests/Tooling/RecursiveASTVisitorTest.cpp

index c8e45016671d29a30f3334373eac616077867aac..4dbf3e45b38748c9a2f8a94adbf38c816af7df4b 100644 (file)
@@ -5518,6 +5518,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
+  // Add alignment attributes if necessary; these attributes are checked when
+  // the ASTContext lays out the structure.
+  if (TUK == TUK_Definition) {
+    AddAlignmentAttributesForRecord(Specialization);
+    AddMsStructLayoutForRecord(Specialization);
+  }
+
   if (ModulePrivateLoc.isValid())
     Diag(Specialization->getLocation(), diag::err_module_private_specialization)
       << (isPartialSpecialization? 1 : 0)
index 1bc738b087a94c1d15f72e58fc6df868277a72d2..5c1d5c6c82af61337fecfd441aebbfb69b05aad3 100644 (file)
@@ -32,3 +32,26 @@ struct Sub : virtual Base {
 int check[sizeof(Sub) == 13 ? 1 : -1];
 
 }
+
+namespace llvm_support_endian {
+
+template<typename, bool> struct X;
+
+#pragma pack(push)
+#pragma pack(1)
+template<typename T> struct X<T, true> {
+  T t;
+};
+#pragma pack(pop)
+
+#pragma pack(push)
+#pragma pack(2)
+template<> struct X<long double, true> {
+  long double c;
+};
+#pragma pack(pop)
+
+int check1[__alignof(X<int, true>) == 1 ? 1 : -1];
+int check2[__alignof(X<long double, true>) == 2 ? 1 : -1];
+
+}
index f3ba6468d038eda0e589a44357bcae2341081177..4b539067b136df1703e6d8845a5d3fe6b7ebc646 100644 (file)
@@ -385,4 +385,11 @@ TEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) {
       "int main() { Simple s; Simple t(s); }\n"));
 }
 
+TEST(RecursiveASTVisitor, VisitsExtension) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("s", 1, 24);
+  EXPECT_TRUE(Visitor.runOver(
+    "int s = __extension__ (s);\n"));
+}
+
 } // end namespace clang