[cfe-dev] Isolated TypedefDecl in CXXDeductionGuideDecl parameter?

Gábor Márton via cfe-dev cfe-dev at lists.llvm.org
Wed Nov 25 07:37:02 PST 2020


Richard, Aaron, thanks for your input!
I've came up with a quick (draft) patch to solve the issue. I might not
cover all cases, and perhaps the change should have a better place in
another function, please take a look if you have some time.
Besides, I ended up using the test infrastructure of the ASTImporter. We
could do a refactor to make that infra usable in other AST related tests,
if you find that direction okay.
https://reviews.llvm.org/D92101

Gabor

On Tue, Nov 24, 2020 at 7:43 PM Richard Smith <richard at metafoo.co.uk> wrote:

> This looks like a bug. We intentionally clone typedef declarations into
> deduction guide declarations in some cases:
>
> template<typename T> struct A {
>   typedef T U;
>   A(U);
> };
>
> ... should generate a deduction guide
>
> template<typename T> [typedef T U;]
> A(U) -> A<T>;
>
> that has a local clone of the typedef declaration. That's important
> because we want the typedef declaration to be part of the current
> instantiation when deducing / instantiating with the deduction guide, in
> order to allow us to properly "look through" U to T. (We tried other
> approaches here and this is the one that worked best.)
>
> But this should only be happening for typedefs that are declared within
> the enclosing class template.
>
> On Fri, 20 Nov 2020 at 08:49, Aaron Ballman <aaron at aaronballman.com>
> wrote:
>
>> On Fri, Nov 20, 2020 at 11:30 AM Gábor Márton <martongabesz at gmail.com>
>> wrote:
>> >
>> > Hi,
>> >
>> > Considering the below code:
>> > 01
>> > 02  struct A {};
>> > 03  typedef A AT;
>> > 04
>> > 05  template <typename T> struct ClassT {
>> > 06    ClassT(AT p0, T* p1) {}
>> > 07  };
>> > 08
>> > 09  A a;
>> > 10  int x;
>> > 11  auto y = ClassT(a, &x);
>> >
>> > The deduction guide's first parameter refers to a TypedefDecl that is
>> isolated
>> > from the first TypedefDecl. First declaration:
>> >
>> > |-TypedefDecl 0x5555561eaec0 <line:3:3, col:13> col:13 referenced AT 'A'
>> > | `-RecordType 0x5555561ead80 'A'
>> > |   `-CXXRecord 0x5555561eacf0 'A'
>> >
>> > Vs the function prototype of the deduction guide refers to an isolated
>> > (out-of-the-redecl-chain) TypedefDecl:
>> >
>> > FunctionProtoType 0x55555621bc80 'auto (AT, T *) -> ClassT<T>'
>> dependent trailing_return cdecl
>> > |-InjectedClassNameType 0x5555561eb220 'ClassT<T>' dependent
>> > | `-CXXRecord 0x5555561eafe0 'ClassT'
>> > |-TypedefType 0x55555621bb20 'AT' sugar
>> > | |-Typedef 0x55555621bac0 'AT'
>> > | `-RecordType 0x5555561ead80 'struct A'
>> > |   `-CXXRecord 0x5555561eacf0 'A'
>> > `-PointerType 0x5555561eb410 'T *' dependent
>> >   `-TemplateTypeParmType 0x5555561eafa0 'T' dependent depth 0 index 0
>> >     `-TemplateTypeParm 0x5555561eaf18 'T'
>> >
>> > So, in the translation unit, we have two distinct TypedefDecl AST
>> nodes. The
>> > first one's DeclContext is the TranslationUnidDecl, however, the
>> second's is
>> > the CXXDeductionGuideDecl.
>> >
>> > This is strange, because when dealing with regular function template
>> > instantiations, the two typedefs are the same and we have only one
>> universal
>> > TypedefDecl node in the AST.
>> > 01
>> > 02  struct A {};
>> > 03  typedef A AT;
>> > 04
>> > 05  template <typename T>
>> > 06  int fun(AT p0, T* p1) {}
>> > 07
>> > 08  A a;
>> > 09  int x;
>> > 10  int y = fun(a, &x);
>> >
>> > TypedefDecl 0x5555561eaf70 <input.cc:3:3, col:13> col:13 referenced AT
>> 'A'
>> > `-RecordType 0x5555561eae30 'A'
>> >   `-CXXRecord 0x5555561eada0 'A'
>> >
>> > FunctionProtoType 0x5555561eb240 'int (AT, T *)' dependent cdecl
>> > |-BuiltinType 0x5555561ab0a0 'int'
>> > |-TypedefType 0x5555561eb090 'AT' sugar
>> > | |-Typedef 0x5555561eaf70 'AT'
>> > | `-RecordType 0x5555561eae30 'struct A'
>> > |   `-CXXRecord 0x5555561eada0 'A'
>> > `-PointerType 0x5555561eb160 'T *' dependent
>> >   `-TemplateTypeParmType 0x5555561eb050 'T' dependent depth 0 index 0
>> >     `-TemplateTypeParm 0x5555561eafc8 'T'
>> >
>> > I was wondering whether this discrepancy is deliberate. IMO, the
>> deduction
>> > guide should refer to the TypedefDecl in the TranslationUnidDecl and it
>> should
>> > not create a new TypedefDecl. Can someone confirm if this is a bug or
>> not?
>>
>> I can't confirm that this behavior is a bug, but it certainly smells
>> like one to me. We use pointer comparisons to establish declaration
>> identity and that would fail with this (and this also gets used in
>> things like the JSON AST dumper). That said, I'm not certain why the
>> behavior is the way it is, so it's possible there's something deeper
>> going on here (but I'd argue it's still likely a bug).
>>
>> ~Aaron
>>
>> >
>> > Context: I am trying to fix an infinite loop in the ASTImporter that is
>> related
>> > to importing deduction guidelines.
>> >
>> > Any insight would be really appreciated.
>> >
>> > Thanks,
>> > Gabor
>> >
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20201125/380f373a/attachment-0001.html>


More information about the cfe-dev mailing list