From 282b87a805812279986cec3e9f77db498e2115ec Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 1 Dec 2013 16:54:29 +0000 Subject: [PATCH] Handle CC and NoReturn when instantiating members of class templates. Before we were considering them only when instantiating templates. This fixes pr18033. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196050 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 2 ++ lib/Sema/SemaTemplate.cpp | 3 +- lib/Sema/SemaTemplateDeduction.cpp | 41 +++++++++++++---------- test/SemaCXX/decl-microsoft-call-conv.cpp | 8 +++++ 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index fbb46ff60b..06edb443cd 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5776,6 +5776,8 @@ public: // C++ Template Argument Deduction (C++ [temp.deduct]) //===--------------------------------------------------------------------===// + QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType); + /// \brief Describes the result of template argument deduction. /// /// The TemplateDeductionResult enumeration describes the result of diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index e995ae1c36..7b901d2df8 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -7436,7 +7436,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, NamedDecl *Prev = *P; if (!HasExplicitTemplateArgs) { if (CXXMethodDecl *Method = dyn_cast(Prev)) { - if (Context.hasSameUnqualifiedType(Method->getType(), R)) { + QualType Adjusted = adjustCCAndNoReturn(R, Method->getType()); + if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) { Matches.clear(); Matches.addDecl(Method, P.getAccess()); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 56df8bab9b..8d66ff68ef 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3501,6 +3501,28 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( Specialization, Info, &OriginalCallArgs); } +QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, + QualType FunctionType) { + if (ArgFunctionType.isNull()) + return ArgFunctionType; + + const FunctionProtoType *FunctionTypeP = + FunctionType->castAs(); + CallingConv CC = FunctionTypeP->getCallConv(); + bool NoReturn = FunctionTypeP->getNoReturnAttr(); + const FunctionProtoType *ArgFunctionTypeP = + ArgFunctionType->getAs(); + if (ArgFunctionTypeP->getCallConv() == CC && + ArgFunctionTypeP->getNoReturnAttr() == NoReturn) + return ArgFunctionType; + + FunctionType::ExtInfo EI = ArgFunctionTypeP->getExtInfo().withCallingConv(CC); + EI = EI.withNoReturn(NoReturn); + ArgFunctionTypeP = + cast(Context.adjustFunctionType(ArgFunctionTypeP, EI)); + return QualType(ArgFunctionTypeP, 0); +} + /// \brief Deduce template arguments when taking the address of a function /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to /// a template. @@ -3538,23 +3560,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateParameterList *TemplateParams = FunctionTemplate->getTemplateParameters(); QualType FunctionType = Function->getType(); - if (!InOverloadResolution && !ArgFunctionType.isNull()) { - const FunctionProtoType *FunctionTypeP = - FunctionType->castAs(); - CallingConv CC = FunctionTypeP->getCallConv(); - bool NoReturn = FunctionTypeP->getNoReturnAttr(); - const FunctionProtoType *ArgFunctionTypeP = - ArgFunctionType->getAs(); - if (ArgFunctionTypeP->getCallConv() != CC || - ArgFunctionTypeP->getNoReturnAttr() != NoReturn) { - FunctionType::ExtInfo EI = - ArgFunctionTypeP->getExtInfo().withCallingConv(CC); - EI = EI.withNoReturn(NoReturn); - ArgFunctionTypeP = cast( - Context.adjustFunctionType(ArgFunctionTypeP, EI)); - ArgFunctionType = QualType(ArgFunctionTypeP, 0); - } - } + if (!InOverloadResolution) + ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, FunctionType); // Substitute any explicit template arguments. LocalInstantiationScope InstScope(*this); diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp index a1a6d0b289..9f1463245b 100644 --- a/test/SemaCXX/decl-microsoft-call-conv.cpp +++ b/test/SemaCXX/decl-microsoft-call-conv.cpp @@ -183,3 +183,11 @@ namespace test4 { }; extern template void foo::bar(const void *); } + +namespace test5 { + template + class valarray { + void bar(); + }; + extern template void valarray::bar(); +} -- 2.40.0