if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
return;
- if (E->isValueDependent()) {
- if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
- if (!TND->getUnderlyingType()->isDependentType()) {
- S.Diag(AL.getLoc(), diag::err_alignment_dependent_typedef_name)
- << E->getSourceRange();
- return;
- }
- }
- }
-
S.AddAlignedAttr(AL.getRange(), D, E, AL.getAttributeSpellingListIndex(),
AL.isPackExpansion());
}
}
}
- if (E->isTypeDependent() || E->isValueDependent()) {
+ if (E->isValueDependent()) {
+ // We can't support a dependent alignment on a non-dependent type,
+ // because we have no way to model that a type is "alignment-dependent"
+ // but not dependent in any other way.
+ if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
+ if (!TND->getUnderlyingType()->isDependentType()) {
+ Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
+ << E->getSourceRange();
+ return;
+ }
+ }
+
// Save dependent expressions in the AST to be instantiated.
AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
AA->setPackExpansion(IsPackExpansion);
--- /dev/null
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+typedef int A alignas(4); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
+template<int N> void f() {
+ typedef int B alignas(N); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
+}