Skip to content

Possible bug: DeclRefExpr wrong NonTypeTemplateParm decl #92292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
deadlocklogic opened this issue May 15, 2024 · 12 comments · Fixed by #135133
Closed

Possible bug: DeclRefExpr wrong NonTypeTemplateParm decl #92292

deadlocklogic opened this issue May 15, 2024 · 12 comments · Fixed by #135133
Assignees
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@deadlocklogic
Copy link

Consider:

namespace ns1 {
	template <typename TA1, bool TA2>
	struct Template1 {};
	template <typename TB1, bool TB2>
	struct Template2 {};
	template <typename U1, bool U2, bool U3>
	struct Template2<Template1<U1, U2>, U3> {};
}
namespace ns2 {
	template <typename TA1, bool TA2>
	struct Template1 {};
	template <typename TB1, bool TB2>
	struct Template2 {};
	template <typename U1, bool U3, bool U2>
	struct Template2<Template1<U1, U2>, U3> {};
}

The difference between the class templates in the 2 namespaces is: typename U1, bool U3, bool U2 instead of typename U1, bool U2, bool U3 in the class template partial specialization.
A repro dump is provided.
While the expected difference is just the template parameter order, this is not the case.
The AST difference is:

|   |-TemplateArgument type 'Template1<type-parameter-0-0, TA2>'
|   | `-TemplateSpecializationType 'Template1<type-parameter-0-0, TA2>' dependent Template1
|   |   |-TemplateArgument type 'type-parameter-0-0'
|   |   | `-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0
|   |   `-TemplateArgument expr
|   |     `-DeclRefExpr <line:2:31> 'bool' NonTypeTemplateParm 0xcf3a360 'TA2' 'bool'
|   |-TemplateArgument expr
|   | `-DeclRefExpr <line:11:38> 'bool' NonTypeTemplateParm 0xcf3ada8 'U3' 'bool'
|   |-TemplateArgument type 'Template1<type-parameter-0-0, U2>'
|   | `-TemplateSpecializationType 'Template1<type-parameter-0-0, U2>' dependent Template1
|   |   |-TemplateArgument type 'type-parameter-0-0'
|   |   | `-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0
|   |   `-TemplateArgument expr
|   |     `-DeclRefExpr <col:33> 'bool' NonTypeTemplateParm 0xcf5a4f8 'U2' 'bool'
|   |-TemplateArgument expr
|   | `-DeclRefExpr <col:38> 'bool' NonTypeTemplateParm 0xcf5a490 'U3' 'bool'

Why the clang::NonTypeTemplateParm TA2 is present? Even though it is not in the current semantic context.
I really think this is a bug, and the second result should be the correct one.
Thanks.

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels May 15, 2024
@llvmbot
Copy link
Member

llvmbot commented May 15, 2024

@llvm/issue-subscribers-clang-frontend

Author: None (deadlocklogic)

