[clang] [Clang] Do not create a NoSFINAETrap for variable specialization. (PR #191000)

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 8 09:02:31 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Corentin Jabot (cor3ntin)

<details>
<summary>Changes</summary>

There is no thing in the standard that says this should happen outside of the immediate context.

Fixes #<!-- -->54439

---
Full diff: https://github.com/llvm/llvm-project/pull/191000.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (-1) 
- (modified) clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (+26) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2da7175b51ea3..34d59171d1905 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -427,6 +427,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when a default argument is passed to an explicit object parameter. (#GH176639)
 - Fixed an alias template CTAD crash.
 - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741)
+- Clang incorrectly instantiated variable specializations outside of the immediate context. (#GH54439)
 - Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class. (#GH176152)
 - Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307)
 - Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable 
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 61878cba32235..09c2482168ab7 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6013,7 +6013,6 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
   if (FromVar->isInvalidDecl())
     return nullptr;
 
-  NonSFINAEContext _(*this);
   InstantiatingTemplate Inst(*this, PointOfInstantiation, FromVar);
   if (Inst.isInvalid())
     return nullptr;
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index aada11dd5f9be..026aa639b34b3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-unused-value -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-unused-value -Wno-c++1y-extensions %s
 // RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wno-unused-value %s
+// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -Wno-unused-value %s
 // RUN: %clang_cc1 -std=c++2c -verify -fsyntax-only -Wno-unused-value %s
 
 
@@ -541,3 +542,28 @@ void test() {
 }
 }
 #endif
+
+#if __cplusplus >= 202002L
+namespace GH54439 {
+template <bool B> struct enable_if {};
+template <> struct enable_if<true> {
+    using type = void;
+};
+template <bool B> using enable_if_t = enable_if<B>::type;
+
+template <typename T> inline constexpr bool dependent_false = false;
+
+template <typename T>
+inline enable_if<dependent_false<T>>::type *is_foo = nullptr;
+
+template <> inline constexpr bool is_foo<int> = true;
+
+template <typename T>
+concept has_is_foo = requires { is_foo<T>; };
+
+static_assert(has_is_foo<int>);
+
+static_assert(not has_is_foo<float>);
+
+}
+#endif

``````````

</details>


https://github.com/llvm/llvm-project/pull/191000


More information about the cfe-commits mailing list