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 &center, 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

Reply via email to