Consider: ```C++ namespace ns1 { template <typename TA1, bool TA2> struct Template1 {}; template <typename TB1, bool TB2> struct Template2 {}; template <typename U1, bool U2, bool U3> struct Template2<Template1<U1, U2>, U3> {}; } namespace ns2 { template <typename TA1, bool TA2> struct Template1 {}; template <typename TB1, bool TB2> struct Template2 {}; template <typename U1, bool U3, bool U2> struct Template2<Template1<U1, U2>, U3> {}; } ``` The difference between the class templates in the 2 namespaces is: `typename U1, bool U3, bool U2` instead of `typename U1, bool U2, bool U3` in the class template partial specialization. A repro [dump](https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QAJgAMfAQQCqAZ0wAFAB6cpvAFYgupWkwahkAUgkAhcxdLL6yAngGVG6AMKpaAVxYNJpVwAZPAZMADkfACNMYhAAZn0AB1RFQicGD29ff2TUxwFg0IiWaNiE20x7fIYhAiZiAkyfPwkKqvTa%2BoJC8KiY%2BP1FOoam7Nahrp7i0oGASltUL2Jkdg5mNkVEphWAagZFLh3TAHYrKQBBUykATgJMFkTDO6O4twIAT0TGVkwdgBVzvodpFUJ5/ucJKY4tgrpcbkNiF4HP97o8mHcuLCrtcTmc4TjjgARKF47F3B5PX5Qt6fb5sf4WIEgsF/CyQ6FY%2BEERHIv6oymQi7Y3GcgnEuKkm7ktHPakfL7rX7yJmg2g7eStYGq9VxKEwoVcnkEFEU9GYdluPmmjHU5WkdXs7D2%2BS6jkGgmSsUkrFE2GKzbbX77CRHU6i6WUl40hU/cEqlkQvWihFI41WmWYTHukXZ30S8P8s1R%2BV036s%2BNq1mO5Pc1MmjOC/E5pt5z0Roty2mK9UVnX25lqjVJ90p3mFu4W9OUzGvO0OvXO136luek7i0m%2Bg3nELGlhMEIQWahjeEjjzWicACsvD83F4qE4bms1h2ikWyypEgSvAImjP8wAaxAS8ABYADopBAgA2a5rmOOIAA5rikOI4muS9LwMTgQN4Fg9CkGRby0UgHw4XhFBAGRfw4LR5jgWAYEQFBUAeOgYnISg0FY%2BhYmQQxjC4BCuBkGhaDuYgKIgSI/1ISIQnqd5OB4WT5OId4AHlIm0TAHCU3guLYQR1IYWhFJo3gsEiLxgDcMRaAou9SCwPdjHEcynLwYgdMcAA3TAHOIzA1B0rw7hkndKj0gw8EiYgFI8LAou5PA8McvziBBZRCXuIxgFoEJQHM%2BYqEMYBFAANTwTAAHd1IVKL%2BEEEQxHYLgQNkQQlFUDR3N0fR%2BJMZ9LGiyIKMgeZUESaoHIAWiGdAoUJMxLGsaQdhmgB1BhUBmrwGAA7bqoYGb0WSqy7kUe90uIPAsDGw82m89IXAYdxPGaPQAleqY%2BliJIUjSARRj8f68nSH6Sn6QZKiegROhGd7smh9o4eGboQl6SG/tsNHgc%2BiYGghmYuHmN8lhWPRzyvG8ZNInY1AQqCZqgkCdj43KdkEsCuAgnYIFwQgSCOL8SZ/P9ZkA%2BI4jA1DZbl%2BWsI4HDSDw1CZfljXUKg0giPvThyMo0hqNo0h6KYxYCESUKOIgTB8CIG70E%2BxrhFEcQ2o6hRlHUGS%2BtIaq4sSPSqY4a8ddpzh1NCq3jVQKh6cZ5nWfZ4xOYQ7neYgDxuJiYWElmMWivmBBMCYLBYgei8ldwvRL25qDjlAhDLwIhChIQuJWl1kj9dsQ3jbPU3GIgJAmCGG2uMSNjiDCH5OAZpmWbZga04zwL7ZIW7nbkZr3fal2up93r8Zhhxntt168eOBCvvQIn%2BhAmRckBjJEb8a/SGf6p79iR/HrP1GXQr6YTsLDGoaMf4gD/gTRob8QCNxxpMDG0wH5SHmNyTAmAt5oMVmHbupFzhDB2JVGqucF5J2XhzLmPMpB8wFg7POQJs5Tx4owguRtxYh2VnhS8PMQKwS4IJLgUFLzXxAh3cO7lSIGyopw0gQEQJ13QnEAiEgoLCWuFBKCUhtZVziDTKRvcB4S0VhIGuwlCIRzIhwoupB0qpGcCBIAA) is provided. While the expected difference is just the template parameter order, this is not the case. The AST difference is: ``` | |-TemplateArgument type 'Template1<type-parameter-0-0, TA2>' | | `-TemplateSpecializationType 'Template1<type-parameter-0-0, TA2>' dependent Template1 | | |-TemplateArgument type 'type-parameter-0-0' | | | `-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0 | | `-TemplateArgument expr | | `-DeclRefExpr <line:2:31> 'bool' NonTypeTemplateParm 0xcf3a360 'TA2' 'bool' | |-TemplateArgument expr | | `-DeclRefExpr <line:11:38> 'bool' NonTypeTemplateParm 0xcf3ada8 'U3' 'bool' ``` ``` | |-TemplateArgument type 'Template1<type-parameter-0-0, U2>' | | `-TemplateSpecializationType 'Template1<type-parameter-0-0, U2>' dependent Template1 | | |-TemplateArgument type 'type-parameter-0-0' | | | `-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0 | | `-TemplateArgument expr | | `-DeclRefExpr <col:33> 'bool' NonTypeTemplateParm 0xcf5a4f8 'U2' 'bool' | |-TemplateArgument expr | | `-DeclRefExpr <col:38> 'bool' NonTypeTemplateParm 0xcf5a490 'U3' 'bool' ``` Why the `clang::NonTypeTemplateParm` `TA2` is present? Even though it is not in the current semantic context. I really think this is a bug, and the second result should be the correct one. Thanks.

