diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-11-08 17:16:59 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-11-08 17:16:59 +0000 | 
| commit | bd6b17f4efb44b1b002600e67c28454f05ff8665 (patch) | |
| tree | 927788525c6463a06aea9c7b8b46481ae421868d /clang/lib | |
| parent | 2cd1fd4a828812e3b45b5144ae8cb7ce950792cd (diff) | |
| download | bcm5719-llvm-bd6b17f4efb44b1b002600e67c28454f05ff8665.tar.gz bcm5719-llvm-bd6b17f4efb44b1b002600e67c28454f05ff8665.zip | |
Improve our handling of C++ [class.copy]p3, which specifies that a
constructor template will not be used to copy a class object to a
value of its own type. We were eliminating all constructor templates
whose specializations look like a copy constructor, which eliminated
important candidates. Fixes PR8182.
llvm-svn: 118418
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 38 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 2 | 
3 files changed, 32 insertions, 16 deletions
| diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 17f2dfda648..bcb47baa24f 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1176,7 +1176,7 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {           (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());  } -bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const { +bool CXXConstructorDecl::isSpecializationCopyingObject() const {    if ((getNumParams() < 1) ||        (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||        (getPrimaryTemplate() == 0) || @@ -1188,12 +1188,6 @@ bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {    ASTContext &Context = getASTContext();    CanQualType ParamType = Context.getCanonicalType(Param->getType()); -  // Strip off the lvalue reference, if any. -  if (CanQual<LValueReferenceType> ParamRefType -                                    = ParamType->getAs<LValueReferenceType>()) -    ParamType = ParamRefType->getPointeeType(); - -      // Is it the same as our our class type?    CanQualType ClassTy       = Context.getCanonicalType(Context.getTagDeclType(getParent())); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index f45893df86d..e601a7d328c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3391,17 +3391,39 @@ static ExprResult CopyObject(Sema &S,    OverloadCandidateSet CandidateSet(Loc);    for (llvm::tie(Con, ConEnd) = S.LookupConstructors(Class);         Con != ConEnd; ++Con) { -    // Only consider copy constructors. -    CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con); -    if (!Constructor || Constructor->isInvalidDecl() || -        !Constructor->isCopyConstructor() || -        !Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) +    // Only consider copy constructors and constructor templates. +    CXXConstructorDecl *Constructor = 0; + +    if ((Constructor = dyn_cast<CXXConstructorDecl>(*Con))) { +      // Handle copy constructors, only. +      if (!Constructor || Constructor->isInvalidDecl() || +          !Constructor->isCopyConstructor() || +          !Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) +        continue; + +      DeclAccessPair FoundDecl +        = DeclAccessPair::make(Constructor, Constructor->getAccess()); +      S.AddOverloadCandidate(Constructor, FoundDecl, +                             &CurInitExpr, 1, CandidateSet); +      continue; +    }  + +    // Handle constructor templates. +    FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(*Con); +    if (ConstructorTmpl->isInvalidDecl()) +      continue; + +    Constructor = cast<CXXConstructorDecl>( +                                         ConstructorTmpl->getTemplatedDecl()); +    if (!Constructor->isConvertingConstructor(/*AllowExplicit=*/false))        continue; +    // FIXME: Do we need to limit this to copy-constructor-like +    // candidates?      DeclAccessPair FoundDecl -      = DeclAccessPair::make(Constructor, Constructor->getAccess()); -    S.AddOverloadCandidate(Constructor, FoundDecl, -                           &CurInitExpr, 1, CandidateSet); +      = DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess()); +    S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0, +                                   &CurInitExpr, 1, CandidateSet, true);    }    OverloadCandidateSet::iterator Best; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 3ed79fd4613..440f5acdbc2 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3457,7 +3457,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,      //   of a class object to an object of its class type.      QualType ClassType = Context.getTypeDeclType(Constructor->getParent());      if (NumArgs == 1 &&  -        Constructor->isCopyConstructorLikeSpecialization() && +        Constructor->isSpecializationCopyingObject() &&          (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) ||           IsDerivedFrom(Args[0]->getType(), ClassType)))        return; | 

