[PATCH] Template argument deduction gcc testsuite test case sfinae-dr657.C
David Majnemer
david.majnemer at gmail.com
Wed Oct 16 22:37:53 PDT 2013
On Wed, Oct 16, 2013 at 10:10 PM, SENTHIL KUMAR THANGAVELU <
senthil.t at samsung.com> wrote:
> Resending mail in txt format.
>
> ------- Original Message -------
> Sender : SENTHIL KUMAR THANGAVELU<senthil.t at samsung.com> ./Senior
> Technical Manager/SRI-Bangalore-Native Framework/Samsung Electronics
> Date : Oct 16, 2013 19:38 (GMT+05:30)
> Title : [PATCH] Template argument deduction gcc testsuite test case
> sfinae-dr657.C
>
> Hello all,
> Found a test case sfinae-dr657.C in gcc 4.8.1 testsuite. This is
> related to c++ standard section "14.8.2 Template argument deduction" which
> states type deduction may fail for "Attempting to create a function type in
> which a parameter type or the return type is an abstract class type". This
> is a DR in
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3027.htmlsection "657. Abstract class parameter in synthesized declaration"
>
> Following test case should compile with -c option as per test case. With
> gcc 4.8.1 and intel x64 compiler 13.1.3 this test case is accepted for
> compilation whereas clang throws "call to 'declval' is ambiguous" error
> during compilation. Problem seems to be call candidate which ends up
> returning abstract type is considered instead of being rejected. As per
> test case abstract type returning call should result in deduction failure
> and only elipsis version should be considered for call candidate list.
>
> test case sfinae-dr657.C
> // DR 657
> // Test that a return or parameter type with abstract class type causes a
> // deduction failure.
> struct A
> {
> A();
> virtual void f() = 0;
> };
> template<class T> T declval();
> template<class T> int declval(...);
> int main()
> {
> int i = declval<A>();
> }
>
> I have added a patch for the issue as follows based on 3.3 base code. This
> patch works and passed LLVM regression. I am looking for comments on the
> patch. Based on comments I will rework the patch and send it.
>
> --- /home/camel/orig/llvm_3.3_src/tools/clang/lib/Sema/SemaOverload.cpp
> +++ /home/camel/llvm_3.3_src/tools/clang/lib/Sema/SemaOverload.cpp
> @@ -9534,6 +9534,51 @@
> return true;
> }
>
> +/// \brief Reject a call candidate if abstract type is returned
> +static bool IsRejectAbstractReturningCallCandidate(
> + FunctionTemplateDecl *FuncTemplate,
> + TemplateArgumentListInfo *ExplicitTemplateArgs) { return
> false;
>
You seem to have an extra 'return false;'
+ if(!FuncTemplate || !ExplicitTemplateArgs)
> + return false;
> +
> + TemplateParameterList *TemplateParams =
> FuncTemplate->getTemplateParameters();
> + FunctionDecl * FD = FuncTemplate->getTemplatedDecl();
> + if (!FD || !TemplateParams)
> + return false;
> +
> + // Check if atleast one of the template param is used as return type
> + const Type * RetType = (FD) ? FD->getResultType().getTypePtr() : 0;
> + unsigned MatchedIdx = 0;
> + bool RetDependsOnTemplateArg = false;
> + for (TemplateParameterList::iterator I = TemplateParams->begin(),
> + E = TemplateParams->end(); I != E ; ++I) {
> + NamedDecl * ND = *I;
> + TemplateTypeParmDecl * TmpParamDecl =
> dyn_cast<TemplateTypeParmDecl>(ND);
> + if (TmpParamDecl) {
> + const Type * TemplateParamType = TmpParamDecl->getTypeForDecl();
> + if (TemplateParamType == RetType) {
> + RetDependsOnTemplateArg = true;
> + break;
> + }
> + }
> + MatchedIdx++;
> + }
> +
> + if (RetDependsOnTemplateArg) {
> + TemplateArgumentListInfo ArgList = *ExplicitTemplateArgs;
> + if(MatchedIdx >= ArgList.size())
> + return false;
> +
> + TemplateArgumentLoc TAL = ArgList[MatchedIdx];
> + CXXRecordDecl * RD =
> + (TAL.getArgument().getKind() == TemplateArgument::Type) ?
> + TAL.getArgument().getAsType().getTypePtr()->getAsCXXRecordDecl() :
> 0;
> +
> + return (RD) ? (RD->getDefinition() && RD->isAbstract()) : false;
> + }
> + return false;
> +}
> +
> /// \brief Add a single candidate to the overload set.
> static void AddOverloadedCallCandidate(Sema &S,
> DeclAccessPair FoundDecl,
> @@ -9558,6 +9603,11 @@
>
> if (FunctionTemplateDecl *FuncTemplate
> = dyn_cast<FunctionTemplateDecl>(Callee)) {
> +
> + if(IsRejectAbstractReturningCallCandidate(FuncTemplate,
> + ExplicitTemplateArgs))
> + return;
> +
> S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
> ExplicitTemplateArgs, Args,
> CandidateSet);
> return;
>
>
>
> Regards
> Senthil Kumar
>
Some quick things: please stick * on the right hand side and spaces between
'if' and '('
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131016/e1df3ba1/attachment.html>
More information about the cfe-commits
mailing list