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
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5389787..496d06c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3245,20 +3245,15 @@
// 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 cb80a69..35636e7 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1105,7 +1105,8 @@
(!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 45ce118..c826b83 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8294,6 +8294,8 @@
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;