From: Richard Smith Date: Fri, 17 Aug 2012 03:20:55 +0000 (+0000) Subject: Don't forget to apply #pragma pack to partial and explicit specializations of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0652c35a303a6186142eea566c88714c59bdc664;p=clang Don't forget to apply #pragma pack to partial and explicit specializations of 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 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c8e4501667..4dbf3e45b3 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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) diff --git a/test/SemaCXX/pragma-pack.cpp b/test/SemaCXX/pragma-pack.cpp index 1bc738b087..5c1d5c6c82 100644 --- a/test/SemaCXX/pragma-pack.cpp +++ b/test/SemaCXX/pragma-pack.cpp @@ -32,3 +32,26 @@ struct Sub : virtual Base { int check[sizeof(Sub) == 13 ? 1 : -1]; } + +namespace llvm_support_endian { + +template struct X; + +#pragma pack(push) +#pragma pack(1) +template struct X { + T t; +}; +#pragma pack(pop) + +#pragma pack(push) +#pragma pack(2) +template<> struct X { + long double c; +}; +#pragma pack(pop) + +int check1[__alignof(X) == 1 ? 1 : -1]; +int check2[__alignof(X) == 2 ? 1 : -1]; + +} diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp index f3ba6468d0..4b539067b1 100644 --- a/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -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