diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4139d1d80ed4..c9d21558c94f 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 7115b8b7d446..5592cd254535 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -7551,6 +7551,8 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, return nullptr; SFINAETrap Trap(*this); + // Switching the DC to ensure the immediate access control checking. + ContextRAII SavedContext(*this, Function->getDeclContext()); SmallVector 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 1c307881e5d4..845ccf00864a 100644 --- a/clang/test/SemaCXX/enable_if.cpp +++ b/clang/test/SemaCXX/enable_if.cpp @@ -562,6 +562,41 @@ 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(uin64); + auto c = static_cast(deleted); +} + +} + 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}}