[cfe-dev] PR27015 (variable template initialized with a generic lambda expresssion)

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Thu Apr 14 11:52:57 PDT 2016


On Wed, Apr 13, 2016 at 3:19 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:

> On Tue, Apr 12, 2016 at 5:34 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> On Tue, Apr 12, 2016 at 5:22 PM, Akira Hatanaka via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> I was wondering whether someone could answer a few questions about
>>> variable templates. I'm trying to come up with a patch that fixes the crash
>>> described in PR27015.
>>>
>>> https://llvm.org/bugs/show_bug.cgi?id=27015
>>>
>>> The crash happens when clang compiles a code that has a variable
>>> template initialized with a generic lambda. For example,
>>>
>>> $ cat test1.c
>>>
>>> template<typename T> auto fn = [](auto a) { return a + T(1); };
>>>
>>> template <typename X>
>>> int func() {
>>>   X a = 0x61;
>>>   fn<char>(a);
>>>   return 0;
>>> }
>>>
>>> int main() {
>>>   func<int>();
>>> }
>>>
>>> First question, is this legal c++14 code? I didn't find anything that
>>> suggests it isn't legal, but I haven't found any code that uses variable
>>> templates like this either other than the provided test case.
>>>
>>
>> Yes, sadly, this is valid C++14 code.
>>
>>
>>> Second question, what would the closure type look like in this case? My
>>> understanding is that the closure type for generic lambda without template
>>> parameters looks like this:
>>>
>>> class Class {
>>> template<typename AT>
>>>   AT operator()(AT a) { ... }
>>>   ...
>>> };
>>>
>>> With template parameter, would it look like this?
>>>
>>> template<typename T>
>>> class Class {
>>> template<typename AT>
>>>   AT operator()(AT a) { return a + T(1); }
>>>   ...
>>> };
>>>
>>
>> No. Each instantiation of 'fn' gets its own closure type. The closure
>> type from the template itself should be treated as being in a dependent
>> context, even though there is no dependent DeclContext to contain it.
>>
>
> After the template declaration for func is parsed,
> VarTemplateSpecialization for fn looks like this in the AST:
>
> `-*VarTemplateSpecializationDecl* 0x10d001a00 <line:23:22, col:62> col:27
> referenced* fn* 'auto' cinit
>
> I think this is not correct as the type of the
> VarTemplateSpecializationDecl at this point should be the closure type for
> fn<char> instead of 'auto'. Is that correct?
>

Yes.


> I'm still trying to understand how instantiation of variable templates
> works, but it seems like one of the problem is that
> Sema::createLambdaClosureType is returning a type that is dependent
> (CXXRecordDecl::isDependentType() returns true), which looks like is
> preventing the type of VarTemplateSpecialization from being replaced.
>

The closure type created in the instantiation should not be considered
dependent. If it is, that's a bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160414/5625e30f/attachment.html>


More information about the cfe-dev mailing list