From 8d08b9b408ca26c1a865f2d4c61ba4426b95062a Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 27 Aug 2010 09:08:28 +0000 Subject: Propagate whether an id-expression is the immediate argument of an '&' expression from the second caller of ActOnIdExpression. Teach template argument deduction that an overloaded id-expression doesn't give a valid type for deduction purposes to a non-static member function unless the expression has the correct syntactic form. Teach ActOnIdExpression that it shouldn't try to create implicit member expressions for '&function', because this isn't a permitted form of use for member functions. Teach CheckAddressOfOperand to diagnose these more carefully. Some of these cases aren't reachable right now because earlier diagnostics interrupt them. llvm-svn: 112258 --- clang/test/SemaCXX/member-pointer.cpp | 67 +++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'clang/test/SemaCXX/member-pointer.cpp') diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index 9d5cd2fc927..83823f69c63 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -79,7 +79,7 @@ void g() { void (HasMembers::*pmf)() = &HasMembers::f; void (*pnf)() = &Fake::f; - &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}} + &hm.f; // expected-error {{cannot create a non-constant pointer to member function}} void (HasMembers::*pmgv)() = &HasMembers::g; void (HasMembers::*pmgi)(int) = &HasMembers::g; @@ -142,8 +142,8 @@ namespace pr5985 { void f() { void (c::*p)(); p = &h; // expected-error {{must explicitly qualify}} - p = &this->h; // expected-error {{must explicitly qualify}} - p = &(*this).h; // expected-error {{must explicitly qualify}} + p = &this->h; // expected-error {{cannot create a non-constant pointer to member function}} + p = &(*this).h; // expected-error {{cannot create a non-constant pointer to member function}} } }; } @@ -174,3 +174,64 @@ namespace PR7176 { void m() { (void)(Condition) &base::Continuous::cond; } } + +namespace rdar8358512 { + // We can't call this with an overload set because we're not allowed + // to look into overload sets unless the parameter has some kind of + // function type. + template void bind(F f); // expected-note 6 {{candidate template ignored}} + template void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}} + template void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}} + + struct A { + void member(); + + void nonstat(); + void nonstat(int); + + void mixed(); + static void mixed(int); + + static void stat(); + static void stat(int); + + template struct Test0 { + void test() { + bind(&nonstat); // expected-error {{no matching function for call}} + bind(&A::nonstat); // expected-error {{no matching function for call}} + + bind(&mixed); // expected-error {{no matching function for call}} + bind(&A::mixed); // expected-error {{no matching function for call}} + + bind(&stat); // expected-error {{no matching function for call}} + bind(&A::stat); // expected-error {{no matching function for call}} + } + }; + + template struct Test1 { + void test() { + bindmem(&nonstat); // expected-error {{no matching function for call}} + bindmem(&A::nonstat); + + bindmem(&mixed); // expected-error {{no matching function for call}} + bindmem(&A::mixed); + + bindmem(&stat); // expected-error {{no matching function for call}} + bindmem(&A::stat); // expected-error {{no matching function for call}} + } + }; + + template struct Test2 { + void test() { + bindfn(&nonstat); // expected-error {{no matching function for call}} + bindfn(&A::nonstat); // expected-error {{no matching function for call}} + + bindfn(&mixed); // expected-error {{no matching function for call}} + bindfn(&A::mixed); // expected-error {{no matching function for call}} + + bindfn(&stat); + bindfn(&A::stat); + } + }; + }; +} -- cgit v1.2.3