r184043 - A quick fix to allow return type deduction on member templates

Faisal Vali faisalv at gmail.com
Wed Jun 26 09:58:40 PDT 2013


Hmm - sorry -  I replied a little too soon - I think i see what the
issue might be, the specialization of
the << operator with unnamed local types probably is getting passed to
DiagnoseUseOfDecl and could be
causing the warning?

eitherway, if the warning does not occur in c++11 mode, that is as it
should be, since I thought local types
being allowed as template parameters was a C++11 feature?

thanks!
Faisal Vali



On Wed, Jun 26, 2013 at 10:33 AM, Faisal Vali <faisalv at gmail.com> wrote:
> Hi Takumi,
>      I'm not sure I understand.  Are you saying that when the current
> snapshot of clang source is compiled with the most recent version of
> clang (itself compiled from the most recent snapshot of clang trunk
> source) - that the following error occurs?
>
>
>> For example,
>>
>> clang/lib/Sema/AnalysisBasedWarnings.cpp:1126:7: error:
>>       template argument uses local type '<anonymous enum at
>>       clang/lib/Sema/AnalysisBasedWarnings.cpp:1105:5>'
>>       [-Werror,-Wlocal-type-template-args]
>>       << ObjectKind << D << FunctionKind
>>       ^~
>>
>> Both ObjectKind and FunctionKind have anonymous local enum types.
>>
>> Any idea?
>
> If so, i am quite puzzled.  It seems that it is emitting an error on
> the code. If you look at the patch, it only affects function decls
> (and really should be only template decls).
> Are there any other errors/warnings that you think might be related -
> i'll try and create a test file that creates such a warning with the
> current clang trunk.
> As far as options, you said only std=c++, right? anything else?
> thank you!
>
>
>
>
>
>
>
>>
>> ...Takumi
>>
>>
>> 2013/6/15 Faisal Vali <faisalv at yahoo.com>:
>>> Author: faisalv
>>> Date: Sat Jun 15 06:54:37 2013
>>> New Revision: 184043
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=184043&view=rev
>>> Log:
>>> A quick fix to allow return type deduction on member templates
>>> by ensuring DiagnoseUseOfDecl is called both on the found decl and the
>>> decl being used (i.e the specialization in the case of member templates) whenever they are different.
>>> Per the exchange captured in
>>> http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130610/081636.html
>>> a more comprehensive fix that allows both decls to be passed into DiagnoseUseOfDecl is (or should be) forthcoming relatively soon.
>>>
>>>
>>> Modified:
>>>     cfe/trunk/lib/Sema/SemaOverload.cpp
>>>     cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=184043&r1=184042&r2=184043&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jun 15 06:54:37 2013
>>> @@ -43,8 +43,15 @@ CreateFunctionRefExpr(Sema &S, FunctionD
>>>                        SourceLocation Loc = SourceLocation(),
>>>                        const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
>>>    if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
>>> +    return ExprError();
>>> +  // If FoundDecl is different from Fn (such as if one is a template
>>> +  // and the other a specialization), make sure DiagnoseUseOfDecl is
>>> +  // called on both.
>>> +  // FIXME: This would be more comprehensively addressed by modifying
>>> +  // DiagnoseUseOfDecl to accept both the FoundDecl and the decl
>>> +  // being used.
>>> +  if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc))
>>>      return ExprError();
>>> -
>>>    DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
>>>                                                   VK_LValue, Loc, LocInfo);
>>>    if (HadMultipleCandidates)
>>> @@ -11001,6 +11008,15 @@ Sema::BuildCallToMemberFunction(Scope *S
>>>        CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
>>>        if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
>>>          return ExprError();
>>> +      // If FoundDecl is different from Method (such as if one is a template
>>> +      // and the other a specialization), make sure DiagnoseUseOfDecl is
>>> +      // called on both.
>>> +      // FIXME: This would be more comprehensively addressed by modifying
>>> +      // DiagnoseUseOfDecl to accept both the FoundDecl and the decl
>>> +      // being used.
>>> +      if (Method != FoundDecl.getDecl() &&
>>> +                      DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
>>> +        return ExprError();
>>>        break;
>>>
>>>      case OR_No_Viable_Function:
>>> @@ -11246,7 +11262,8 @@ Sema::BuildCallToObjectOfClassType(Scope
>>>      CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
>>>      if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
>>>        return ExprError();
>>> -
>>> +    assert(Conv == Best->FoundDecl.getDecl() &&
>>> +             "Found Decl & conversion-to-functionptr should be same, right?!");
>>>      // We selected one of the surrogate functions that converts the
>>>      // object parameter to a function pointer. Perform the conversion
>>>      // on the object argument, then let ActOnCallExpr finish the job.
>>>
>>> Modified: cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp?rev=184043&r1=184042&r2=184043&view=diff
>>> ==============================================================================
>>> --- cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp Sat Jun 15 06:54:37 2013
>>> @@ -339,5 +339,37 @@ namespace ExplicitInstantiationDecl {
>>>    extern template auto f(int);
>>>    int (*p)(int) = f;
>>>  }
>>> -
>>> +namespace MemberTemplatesWithDeduction {
>>> +  struct M {
>>> +    template<class T> auto foo(T t) { return t; }
>>> +    template<class T> auto operator()(T t) const { return t; }
>>> +    template<class T> static __attribute__((unused)) int static_foo(T) {
>>> +      return 5;
>>> +    }
>>> +    template<class T> operator T() { return T{}; }
>>> +    operator auto() { return &static_foo<int>; }
>>> +  };
>>> +  struct N : M {
>>> +    using M::foo;
>>> +    using M::operator();
>>> +    using M::static_foo;
>>> +    using M::operator auto;
>>> +  };
>>> +
>>> +  template <class T> int test() {
>>> +    int i = T{}.foo(3);
>>> +    T m = T{}.foo(M{});
>>> +    int j = T{}(3);
>>> +    M m2 = M{}(M{});
>>> +    int k = T{}.static_foo(4);
>>> +    int l = T::static_foo(5);
>>> +    int l2 = T{};
>>> +    struct X { };
>>> +    X x = T{};
>>> +    return 0;
>>> +  }
>>> +  int Minst = test<M>();
>>> +  int Ninst = test<N>();
>>> +
>>> +}
>>>  }
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list