@shafik
Copy link
Collaborator

shafik commented May 16, 2024

CC @erichkeane

@deadlocklogic
Copy link
Author

@shafik @erichkeane Any prognosis at least? Is this a bug or not?
Thanks.

@cor3ntin
Copy link
Contributor

@mizvekov

@mizvekov
Copy link
Contributor

mizvekov commented May 27, 2024

This is a known limitation of how we deal with canonicalization of template arguments of expression kind.

Expressions in clang are not uniqued and we don't build a canonical form for them
Also, uniquing them in their current form would yield little benefit, since they carry their source locations.

So when we need to build a canonical TemplateSpecializationType which has a template argument of expression kind, we choose the first expression encountered as a placeholder, and the TemplateSpecializationType is uniqued based on a canonical profiling of that expression.

If you later try to build another canonical TemplateSpecializationType which has a different expression, but which is canonically the same as the previous expression, then we won't build a new type and just return an existing one.

I suspect what is occurring in your example is that the canonical TST from the specialization argument of the partial specialization of ns1::Template2 is reusing the same TST that was built earlier for the injected specialization type of ns1::Template1. They have the same template arguments in the same order.

The issue does not occur in ns2 because there they don't have the same order.

Ie:
Injected TST of ns1::Template1: ns1::Template1<type-parameter-0-0, expression-parameter-0-1>.
TST from partial specialization arguments of ns1::Template2: ns1::Template1<type-parameter-0-0, expression-parameter-0-1>. The same as above.

Injected TST of ns2::Template1: ns2::Template1<type-parameter-0-0, expression-parameter-0-1>.
TST from partial specialization arguments of ns2::Template2: ns2::Template1<type-parameter-0-0, expression-parameter-0-2>. Not the same, notice the difference in the last argument.

@zyn0217
Copy link
Contributor

zyn0217 commented May 27, 2024

we choose the first expression encountered as a placeholder, and the TemplateSpecializationType is uniqued based on a canonical profiling of that expression.
If you later try to build another canonical TemplateSpecializationType which has a different expression, but which is canonically the same as the previous expression, then we won't build a new type and just return an existing one.

Yep, this mechanism also causes #84052.

@mizvekov
Copy link
Contributor

I think one solution for the specific problem of AST dumps is to build a canonical expression printer, and use that for printing expressions off of any AST node which is uniqued.

So this ast-dump would have printed instead:
TemplateSpecializationType 'Template1<type-parameter-0-0, expr-parameter-0-1>' dependent Template1,
which is less confusing.

Ie this printer would dig down an expression and ignore any non-structural parts.

@deadlocklogic
Copy link
Author

deadlocklogic commented May 27, 2024

In my case: the main usage of this is with printing, so I must resolve every AST declaration to its fully qualified name.
I wasn't satisfied with the default DeclPrinter because it had difficulties with template arguments (type-parameter-*-*), so I wrote my own.

The controversial case of TemplateTypeParmDecl

Now consider the same example with replacing the NonTypeTemplateParmDecl with TemplateTypeParmDecl, the AST behaves correctly and as expected without any other dependencies on the outer context.

@mizvekov
Copy link
Contributor

The default DeclPrinter is not at fault here. You are asking it to print a canonical type, and that's the information there.

If you are dumping the whole AST of a program, then you are going to find canonical types and references to canonical template parameters. There is no helping that.

