https://github.com/mark-de-wever-sonarsource updated https://github.com/llvm/llvm-project/pull/142338
>From 930e073e4d5bfbde8028fbb8330e6b91348cc20b Mon Sep 17 00:00:00 2001 From: Mark de Wever <mark.dewe...@sonarsource.com> Date: Mon, 2 Jun 2025 08:57:59 +0200 Subject: [PATCH 1/2] Fix crash on template-specialization This applies the name restoration as suggested by Richard Smith. Fixes: #54279 --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 +++++ clang/test/CodeGenCXX/constructor-init.cpp | 2 +- clang/test/SemaTemplate/default-arguments.cpp | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 174c8fc59e4fa..9853466e01496 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -34,6 +34,7 @@ #include "clang/Sema/SemaSwift.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateInstCallback.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/TimeProfiler.h" #include <optional> @@ -5120,6 +5121,10 @@ bool Sema::addInstantiatedParametersToScope( // Simple case: not a parameter pack. assert(FParamIdx < Function->getNumParams()); ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); + DeclarationName name = FunctionParam->getDeclName(); + auto _ = llvm::make_scope_exit([&]() { + FunctionParam->setDeclName(name); + }); FunctionParam->setDeclName(PatternParam->getDeclName()); // If the parameter's type is not dependent, update it to match the type // in the pattern. They can differ in top-level cv-qualifiers, and we want diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp index f191599f360e7..b5f4cc0b3d6c8 100644 --- a/clang/test/CodeGenCXX/constructor-init.cpp +++ b/clang/test/CodeGenCXX/constructor-init.cpp @@ -160,7 +160,7 @@ template<typename T> struct X; // Make sure that the instantiated constructor initializes start and // end properly. -// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(ptr {{[^,]*}} %this, ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %other) unnamed_addr +// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(ptr {{[^,]*}} %this, ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %0) unnamed_addr // CHECK: {{store.*null}} // CHECK: {{store.*null}} // CHECK: ret diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index 5ea34c0254ec1..a366c3d8ab722 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -283,3 +283,12 @@ static_assert(S<short *>().SizeOfT<char>() == sizeof(short *), ""); } // namespace GH68490 #endif + +namespace PR54279 { +// Using a different name for the argument when there is a default argument +// caused a crash. +template <typename T> void f(const T &a, int c = 0); +template <> void f(const int &unused, int) { + f(42); +} +} >From 25d0d5dace764977949e91a1a65d81dc79239bb8 Mon Sep 17 00:00:00 2001 From: Mark de Wever <mark.dewe...@sonarsource.com> Date: Tue, 3 Jun 2025 16:58:53 +0200 Subject: [PATCH 2/2] Address review comments --- clang/docs/ReleaseNotes.rst | 1 + .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +- clang/test/SemaTemplate/default-arguments.cpp | 40 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 32266fce4d3cb..810b725c2a456 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -805,6 +805,7 @@ Bug Fixes to C++ Support - Clang modules now allow a module and its user to differ on TrivialAutoVarInit* - Fixed an access checking bug when initializing non-aggregates in default arguments (#GH62444), (#GH83608) - Fixed a pack substitution bug in deducing class template partial specializations. (#GH53609) +- Fixed a crash when specializing a template function whose primary template has a default argument (#GH54279) (#GH95420) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 9853466e01496..f926b0458ff9e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5121,9 +5121,9 @@ bool Sema::addInstantiatedParametersToScope( // Simple case: not a parameter pack. assert(FParamIdx < Function->getNumParams()); ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); - DeclarationName name = FunctionParam->getDeclName(); + DeclarationName Name = FunctionParam->getDeclName(); auto _ = llvm::make_scope_exit([&]() { - FunctionParam->setDeclName(name); + FunctionParam->setDeclName(Name); }); FunctionParam->setDeclName(PatternParam->getDeclName()); // If the parameter's type is not dependent, update it to match the type diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index a366c3d8ab722..35ff6daa8a1dd 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -292,3 +292,43 @@ template <> void f(const int &unused, int) { f(42); } } + +namespace PR54279 { +template <int> struct a {}; +namespace b { +template <int c> +void e(a<c> &, const int ¢er, double, double, unsigned, bool = 0); +template <int c> void d(a<c> &, double, double, double, unsigned, bool); +} // namespace b +struct g { + g(int center = 0); + int center; +}; +namespace b { +template <> void e(a<3> &, const int &f, double, double, unsigned, bool) { + a<3> h; + e(h, 0, 0, 0, 0); +} +template <> void d(a<0> &, double, double, double, unsigned, bool); +} // namespace b +} + +namespace PR95420 { +template <typename _Container> +constexpr auto +size(const _Container &__cont) noexcept -> decltype(__cont.size0); + +struct A { + A* data[2]; +}; + +template <typename T> +void f1(unsigned long, const A& f, const A& b = {}); + +template <> +void f1<A>(unsigned long size, const A& f, const A& b) { // We also need b + f1<A>(0, *f.data[0]); // We still need this line + + size; // Changing the name of size prevents crash +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits