diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 61629ff30aee..8e24087b3dcd 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -744,6 +744,19 @@ Improvements to Clang's diagnostics - Clang now diagnoses dangling assignments for pointer-like objects (annotated with `[[gsl::Pointer]]`) under `-Wdangling-assignment-gsl` (off by default) Fixes #GH63310. + +- Clang now diagnoses uses of alias templates with a deprecated attribute. (Fixes #GH18236). + + .. code-block:: c++ + + template + struct NoAttr { + }; + + template + using UsingWithAttr __attribute__((deprecated)) = NoAttr; + + UsingWithAttr objUsingWA; // warning: 'UsingWithAttr' is deprecated Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index df83bbfb7aac..17566c226ec8 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -107,6 +107,12 @@ ShouldDiagnoseAvailabilityOfDecl(Sema &S, const NamedDecl *D, break; } + // For alias templates, get the underlying declaration. + if (const auto *ADecl = dyn_cast(D)) { + D = ADecl->getTemplatedDecl(); + Result = D->getAvailability(Message); + } + // Forward class declarations get their attributes from their definition. if (const auto *IDecl = dyn_cast(D)) { if (IDecl->getDefinition()) { diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9d9620162538..87b1f98bbe5a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3344,6 +3344,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, *this, /*PointOfInstantiation=*/TemplateLoc, /*Entity=*/AliasTemplate, /*TemplateArgs=*/TemplateArgLists.getInnermost()); + + // Diagnose uses of this alias. + (void)DiagnoseUseOfDecl(AliasTemplate, TemplateLoc); + if (Inst.isInvalid()) return QualType(); diff --git a/clang/test/SemaTemplate/alias-template-deprecated.cpp b/clang/test/SemaTemplate/alias-template-deprecated.cpp new file mode 100644 index 000000000000..7418e222bcfc --- /dev/null +++ b/clang/test/SemaTemplate/alias-template-deprecated.cpp @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// +// This test checks that a deprecated attribute on an alias +// template triggers a warning diagnostic when it is used. + +template +struct NoAttr { + void foo() {} +}; + +// expected-note@+2 7{{'UsingWithAttr' has been explicitly marked deprecated here}} +template +using UsingWithAttr __attribute__((deprecated)) = NoAttr; + +// expected-note@+1 {{'UsingInstWithAttr' has been explicitly marked deprecated here}} +using UsingInstWithAttr __attribute__((deprecated)) = NoAttr; + +// expected-note@+1 {{'TDWithAttr' has been explicitly marked deprecated here}} +typedef NoAttr TDWithAttr __attribute__((deprecated)); + +// expected-warning@+1 {{'UsingWithAttr' is deprecated}} +typedef UsingWithAttr TDUsingWithAttr; + +typedef NoAttr TDNoAttr; + +// expected-note@+1 {{'UsingTDWithAttr' has been explicitly marked deprecated here}} +using UsingTDWithAttr __attribute__((deprecated)) = TDNoAttr; + +struct S { + NoAttr f1; + // expected-warning@+1 {{'UsingWithAttr' is deprecated}} + UsingWithAttr f2; +}; + +// expected-warning@+1 {{'UsingWithAttr' is deprecated}} +void foo(NoAttr s1, UsingWithAttr s2) { +} + +// expected-note@+2 {{'UsingWithCPPAttr' has been explicitly marked deprecated here}} +template +using UsingWithCPPAttr [[deprecated]] = NoAttr; + +// expected-note@+1 {{'UsingInstWithCPPAttr' has been explicitly marked deprecated here}} +using UsingInstWithCPPAttr [[deprecated("Do not use this")]] = NoAttr; + +void bar() { + NoAttr obj; // Okay + + // expected-warning@+2 {{'UsingWithAttr' is deprecated}} + // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + UsingWithAttr objUsingWA; + + // expected-warning@+2 {{'UsingWithAttr' is deprecated}} + // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + NoAttr> s; + + // expected-note@+1 {{'DepInt' has been explicitly marked deprecated here}} + using DepInt [[deprecated]] = int; + // expected-warning@+3 {{'UsingWithAttr' is deprecated}} + // expected-warning@+2 {{'DepInt' is deprecated}} + // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + using X = UsingWithAttr; + + // expected-warning@+2 {{'UsingWithAttr' is deprecated}} + // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + UsingWithAttr().foo(); + + // expected-warning@+1 {{'UsingInstWithAttr' is deprecated}} + UsingInstWithAttr objUIWA; + + // expected-warning@+1 {{'TDWithAttr' is deprecated}} + TDWithAttr objTDWA; + + // expected-warning@+1 {{'UsingTDWithAttr' is deprecated}} + UsingTDWithAttr objUTDWA; + + // expected-warning@+2 {{'UsingWithCPPAttr' is deprecated}} + // expected-note@+1 {{in instantiation of template type alias 'UsingWithCPPAttr' requested here}} + UsingWithCPPAttr objUsingWCPPA; + + // expected-warning@+1 {{'UsingInstWithCPPAttr' is deprecated: Do not use this}} + UsingInstWithCPPAttr objUICPPWA; +}