If you are talking about seeing these 'type-parameters--' in the as-written portion of compiler issued diagnostics, then that's a bug, and we have to fix these one by one.

@deadlocklogic
Copy link
Author

If you are talking about seeing these 'type-parameters--' in the as-written portion of compiler issued diagnostics, then that's a bug, and we have to fix these one by one.

Yes indeed, these are pretty annoying while printing a type but wouldn't solve the problem, as ns::Template2 in:

namespace ns1 {
	template <typename TA1, bool TA2>
	struct Template1 {};
	template <typename TB1, bool TB2>
	struct Template2 {};
	template <typename U1, bool U2, bool U3>
	struct Template2<Template1<U1, U2>, U3> {};
}

is printed as ns1::Template2<ns1::Template1<type-parameter-0-0, TA2>, U3> instead of ns1::Template2<ns1::Template1<type-parameter-0-0, U2>, U3> (independently on how expressions are represented in the AST, and disregarding the fact of unresolved arguments 'type-parameters--').

Ie this printer would dig down an expression and ignore any non-structural parts.

So the current DeclPrinter behavior is kind of broken: when I need to print types I am not really concerned on how expressions are expressed in the AST, rather than getting a valid string (which hopefully can be processed/parsed/used in code generation etc).

Expressions in clang are not uniqued and we don't build a canonical form for them
Also, uniquing them in their current form would yield little benefit, since they carry their source locations.

So when we need to build a canonical TemplateSpecializationType which has a template argument of expression kind, we choose the first expression encountered as a placeholder, and the TemplateSpecializationType is uniqued based on a canonical profiling of that expression.

So currently, what is the best way to obtain a valid fully qualified notation of a decl (considering template arguments in case this is a template)?

Actually I am working on a tool and which needs to construct parallel raw templates but these synthetized templates may appear in a different namespace/context.
So using a modified default type/decl printer, I can obtain at best:

namespace custom_ns {
	template <typename TA1, bool TA2>
	struct Template1 {};
	template <typename TB1, bool TB2>
	struct Template2 {};
	template <typename U1, bool U2, bool U3>
	struct Template2<::ns::Template1<U1, TA2 /*This is so unwanted/ breaks the compilation*/>, U3> {};
}

Anything to do here, or I have to wait for a better printer, or maybe fixing the mechanism as mentioned in tagged issue?

@mizvekov
Copy link
Contributor

mizvekov commented May 27, 2024

Anything to do here, or I have to wait for a better printer, or maybe fixing the mechanism as mentioned in tagged issue?

I believe this old patch of mine gets you almost there: mizvekov@252f292

It's on my TODO list to rebase and create a PR for this soon.

Except that, in that patch, I chose not to preserve the as-written expression, as that would mean we would basically never be able to unique those CanonicalTemplateSpecialziationTypes.

But that patch would have those TSTs carry a converted argument list which is fully sugared.

For example, that list would have a converted argument list, in which this argument would be represented by a Declaration kind of TemplateArgument pointing to the NTTP decl as written.

Though again in that patch, the converted argument list is not wired to the AST dumper.

zyn0217 added a commit that referenced this issue May 29, 2024
…93556)

This patch takes Richard's approach of no longer modeling dependent NTTP
arguments with TemplateParamObjectDecls. Clang used to do so, which left
behind a problem in that we might mess up dependent and non-dependent
arguments that boil down to the same canonical type because there's a
default argument on the NTTP.

The problem of "canonical expression" is still present because this
patch doesn't touch the profiling part. Namely, #92292 seems different.

Fixes #84052
vg0204 pushed a commit to vg0204/llvm-project that referenced this issue May 29, 2024
…lvm#93556)

This patch takes Richard's approach of no longer modeling dependent NTTP
arguments with TemplateParamObjectDecls. Clang used to do so, which left
behind a problem in that we might mess up dependent and non-dependent
arguments that boil down to the same canonical type because there's a
default argument on the NTTP.

The problem of "canonical expression" is still present because this
patch doesn't touch the profiling part. Namely, llvm#92292 seems different.

Fixes llvm#84052
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
@mizvekov mizvekov self-assigned this Apr 10, 2025
mizvekov added a commit that referenced this issue Apr 10, 2025
…ion kind

