From: Douglas Gregor Date: Thu, 27 Aug 2009 23:35:55 +0000 (+0000) Subject: When looking for overloaded member operators, make sure to instantiate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8a5ae2401645788144c0ae769a2fb899866801f5;p=clang When looking for overloaded member operators, make sure to instantiate class template specializations (when possible) and look into base classes. Thanks to Eli for the test case! FIXME -=1. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80302 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index abcb9634ba..b08a51f016 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -514,7 +514,9 @@ public: /// user-declared constructors. When true, a default constructor /// will not be implicitly declared. bool hasUserDeclaredConstructor() const { - assert(isDefinition() && "Incomplete record decl!"); + assert((isDefinition() || + cast(getTypeForDecl())->isBeingDefined()) && + "Incomplete record decl!"); return UserDeclaredConstructor; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 5c92e12f69..7e00a1ecd8 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2638,11 +2638,17 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, // result of the qualified lookup of T1::operator@ // (13.3.1.1.1); otherwise, the set of member candidates is // empty. - // FIXME: Lookup in base classes, too! if (const RecordType *T1Rec = T1->getAs()) { - DeclContext::lookup_const_iterator Oper, OperEnd; - for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName); - Oper != OperEnd; ++Oper) + // Complete the type if it can be completed. Otherwise, we're done. + if (RequireCompleteType(OpLoc, T1, PartialDiagnostic(0))) + return; + + LookupResult Operators = LookupQualifiedName(T1Rec->getDecl(), OpName, + LookupOrdinaryName, false); + for (LookupResult::iterator Oper = Operators.begin(), + OperEnd = Operators.end(); + Oper != OperEnd; + ++Oper) AddMethodCandidate(cast(*Oper), Args[0], Args+1, NumArgs - 1, CandidateSet, /*SuppressUserConversions=*/false); diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 916d753a3f..02b47bd7b1 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -209,3 +209,7 @@ namespace M { (void)(x + x); } } + +struct AA { bool operator!=(AA&); }; +struct BB : AA {}; +bool x(BB y, BB z) { return y != z; }