[PATCH] Template argument deduction gcc testsuite test case sfinae-dr657.C

Richard Smith richard at metafoo.co.uk
Thu Oct 17 16:16:34 PDT 2013


On Thu, Oct 17, 2013 at 4:15 PM, Richard Smith <richard at metafoo.co.uk>wrote:

> 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.
>>
>
> The relevant language rule is completely broken. Consider:
>
> template<typename T> T declval(int);
> template<typename T> int declval(...);
>
> struct A;
> using T = decltype(declval<A>(0)); // what type is this?
>
> struct A { virtual void f() = 0; };
> using T = decltype(declval<A>(0)); // what type is it now?
>
> ... and worse:
>
> template<typename T> struct X { virtual void f() = 0; };
> using U = decltype(declval<X<int>>(0)); // does this cause the
> instantiation of X<int>?
>
> The rules for decltype were crafted such that the type would not be
> completed here. If the type depends on whether X<int> is abstract, then we
> would need to complete it.
>
> GCC gives U the type 'X<int>', not 'int'. But it changes its mind if you
> trigger the instantiation of X<int> before the declaration of U.
>
> => I believe this to be a bug in the standard, not a bug in Clang.
>

... and it's already been filed. This is core issue 1646.


> --- /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;
>> +  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
>>
>> _______________________________________________
>> 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/20131017/6c89aad7/attachment.html>


More information about the cfe-commits mailing list