https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/176080

We ensure immediate access control checking when evaluating the enable_if 
attribute to rule out inaccessible constructors during potential overload 
resolution, treating them as SFINAE errors rather than hard errors, making the 
behavior more preferable with the nature of the enable_if attribute.

Compared to the last patch, we now avoid switching the DC directly because 
there are cases where we're checking enable_if attribute within a lambda and 
getCurLambda() requires a lambda context to distinguish from template 
instantiation.

This reapplies #175899

>From d226a3881adf29804c129eff5ac67ed2fb95f0a4 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Wed, 14 Jan 2026 15:20:30 +0800
Subject: [PATCH] [Clang] Check enable_if attribute without delayed diagnostics

We ensure immediate access control checking when evaluating the enable_if
attribute to rule out inaccessible constructors during potential overload
resolution, treating them as SFINAE errors rather than hard errors, making
the behavior more preferable with the nature of the enable_if attribute.

Compared to the last patch, we now avoid switching the DC directly because
there are cases where we're checking enable_if attribute within a lambda
and getCurLambda() requires a lambda context to distinguish from
template instantiation.

This reapplies #175899
---
 clang/docs/ReleaseNotes.rst      |  1 +
 clang/lib/Sema/SemaOverload.cpp  |  5 ++++
 clang/test/SemaCXX/enable_if.cpp | 48 ++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b91d99647855c..cd2f4dd581bad 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -120,6 +120,7 @@ Bug Fixes to Compiler Builtins
 
 Bug Fixes to Attribute Support
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a behavioral discrepancy between deleted functions and private members 
when checking the ``enable_if`` attribute. (#GH175895)
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7115b8b7d446a..bc3a5c8e567f0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7551,6 +7551,11 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function,
     return nullptr;
 
   SFINAETrap Trap(*this);
+  // Perform the access checking immediately so any access diagnostics are
+  // caught by the SFINAE trap.
+  llvm::scope_exit _([&, CurrentState(DelayedDiagnostics.pushUndelayed())] {
+    DelayedDiagnostics.popUndelayed(CurrentState);
+  });
   SmallVector<Expr *, 16> ConvertedArgs;
   // FIXME: We should look into making enable_if late-parsed.
   Expr *DiscardedThis;
diff --git a/clang/test/SemaCXX/enable_if.cpp b/clang/test/SemaCXX/enable_if.cpp
index 1c307881e5d4a..4b0a253d89fed 100644
--- a/clang/test/SemaCXX/enable_if.cpp
+++ b/clang/test/SemaCXX/enable_if.cpp
@@ -562,6 +562,54 @@ namespace IgnoreUnusedArgSideEffects {
 #endif
 }
 
+namespace GH175895 {
+
+using int32_t = int;
+
+struct wxuin_t {
+  wxuin_t() {}
+  wxuin_t(int32_t v) __attribute__((enable_if(v == 0, "Expect only constant 
expressions"))) {}
+};
+
+struct wxuin64_t {
+  wxuin64_t() {}
+
+  explicit operator wxuin_t() const { return {}; }
+
+private:
+  operator int() const { return 0; }
+};
+
+struct wxuin64_t_deleted {
+  wxuin64_t_deleted() {}
+
+  explicit operator wxuin_t() const { return {}; }
+
+  operator int() = delete;
+};
+
+void main() {
+  wxuin64_t uin64{};
+  wxuin64_t_deleted deleted{};
+  auto b = static_cast<wxuin_t>(uin64);
+  auto c = static_cast<wxuin_t>(deleted);
+}
+
+namespace Regression {
+
+const int kMaxNumber = 1;
+struct Arg {
+  Arg(int);
+};
+void PlaceholderBitmask();
+void Substitute(Arg) __attribute__((enable_if(PlaceholderBitmask, ""))) {
+  (void)[] { Substitute(kMaxNumber); };
+}
+
+}
+
+}
+
 namespace DefaultArgs {
   void f(int n = __builtin_LINE()) __attribute__((enable_if(n == 12345, "only 
callable on line 12345"))); // expected-note {{only callable on line 12345}}
   void g() { f(); } // expected-error {{no matching function}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to