Correct class-template deprecation behavior-REDUX
Correct class-template deprecation behavior
Based on the comment in the test, and my reading of the standard, a deprecated warning should be issued in the following case:
template<typename T> [[deprecated]] class Foo{}; Foo<int> f;
This was not the case, because the ClassTemplateSpecializationDecl creation did not also copy the deprecated attribute.
Note: I did NOT audit the complete set of attributes to see WHICH ones should be copied, so instead I simply copy ONLY the deprecated attribute.
Previous DiffRev: https://reviews.llvm.org/D27486, was reverted.
This patch fixes the issues brought up here by the reverter: https://reviews.llvm.org/rL298410
Differential Revision: https://reviews.llvm.org/D31245
llvm-svn: 298634
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index cab55ea..d75d705 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -328,6 +328,34 @@
Attr.getRange());
}
+static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) {
+ if (!D->hasAttrs() || NewAttr->duplicatesAllowed())
+ return false;
+ return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) {
+ return Attr->getKind() == NewAttr->getKind();
+ }) != D->getAttrs().end();
+}
+
+void Sema::InstantiateAttrsForDecl(
+ const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
+ Decl *New, LateInstantiatedAttrVec *LateAttrs,
+ LocalInstantiationScope *OuterMostScope) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) {
+ for (const auto *TmplAttr : Tmpl->attrs()) {
+ // FIXME: If any of the special case versions from InstantiateAttrs become
+ // applicable to template declaration, we'll need to add them here.
+ CXXThisScopeRAII ThisScope(
+ *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()),
+ /*TypeQuals*/ 0, ND->isCXXInstanceMember());
+
+ Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
+ TmplAttr, Context, *this, TemplateArgs);
+ if (NewAttr && !DeclContainsAttr(New, NewAttr))
+ New->addAttr(NewAttr);
+ }
+ }
+}
+
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
const Decl *Tmpl, Decl *New,
LateInstantiatedAttrVec *LateAttrs,
@@ -421,7 +449,8 @@
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
*this, TemplateArgs);
- if (NewAttr)
+
+ if (NewAttr && !DeclContainsAttr(New, NewAttr))
New->addAttr(NewAttr);
}
}