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

Akira Hatanaka via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 13 15:19:48 PDT 2016


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?

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160413/e17fdeae/attachment.html>


More information about the cfe-dev mailing list