aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-04-22 18:44:12 +0000
committerJohn McCall <rjmccall@apple.com>2010-04-22 18:44:12 +0000
commite9ee23edd17c4bb7f271e67f8790792b4de677fc (patch)
tree4588b8e20cf8033c3ba36ddd453cc3b2f0a308d6
parentfe1ea7b3e4552a612a1b0a11734598651e5ddfdf (diff)
Use the naming class from the overloaded lookup when access-checking an
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
-rw-r--r--include/clang/AST/ExprCXX.h3
-rw-r--r--lib/AST/ExprCXX.cpp7
-rw-r--r--lib/Sema/SemaAccess.cpp10
-rw-r--r--test/SemaCXX/addr-of-overloaded-function.cpp16
4 files changed, 27 insertions, 9 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 7f7f0858a1..262d2b4ed9 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -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(); }
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index b9a4ee6e4d..c19fd834ea 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -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();
}
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index af0c5b526c..14a693f5b6 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -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));
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index 391fc30959..f8b00df173 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -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);
+ }
+}