]> granicus.if.org Git - clang/commitdiff
Allow calling an overloaded function set by taking the address of the
authorDouglas Gregor <dgregor@apple.com>
Thu, 13 Oct 2011 18:10:35 +0000 (18:10 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 13 Oct 2011 18:10:35 +0000 (18:10 +0000)
functions, e.g., (&f)(0). Fixes <rdar://problem/9803316>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141877 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.cpp
lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
test/SemaCXX/alignof-sizeof-reference.cpp
test/SemaCXX/overload-call.cpp

index 2cb927568108a0698586352ba23d1729d5f592bb..7b9f5909d1c3f619e16ceeff95cabe61f2cc65a1 100644 (file)
@@ -894,10 +894,8 @@ bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy,
       }
     }
 
-    // Ignore overloads where the address is taken, because apparently
-    // overload resolution doesn't apply in these cases.  In theory,
-    // this can make us miss a few cases, but whatever.
-    if (FR.IsAddressOfOperand)
+    // Ignore overloads that are the pointer-to-member.
+    if (FR.IsAddressOfOperand && FR.HasFormOfMemberPointer)
       return false;
 
     return true;
index d0ad5c8bfd2a3a99d590274fb86bb657e56eff74..bfe98498d8955e53d8e8bc6454357946fafe2787 100644 (file)
@@ -3549,8 +3549,8 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
   if (Fn->getType() == Context.OverloadTy) {
     OverloadExpr::FindResult find = OverloadExpr::find(Fn);
 
-    // We aren't supposed to apply this logic if there's an '&' involved.
-    if (!find.IsAddressOfOperand) {
+    // We aren't supposed to apply this logic for if there's an '&' involved.
+    if (!(find.IsAddressOfOperand && find.HasFormOfMemberPointer)) {
       OverloadExpr *ovl = find.Expression;
       if (isa<UnresolvedLookupExpr>(ovl)) {
         UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(ovl);
index 129a4f4e77094ae806c784f5b1a4fec0330acbde..ac11940c80daa5941f7c6c8e95ffe2138ce4dc07 100644 (file)
@@ -29,8 +29,7 @@ bool b8 = !S(); //expected-error {{invalid argument type 'S'}}
 
 namespace PR8181
 {
-  void f() { } // expected-note{{possible target for call}}
+  bool f() { } // expected-note{{possible target for call}}
   void f(char) { } // expected-note{{possible target for call}}
-  bool b = !&f;  //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
-
+  bool b = !&f;  //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
 }
index 1d65abbcc9febbc25d6425ce25938717c45a8b92..6a2d301ff4e1b48ed48f70ea700fc04cf048da24 100644 (file)
@@ -11,7 +11,8 @@ void test() {
 void f();  // expected-note{{possible target for call}}
 void f(int);  // expected-note{{possible target for call}}
 void g() { 
-  sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
+  sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} \
+  // expected-warning{{expression result unused}}
 }
 
 template<typename T> void f_template(); // expected-note{{possible target for call}}
index 9cc48993fde917cb96eaa900879069d839bdc2bb..00f6a9460a7a35cb0b18913c97f36b609dd1a7eb 100644 (file)
@@ -525,3 +525,12 @@ namespace PR9507 {
     f(n); // expected-error{{call to 'f' is ambiguous}}
   }
 }
+
+namespace rdar9803316 {
+  void foo(float);
+  int &foo(int);
+
+  void bar() {
+    int &ir = (&foo)(0);
+  }
+}