Author: Younan Zhang
Date: 2026-01-20T10:13:41+08:00
New Revision: 53ae317ed28b71c991309d38a7171a3173f364d7

URL: 
https://github.com/llvm/llvm-project/commit/53ae317ed28b71c991309d38a7171a3173f364d7
DIFF: 
https://github.com/llvm/llvm-project/commit/53ae317ed28b71c991309d38a7171a3173f364d7.diff

LOG: [Clang] Check enable_if attribute without delayed diagnostics (#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

Fixes https://github.com/llvm/llvm-project/issues/175895

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaOverload.cpp
    clang/test/SemaCXX/enable_if.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b75715e873c50..100474a5a1777 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -131,6 +131,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..a4f6b23066736 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7551,6 +7551,12 @@ 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 UndelayDiags(
+      [&, 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