[clang] [Clang] Warn on deprecated specializations used in system headers. (PR #70353)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 26 09:55:07 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: cor3ntin (cor3ntin)
<details>
<summary>Changes</summary>
When the top of the instantiation stack is in user code.
The goal of this PR is to allow deprecation of some char_traits specializations in libc++ as done in https://reviews.llvm.org/D157058 which was later reverted by
https://github.com/llvm/llvm-project/pull/66153#issuecomment-1719578384 as Clang never emitted the libc++ warnings.
Because Clang likes to eagerly instantiate, we can look for the location of the top of the instantiation stack, and emit a warning if that location is in user code.
The warning emission is forced by temporarily instructing the diag engine not to silence warning in system headers.
---
Full diff: https://github.com/llvm/llvm-project/pull/70353.diff
5 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/include/clang/Sema/Sema.h (+2)
- (modified) clang/lib/Sema/SemaAvailability.cpp (+23)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+22)
- (added) clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp (+28)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7238386231e1a28..0c46e0a5912905e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -404,6 +404,8 @@ Improvements to Clang's diagnostics
- ``-Wzero-as-null-pointer-constant`` diagnostic is no longer emitted when using ``__null``
(or, more commonly, ``NULL`` when the platform defines it as ``__null``) to be more consistent
with GCC.
+- Clang will warn on deprecated specializations used in system headers when their instantiation
+ is caused by user code.
Bug Fixes in This Version
-------------------------
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 18ac85011aa752a..1a75fff331add5a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8476,6 +8476,8 @@ class Sema final {
ArrayRef<TemplateArgument> SugaredConverted,
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
+ SourceLocation getTopMostPointOfInstantiation(const NamedDecl *) const;
+
/// Specifies the context in which a particular template
/// argument is being checked.
enum CheckTemplateArgumentKind {
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index 84c06566387ccbe..846a31a79673096 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -536,6 +536,29 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
}
}
+ // We emit deprecation warning for deprecated specializations
+ // when their instantiation stacks originate outside
+ // of a system header, even if the diagnostics is suppresed at the
+ // point of definition.
+ SourceLocation InstantiationLoc =
+ S.getTopMostPointOfInstantiation(ReferringDecl);
+ bool ShouldAllowWarningInSystemHeader =
+ InstantiationLoc != Loc &&
+ !S.getSourceManager().isInSystemHeader(InstantiationLoc);
+ struct AllowWarningInSystemHeaders {
+ AllowWarningInSystemHeaders(DiagnosticsEngine &E,
+ bool AllowWarningInSystemHeaders)
+ : Engine(E), Prev(E.getSuppressSystemWarnings()) {
+ E.setSuppressSystemWarnings(!AllowWarningInSystemHeaders);
+ }
+ ~AllowWarningInSystemHeaders() { Engine.setSuppressSystemWarnings(Prev); }
+
+ private:
+ DiagnosticsEngine &Engine;
+ bool Prev;
+ } SystemWarningOverrideRAII(S.getDiagnostics(),
+ ShouldAllowWarningInSystemHeader);
+
if (!Message.empty()) {
S.Diag(Loc, diag_message) << ReferringDecl << Message << FixIts;
if (ObjCProperty)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c2477ec0063e418..61d034e13b0a292 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -11615,3 +11615,25 @@ void Sema::checkSpecializationReachability(SourceLocation Loc,
Sema::AcceptableKind::Reachable)
.check(Spec);
}
+
+/// Returns the top most location responsible for the definition of \p N.
+/// If \p N is a a template specialization, this is the location
+/// of the top of the instantiation stack.
+/// Otherwise, the location of \p N is returned.
+SourceLocation Sema::getTopMostPointOfInstantiation(const NamedDecl *N) const {
+ if (!getLangOpts().CPlusPlus || CodeSynthesisContexts.empty())
+ return N->getLocation();
+ if (auto *FD = dyn_cast<FunctionDecl>(N)) {
+ if (!FD->isFunctionTemplateSpecialization())
+ return FD->getLocation();
+ } else if (!isa<ClassTemplateSpecializationDecl,
+ VarTemplateSpecializationDecl>(N)) {
+ return N->getLocation();
+ }
+ for (const CodeSynthesisContext &CSC : CodeSynthesisContexts) {
+ if (!CSC.isInstantiationRecord() || CSC.PointOfInstantiation.isInvalid())
+ continue;
+ return CSC.PointOfInstantiation;
+ }
+ return N->getLocation();
+}
diff --git a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
new file mode 100644
index 000000000000000..270e4292bf9a47b
--- /dev/null
+++ b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#ifdef BE_THE_HEADER
+#pragma clang system_header
+
+template <typename T>
+struct traits;
+
+template <>
+struct [[ deprecated]] traits<int> {}; // expected-note {{'traits<int>' has been explicitly marked deprecated here}}
+
+template<typename T, typename Trait = traits<T>> // expected-warning {{'traits<int>' is deprecated}}
+struct basic_string {};
+
+// should not warn, defined and used in system headers
+using __do_what_i_say_not_what_i_do = traits<int> ;
+
+template<typename T, typename Trait = traits<double>>
+struct should_not_warn {};
+
+#else
+#define BE_THE_HEADER
+#include __FILE__
+
+basic_string<int> test1; // expected-note {{in instantiation of default argument for 'basic_string<int>' required here}}
+should_not_warn<int> test2;
+
+#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/70353
More information about the cfe-commits
mailing list