[Sema] Teach CheckPlaceholderExpr about unaddressable functions.
Given the following C++:
```
void foo();
void foo() __attribute__((enable_if(false, "")));
bool bar() {
auto P = foo;
return P == foo;
}
```
We'll currently happily (and correctly) resolve `foo` to the `foo`
overload without `enable_if` when assigning to `P`. However, we'll
complain about an ambiguous overload on the `P == foo` line, because
`Sema::CheckPlaceholderExpr` doesn't recognize that there's only one
`foo` that could possibly work here.
This patch teaches `Sema::CheckPlaceholderExpr` how to properly deal
with such cases.
Grepping for other callers of things like
`Sema::ResolveAndFixSingleFunctionTemplateSpecialization`, it *looks*
like this is the last place that needed to be fixed up. If I'm wrong,
I'll see if there's something we can do that beats what amounts to
whack-a-mole with bugs.
llvm-svn: 272080
diff --git a/clang/test/SemaCXX/unaddressable-functions.cpp b/clang/test/SemaCXX/unaddressable-functions.cpp
index 823f1be..286cbee 100644
--- a/clang/test/SemaCXX/unaddressable-functions.cpp
+++ b/clang/test/SemaCXX/unaddressable-functions.cpp
@@ -100,3 +100,48 @@
auto PtrOk = &foo<int>;
auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
}
+
+namespace pointer_equality {
+ using FnTy = void (*)();
+
+ void bothEnableIf() __attribute__((enable_if(false, "")));
+ void bothEnableIf() __attribute__((enable_if(true, "")));
+
+ void oneEnableIf() __attribute__((enable_if(false, "")));
+ void oneEnableIf();
+
+ void test() {
+ FnTy Fn;
+ (void)(Fn == bothEnableIf);
+ (void)(Fn == &bothEnableIf);
+ (void)(Fn == oneEnableIf);
+ (void)(Fn == &oneEnableIf);
+ }
+
+ void unavailableEnableIf() __attribute__((enable_if(false, "")));
+ void unavailableEnableIf() __attribute__((unavailable("noooo"))); // expected-note 2{{marked unavailable here}}
+
+ void testUnavailable() {
+ FnTy Fn;
+ (void)(Fn == unavailableEnableIf); // expected-error{{is unavailable}}
+ (void)(Fn == &unavailableEnableIf); // expected-error{{is unavailable}}
+ }
+
+ class Foo {
+ static void staticAccessEnableIf(); // expected-note 2{{declared private here}}
+ void accessEnableIf(); // expected-note{{declared private here}}
+
+ public:
+ static void staticAccessEnableIf() __attribute__((enable_if(false, "")));
+ void accessEnableIf() __attribute__((enable_if(false, "")));
+ };
+
+ void testAccess() {
+ FnTy Fn;
+ (void)(Fn == Foo::staticAccessEnableIf); // expected-error{{is a private member}}
+ (void)(Fn == &Foo::staticAccessEnableIf); // expected-error{{is a private member}}
+
+ void (Foo::*MemFn)();
+ (void)(MemFn == &Foo::accessEnableIf); // expected-error{{is a private member}}
+ }
+}