]> granicus.if.org Git - clang/commitdiff
Use the naming class from the overloaded lookup when access-checking an
authorJohn McCall <rjmccall@apple.com>
Thu, 22 Apr 2010 18:44:12 +0000 (18:44 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 22 Apr 2010 18:44:12 +0000 (18:44 +0000)
address of overloaded function, instead of assuming that a nested name
specifier was used.  A nested name specifier is not required for static
functions.

Fixes PR6886.

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

include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/Sema/SemaAccess.cpp
test/SemaCXX/addr-of-overloaded-function.cpp

index 7f7f0858a1414f7b7e1bf18f1afd30115ced338f..262d2b4ed924fc0c8f6e6db2ce40bc16c8f05afe 100644 (file)
@@ -1289,6 +1289,9 @@ public:
     Results.append(Begin, End);
   }
 
+  /// Gets the naming class of this lookup, if any.
+  CXXRecordDecl *getNamingClass() const;
+
   typedef UnresolvedSetImpl::iterator decls_iterator;
   decls_iterator decls_begin() const { return Results.begin(); }
   decls_iterator decls_end() const { return Results.end(); }
index b9a4ee6e4d2c88c8252ae367b31356d5de43d2a5..c19fd834eae88db70da68a617b3034e9d93ad8dc 100644 (file)
@@ -180,6 +180,13 @@ bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
   return false;
 }
 
+CXXRecordDecl *OverloadExpr::getNamingClass() const {
+  if (isa<UnresolvedLookupExpr>(this))
+    return cast<UnresolvedLookupExpr>(this)->getNamingClass();
+  else
+    return cast<UnresolvedMemberExpr>(this)->getNamingClass();
+}
+
 Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
   return child_iterator();
 }
index af0c5b526cea2bb4e32834e509bac3ff3d2cdfb3..14a693f5b64138ec103eb12d36b504943d24bb98 100644 (file)
@@ -1230,15 +1230,7 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
     return AR_accessible;
 
   OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
-  NestedNameSpecifier *Qualifier = Ovl->getQualifier();
-  assert(Qualifier && "address of overloaded member without qualifier");
-
-  CXXScopeSpec SS;
-  SS.setScopeRep(Qualifier);
-  SS.setRange(Ovl->getQualifierRange());
-  DeclContext *DC = computeDeclContext(SS);
-  assert(DC && DC->isRecord() && "scope did not resolve to record");
-  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(DC);
+  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
 
   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
                       Context.getTypeDeclType(NamingClass));
index 391fc3095986781003712c8043f505ad18d86655..f8b00df17314e856dc7022973fabca9060ed9e62 100644 (file)
@@ -70,3 +70,19 @@ struct C {
     int (&fp)() = f; // expected-error{{address of overloaded function 'f' does not match required type 'int ()'}}
   }
 };
+
+// PR6886
+namespace test0 {
+  void myFunction(void (*)(void *));
+
+  class Foo {
+    void foo();
+
+    static void bar(void*);
+    static void bar();
+  };
+
+  void Foo::foo() {
+    myFunction(bar);
+  }
+}