[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