diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/using-decl-1.cpp | 18 |
3 files changed, 29 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index aac3ffe6dd8..289c81da7a3 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1528,15 +1528,12 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs, for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(), E = Functions.end(); I != E; ++I) { - FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I); - if (!FDecl) - FDecl = cast<FunctionTemplateDecl>(*I)->getTemplatedDecl(); + // Look through any using declarations to find the underlying function. + NamedDecl *Fn = (*I)->getUnderlyingDecl(); - // Add the namespace in which this function was defined. Note - // that, if this is a member function, we do *not* consider the - // enclosing namespace of its class. - DeclContext *Ctx = FDecl->getDeclContext(); - CollectNamespace(AssociatedNamespaces, Ctx); + FunctionDecl *FDecl = dyn_cast<FunctionDecl>(Fn); + if (!FDecl) + FDecl = cast<FunctionTemplateDecl>(Fn)->getTemplatedDecl(); // Add the classes and namespaces associated with the parameter // types and return type of this function. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 9f175f962b8..72a85cc968d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4465,6 +4465,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, bool FoundNonTemplateFunction = false; for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) { + // Look through any using declarations to find the underlying function. + NamedDecl *Fn = (*I)->getUnderlyingDecl(); + // C++ [over.over]p3: // Non-member functions and static member functions match // targets of type "pointer-to-function" or "reference-to-function." @@ -4473,7 +4476,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, // Note that according to DR 247, the containing class does not matter. if (FunctionTemplateDecl *FunctionTemplate - = dyn_cast<FunctionTemplateDecl>(*I)) { + = dyn_cast<FunctionTemplateDecl>(Fn)) { if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) { // Skip non-static function templates when converting to pointer, and @@ -4510,7 +4513,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, continue; } - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) { + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) { // Skip non-static functions when converting to pointer, and static // when converting to member pointer. if (Method->isStatic() == IsMember) @@ -4522,7 +4525,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, } else if (IsMember) continue; - if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) { + if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) { QualType ResultTy; if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) || IsNoReturnConversion(Context, FunDecl->getType(), FunctionType, diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp index fe4d167fe27..e8a7d70976e 100644 --- a/clang/test/SemaCXX/using-decl-1.cpp +++ b/clang/test/SemaCXX/using-decl-1.cpp @@ -42,3 +42,21 @@ struct X1 : X0 { struct A { void f(); }; struct B : A { }; class C : B { using B::f; }; + +// PR5751: Resolve overloaded functions through using decls. +namespace O { + void f(int i); + void f(double d); +} +namespace P { + void f(); + void g(void (*ptr)(int)); + using O::f; + void test() { + f(); + f(1); + void (*f_ptr1)(double) = f; + void (*f_ptr2)() = f; + g(f); + } +} |