This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions.

This is helpful for debugging, or if these template arguments somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
mizvekov added a commit that referenced this issue Apr 10, 2025
This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
…ion kind

This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions.

This is helpful for debugging, or if these template arguments somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
mizvekov added a commit that referenced this issue Apr 10, 2025
…135119)

This changes the TemplateArgument representation to hold a flag
indicating whether a template argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now. Without this
uniquing, this patch stands neutral in terms of performance impact.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
mizvekov added a commit that referenced this issue Apr 10, 2025
…ion kind

This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions.

This is helpful for debugging, or if these template arguments somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
@mizvekov
Copy link
Contributor

This will be fixed by #135133

The solution is along the lines I outlined before: We keep track of whether a TemplateArgument of expression kind is supposed to be canonical, and when printing those canonical arguments, we do it in a way which discards non-canonical information.

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue Apr 10, 2025
…ion types (#135119)

This changes the TemplateArgument representation to hold a flag
indicating whether a template argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
llvm/llvm-project#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now. Without this
uniquing, this patch stands neutral in terms of performance impact.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
…ion kind

This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions.

This is helpful for debugging, or if these template arguments somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 11, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 12, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 12, 2025
… types

This changes the TemplateArgument representation to hold a flag indicating
whether a tempalte argument of expression type is supposed to be canonical
or not.

This gets one step closer to solving #92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with
the AST more well-behaved, profiling template argument lists is
still too expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't
in some cases get incorrectly flagged as sugar over their own canonical
form. This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these TSTs.
mizvekov added a commit that referenced this issue Apr 12, 2025
… types (#135414)

This relands #135119, after
fixing crashes seen in LLDB CI reported here:
#135119 (comment)

Fixes #135119

This changes the TemplateArgument representation to hold a flag
indicating whether a tempalte argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue Apr 12, 2025
…cialization types (#135414)

This relands llvm/llvm-project#135119, after
fixing crashes seen in LLDB CI reported here:
llvm/llvm-project#135119 (comment)

Fixes llvm/llvm-project#135119

This changes the TemplateArgument representation to hold a flag
indicating whether a tempalte argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
llvm/llvm-project#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
mizvekov added a commit that referenced this issue Apr 12, 2025
This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.

This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
mizvekov added a commit that referenced this issue Apr 13, 2025
This patch extends the canonicalization printing policy to cover expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.

This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
mizvekov added a commit that referenced this issue Apr 14, 2025
This patch extends the canonicalization printing policy to cover
expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.

This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely
unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to
be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes #92292
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue Apr 14, 2025
This patch extends the canonicalization printing policy to cover
expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.

This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely
unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to
be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes llvm/llvm-project#92292
var-const pushed a commit to ldionne/llvm-project that referenced this issue Apr 17, 2025
…lvm#135119)

This changes the TemplateArgument representation to hold a flag
indicating whether a template argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
llvm#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now. Without this
uniquing, this patch stands neutral in terms of performance impact.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
var-const pushed a commit to ldionne/llvm-project that referenced this issue Apr 17, 2025
… types (llvm#135414)

This relands llvm#135119, after
fixing crashes seen in LLDB CI reported here:
llvm#135119 (comment)

Fixes llvm#135119

This changes the TemplateArgument representation to hold a flag
indicating whether a tempalte argument of expression type is supposed to
be canonical or not.

This gets one step closer to solving
llvm#92292

This still doesn't try to unique as-written TSTs. While this would
increase the amount of memory savings and make code dealing with the AST
more well-behaved, profiling template argument lists is still too
expensive for this to be worthwhile, at least for now.

This also fixes the context creation of TSTs, so that they don't in some
cases get incorrectly flagged as sugar over their own canonical form.
This is captured in the test expectation change of some AST dumps.

This fixes some places which were unnecessarily canonicalizing these
TSTs.
var-const pushed a commit to ldionne/llvm-project that referenced this issue Apr 17, 2025
This patch extends the canonicalization printing policy to cover
expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.

This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely
unrelated
expressions, which can be quite confusing.

This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to
be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.

Fixes llvm#92292
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants