When looking for operator() to type-check a call to an object of class
type, use full qualified name lookup rather than the poking the
declaration context directly. This makes sure that we see operator()'s
in superclasses. Also, move the complete-type check before this name
lookup.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88842 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index b324068..56a878b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5255,8 +5255,15 @@
// (E).operator().
OverloadCandidateSet CandidateSet;
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
+
+ if (RequireCompleteType(LParenLoc, Object->getType(),
+ PartialDiagnostic(diag::err_incomplete_object_call)
+ << Object->getSourceRange()))
+ return true;
+
+ LookupResult R;
+ LookupQualifiedName(R, Record->getDecl(), OpName, LookupOrdinaryName, false);
+ for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Oper)) {
AddMethodTemplateCandidate(FunTmpl, false, 0, 0, Object, Args, NumArgs,
@@ -5268,11 +5275,6 @@
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
}
-
- if (RequireCompleteType(LParenLoc, Object->getType(),
- PartialDiagnostic(diag::err_incomplete_object_call)
- << Object->getSourceRange()))
- return true;
// C++ [over.call.object]p2:
// In addition, for each conversion function declared in T of the
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 750038d..7762667 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -164,7 +164,11 @@
double& operator()(...) const;
};
-void test_callable(Callable c, Callable2 c2, const Callable2& c2c) {
+struct DerivesCallable : public Callable {
+};
+
+void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
+ DerivesCallable dc) {
int &ir = c(1);
float &fr = c(1, 3.14159, 17, 42);
@@ -175,6 +179,9 @@
int &ir2 = c2();
int &ir3 = c2(1);
double &fr2 = c2c();
+
+ int &ir4 = dc(17);
+ double &fr3 = dc(3.14159f);
}
typedef float FLOAT;