diff options
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 30 | ||||
-rw-r--r-- | test/SemaCXX/using-decl-assignment-cache.cpp | 16 |
2 files changed, 38 insertions, 8 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 204a697e93..108346a9d1 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2240,7 +2240,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, ThisTy.addConst(); if (VolatileThis) ThisTy.addVolatile(); - Expr::Classification ObjectClassification = + Expr::Classification Classification = (new (Context) OpaqueValueExpr(SourceLocation(), ThisTy, RValueThis ? VK_RValue : VK_LValue))-> Classify(Context); @@ -2256,12 +2256,21 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, assert((I != E) && "lookup for a constructor or assignment operator was empty"); for ( ; I != E; ++I) { - if ((*I)->isInvalidDecl()) + Decl *DD = *I; + + if (UsingShadowDecl *U = dyn_cast<UsingShadowDecl>(D)) + DD = U->getTargetDecl(); + + if (DD->isInvalidDecl()) continue; - if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) { - AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, NumArgs, - OCS, true); + if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(DD)) { + if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), D, ThisTy, + Classification, &Arg, NumArgs, OCS, true); + else + AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, + NumArgs, OCS, true); // Here we're looking for a const parameter to speed up creation of // implicit copy methods. @@ -2274,9 +2283,14 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, Result->setConstParamMatch(true); } } else if (FunctionTemplateDecl *Tmpl = - dyn_cast<FunctionTemplateDecl>(*I)) { - AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), - 0, &Arg, NumArgs, OCS, true); + dyn_cast<FunctionTemplateDecl>(DD)) { + if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), + D, 0, ThisTy, Classification, &Arg, NumArgs, + OCS, true); + else + AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), + 0, &Arg, NumArgs, OCS, true); } } diff --git a/test/SemaCXX/using-decl-assignment-cache.cpp b/test/SemaCXX/using-decl-assignment-cache.cpp new file mode 100644 index 0000000000..a3a50e5d2c --- /dev/null +++ b/test/SemaCXX/using-decl-assignment-cache.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only %s + +struct D; +struct B { + D& operator = (const D&); +}; +struct D : B { + using B::operator=; +}; +struct F : D { +}; + +void H () { + F f; + f = f; +} |