]> granicus.if.org Git - clang/commitdiff
[Sema] Don't permit dependent alignments on non-dependent typedef-names
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 7 Apr 2015 02:37:09 +0000 (02:37 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 7 Apr 2015 02:37:09 +0000 (02:37 +0000)
A dependent alignment attribute (like __attribute__((aligned(...))) or
__declspec(align(...))) on a non-dependent typedef or using declaration
poses a considerable challenge: the type is _not_ dependent, the size
_may_ be dependent if the type is used as an array type, the alignment
_is_ dependent.

It is reasonable for a compiler to be able to query the size and
alignment of a complete type.  Let's help that become an invariant.

This fixes PR22042.

Differential Revision: http://reviews.llvm.org/D8693

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/alignof.cpp

index bf0a4608e9575f34e2f3bb0bb788cb50dad4a83c..03635ab3e2943c800a38bc499808de35766d3d7a 100644 (file)
@@ -2134,6 +2134,8 @@ def error_cannot_find_suitable_accessor : Error<
 
 def err_alignment_not_power_of_two : Error<
   "requested alignment is not a power of 2">;
+def err_alignment_dependent_typedef_name : Error<
+  "requested alignment is dependent but declaration is not dependent">;
 
 def err_attribute_aligned_too_great : Error<
   "requested alignment must be %0 bytes or smaller">;
index 4ef62b9bb5d858534ba6d06eb636288e89acf958..05a81a82931c5aa705400546c4c4caeb0c434672 100644 (file)
@@ -2863,6 +2863,16 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
     return;
 
+  if (E->isValueDependent()) {
+    if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
+      if (!TND->getUnderlyingType()->isDependentType()) {
+        S.Diag(Attr.getLoc(), diag::err_alignment_dependent_typedef_name)
+            << E->getSourceRange();
+        return;
+      }
+    }
+  }
+
   S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
                    Attr.isPackExpansion());
 }
index f51146ccd3cda7fc1a6140047da76222f76fdb7c..e3690ea926a253dd3b46a0bd8f388e4efa4c30e0 100644 (file)
@@ -84,3 +84,16 @@ template <typename T> void n(T) {
   static_assert(sizeof(k) == alignof(long long), "");
 }
 template void n(long long);
+
+namespace PR22042 {
+template <typename T>
+void Fun(T A) {
+  typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}}
+  int k1[__alignof__(T1)];
+}
+
+template <int N>
+struct S {
+  typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}}
+};
+}