Skip to content

[cling][AST] Strip elaborated keyword exposed by partial desugaring - #23060

Draft
guitargeek wants to merge 1 commit into
root-project:masterfrom
guitargeek:issue-23055-typename-keyword
Draft

[cling][AST] Strip elaborated keyword exposed by partial desugaring#23060
guitargeek wants to merge 1 commit into
root-project:masterfrom
guitargeek:issue-23055-typename-keyword

Conversation

@guitargeek

Copy link
Copy Markdown
Contributor

GetPartiallyDesugaredTypeImpl removes the elaborated type keyword ('typename', 'struct', ...) of its input type: the keyword is pure syntax and must never end up in a normalized type name. Since the LLVM 22 migration removed ElaboratedType, the keyword lives on the type node itself, and desugaring can expose a new one that nothing strips. With

template <typename T> struct Container {
   typedef typename std::vector<T*> seq_type;
   seq_type m_sequential;
};

the keyword sits on the TemplateSpecializationType that seq_type resolves to, so the normalized name of m_sequential came out as 'typename std::vector<Track*>'. TStreamerInfo::BuildOld then fails to match it against the 'vector<Track*>' stored in the file, sets the new type to -2 and skips the element, i.e. the member is silently not read.

The leak became visible with 081af22, which attaches the reconstructed prefix to the TemplateSpecializationType; TypePrinter prints the keyword whenever it is not None.

Only TemplateSpecializationType is affected; struct/enum elaborated typedefs already normalize correctly.

Fixes #23055

🤖 Done with the help of AI

GetPartiallyDesugaredTypeImpl removes the elaborated type keyword
('typename', 'struct', ...) of its input type: the keyword is pure
syntax and must never end up in a normalized type name. Since the
LLVM 22 migration removed ElaboratedType, the keyword lives on the
type node itself, and desugaring can expose a *new* one that nothing
strips. With

```c++
template <typename T> struct Container {
   typedef typename std::vector<T*> seq_type;
   seq_type m_sequential;
};
```

the keyword sits on the TemplateSpecializationType that seq_type
resolves to, so the normalized name of m_sequential came out as
'typename std::vector<Track*>'. TStreamerInfo::BuildOld then fails to
match it against the 'vector<Track*>' stored in the file, sets the new
type to -2 and skips the element, i.e. the member is silently not read.

The leak became visible with 081af22, which attaches the
reconstructed prefix to the TemplateSpecializationType; TypePrinter
prints the keyword whenever it is not None.

Only TemplateSpecializationType is affected; struct/enum elaborated
typedefs already normalize correctly.

Fixes root-project#23055

🤖 Done with the help of AI

@hahnjo hahnjo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I debated if I want to spend time trying to understand what the AI did. In the end, I did and my conclusion would be that Cling is not the right place to commit changes based on half-understood problems...

Comment on lines +1550 to +1554
// a normalized type name. The keyword of the *input* type is taken care of
// at the top of this function, but desugaring can expose a new one, as in
// typedef typename std::vector<T*> seq_type;
// where the keyword sits on the TemplateSpecializationType that the typedef
// resolves to.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is *input*, where is something like this already "taken care of at the top of this function" (I don't see it), and what happens if there is a typedef pointing to another alias?

@vgvassilev

Copy link
Copy Markdown
Member

Can you ask claude to reproduce the behavior through a clang diagnostic (through the type printer) and if that's reproducible that could be a good reason to submit an upstream fix.

@guitargeek
guitargeek marked this pull request as draft August 10, 2026 14:25
@github-actions

Copy link
Copy Markdown

Test Results

    23 files      23 suites   5d 0h 9m 13s ⏱️
 3 854 tests  3 845 ✅ 0 💤  9 ❌
78 522 runs  78 428 ✅ 1 💤 93 ❌

For more details on these failures, see this check.

Results for commit bf98c57.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression when reading a type spelled via a dependent alias

3 participants