diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-09-10 06:35:32 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-09-10 06:35:32 +0000 |
commit | 4576a77b809649f5b8d0ff8c7a4be57eeee0ecf9 (patch) | |
tree | 26b3a2987ae7f0dfcbf7e3c0d0e34ac246a547cb /clang/lib/Sema | |
parent | 4d10ba37b93755fa7a843e24b92f9bfc5b1b805d (diff) | |
download | bcm5719-llvm-4576a77b809649f5b8d0ff8c7a4be57eeee0ecf9.tar.gz bcm5719-llvm-4576a77b809649f5b8d0ff8c7a4be57eeee0ecf9.zip |
PR33222: Require the declared return type not the actual return type to
match when checking for redeclaration of a function template.
This properly handles differences in deduced return types, particularly
when performing redeclaration checks for a friend function template.
llvm-svn: 341778
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 2 |
3 files changed, 7 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 538978799e8..496d06c6aca 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3245,20 +3245,15 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, // Redeclarations or specializations of a function or function template // with a declared return type that uses a placeholder type shall also // use that placeholder, not a deduced type. - QualType OldDeclaredReturnType = - (Old->getTypeSourceInfo() - ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : OldType)->getReturnType(); - QualType NewDeclaredReturnType = - (New->getTypeSourceInfo() - ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : NewType)->getReturnType(); + QualType OldDeclaredReturnType = Old->getDeclaredReturnType(); + QualType NewDeclaredReturnType = New->getDeclaredReturnType(); if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && canFullyTypeCheckRedeclaration(New, Old, NewDeclaredReturnType, OldDeclaredReturnType)) { QualType ResQT; if (NewDeclaredReturnType->isObjCObjectPointerType() && OldDeclaredReturnType->isObjCObjectPointerType()) + // FIXME: This does the wrong thing for a deduced return type. ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); if (ResQT.isNull()) { if (New->isCXXClassMember() && New->isOutOfLine()) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index cb80a6946b9..35636e73cf3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1105,7 +1105,8 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch) || - OldType->getReturnType() != NewType->getReturnType())) + !Context.hasSameType(Old->getDeclaredReturnType(), + New->getDeclaredReturnType()))) return true; // If the function is a class member, its signature includes the diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 45ce11874db..c826b836a70 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -8294,6 +8294,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { QualType Adjusted = Function->getType(); if (!hasExplicitCallingConv(Adjusted)) Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType()); + // This doesn't handle deduced return types, but both function + // declarations should be undeduced at this point. if (Context.hasSameType(Adjusted, Method->getType())) { FoundInstantiation = *I; Instantiation = Method; |