Author: cor3ntin Date: 2023-11-17T18:16:34+01:00 New Revision: aafad2d214246bae4d53ce3178b11486ebc83890
URL: https://github.com/llvm/llvm-project/commit/aafad2d214246bae4d53ce3178b11486ebc83890 DIFF: https://github.com/llvm/llvm-project/commit/aafad2d214246bae4d53ce3178b11486ebc83890.diff LOG: [Clang] Warn on deprecated specializations used in system headers. (#70353) 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. Added: clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaAvailability.cpp clang/lib/Sema/SemaTemplate.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ee630663ae8013b..52c9d6eb69617b0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -449,6 +449,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. Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5e417228528db32..e6a9d8da6d911cc 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8464,6 +8464,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 766ebd90fded0c4..c188dd34014a4b3 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -11601,3 +11601,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 (const 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..79c9d339b6f2058 --- /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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits