summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-14 23:11:21 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-14 23:11:21 +0000
commit064fdb2fe844a4c70fc9b16426433878d78c8298 (patch)
tree25296d5b679b53117d73b80ec98918b1d5b2f6ea /clang/lib/Sema/SemaOverload.cpp
parent1deb972b55c20d14ecdcce3515b4596311fae5b2 (diff)
downloadbcm5719-llvm-064fdb2fe844a4c70fc9b16426433878d78c8298.tar.gz
bcm5719-llvm-064fdb2fe844a4c70fc9b16426433878d78c8298.zip
Always diagnose and complain about problems in
ResolveAddressOfOverloadedFunction when asked to complain. Previously, we had some weird handshake where ResolveAddressOfOverloadedFunction expected its caller to handle some of the diagnostics but not others, and yet there was no way for the caller to know which case we were in. Eliminate this madness, fixing <rdar://problem/7765884>. llvm-svn: 101312
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp90
1 files changed, 54 insertions, 36 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index e039669257b..53e05eed60a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -613,31 +613,36 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// type "pointer to T." The result is a pointer to the
// function. (C++ 4.3p1).
FromType = Context.getPointerType(FromType);
- } else if (FunctionDecl *Fn
- = ResolveAddressOfOverloadedFunction(From, ToType, false,
- AccessPair)) {
- // Address of overloaded function (C++ [over.over]).
- SCS.First = ICK_Function_To_Pointer;
-
- // We were able to resolve the address of the overloaded function,
- // so we can convert to the type of that function.
- FromType = Fn->getType();
- if (ToType->isLValueReferenceType())
- FromType = Context.getLValueReferenceType(FromType);
- else if (ToType->isRValueReferenceType())
- FromType = Context.getRValueReferenceType(FromType);
- else if (ToType->isMemberPointerType()) {
- // Resolve address only succeeds if both sides are member pointers,
- // but it doesn't have to be the same class. See DR 247.
- // Note that this means that the type of &Derived::fn can be
- // Ret (Base::*)(Args) if the fn overload actually found is from the
- // base class, even if it was brought into the derived class via a
- // using declaration. The standard isn't clear on this issue at all.
- CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
- FromType = Context.getMemberPointerType(FromType,
- Context.getTypeDeclType(M->getParent()).getTypePtr());
- } else
- FromType = Context.getPointerType(FromType);
+ } else if (From->getType() == Context.OverloadTy) {
+ if (FunctionDecl *Fn
+ = ResolveAddressOfOverloadedFunction(From, ToType, false,
+ AccessPair)) {
+ // Address of overloaded function (C++ [over.over]).
+ SCS.First = ICK_Function_To_Pointer;
+
+ // We were able to resolve the address of the overloaded function,
+ // so we can convert to the type of that function.
+ FromType = Fn->getType();
+ if (ToType->isLValueReferenceType())
+ FromType = Context.getLValueReferenceType(FromType);
+ else if (ToType->isRValueReferenceType())
+ FromType = Context.getRValueReferenceType(FromType);
+ else if (ToType->isMemberPointerType()) {
+ // Resolve address only succeeds if both sides are member pointers,
+ // but it doesn't have to be the same class. See DR 247.
+ // Note that this means that the type of &Derived::fn can be
+ // Ret (Base::*)(Args) if the fn overload actually found is from the
+ // base class, even if it was brought into the derived class via a
+ // using declaration. The standard isn't clear on this issue at all.
+ CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
+ FromType = Context.getMemberPointerType(FromType,
+ Context.getTypeDeclType(M->getParent()).getTypePtr());
+ } else {
+ FromType = Context.getPointerType(FromType);
+ }
+ } else {
+ return false;
+ }
} else {
// We don't require any conversions for the first step.
SCS.First = ICK_Identity;
@@ -5295,15 +5300,6 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
IsMember = true;
}
- // We only look at pointers or references to functions.
- FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
- if (!FunctionType->isFunctionType())
- return 0;
-
- // Find the actual overloaded function declaration.
- if (From->getType() != Context.OverloadTy)
- return 0;
-
// C++ [over.over]p1:
// [...] [Note: any redundant set of parentheses surrounding the
// overloaded function name is ignored (5.1). ]
@@ -5316,6 +5312,18 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
ExplicitTemplateArgs = &ETABuffer;
}
+
+ // We expect a pointer or reference to function, or a function pointer.
+ FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
+ if (!FunctionType->isFunctionType()) {
+ if (Complain)
+ Diag(From->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
+ << OvlExpr->getName() << ToType;
+
+ return 0;
+ }
+
+ assert(From->getType() == Context.OverloadTy);
// Look through all of the overloaded functions, searching for one
// whose type matches exactly.
@@ -5397,9 +5405,19 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
}
// If there were 0 or 1 matches, we're done.
- if (Matches.empty())
+ if (Matches.empty()) {
+ if (Complain) {
+ Diag(From->getLocStart(), diag::err_addr_ovl_no_viable)
+ << OvlExpr->getName() << FunctionType;
+ for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+ E = OvlExpr->decls_end();
+ I != E; ++I)
+ if (FunctionDecl *F = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
+ NoteOverloadCandidate(F);
+ }
+
return 0;
- else if (Matches.size() == 1) {
+ } else if (Matches.size() == 1) {
FunctionDecl *Result = Matches[0].second;
FoundResult = Matches[0].first;
MarkDeclarationReferenced(From->getLocStart(), Result);
OpenPOWER on IntegriCloud