-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang] Fall back to DW_TAG_typedef for instantiation dependent template aliases #90032
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
Conversation
…ate aliases Workaround for issue llvm#89774
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Orlando Cazalet-Hyams (OCHyams) ChangesWorkaround for issue #89774 until it can be properly fixed. When Full diff: https://github.com/llvm/llvm-project/pull/90032.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 539ded5cca5e1b..787db350487417 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1372,7 +1372,26 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
SourceLocation Loc = AliasDecl->getLocation();
- if (CGM.getCodeGenOpts().DebugTemplateAlias) {
+ if (CGM.getCodeGenOpts().DebugTemplateAlias &&
+ // The TemplateSpecializationType doesn't contain any instantiation
+ // information; dependent template arguments can't be resolved. For now,
+ // fall back to DW_TAG_typedefs for template aliases that are
+ // instantiation dependent, e.g.:
+ // ```
+ // template <int>
+ // using A = int;
+ //
+ // template<int I>
+ // struct S {
+ // using AA = A<I>; // Instantiation dependent.
+ // AA aa;
+ // };
+ //
+ // S<0> s;
+ // ```
+ // S::AA's underlying type A<I> is dependent on I so will be emitted as a
+ // DW_TAG_typedef.
+ !Ty->isInstantiationDependentType()) {
auto ArgVector = ::GetTemplateArgs(TD, Ty);
TemplateArgs Args = {TD->getTemplateParameters(), ArgVector};
diff --git a/clang/test/CodeGenCXX/dependent-template-alias.cpp b/clang/test/CodeGenCXX/dependent-template-alias.cpp
new file mode 100644
index 00000000000000..deb243f9fc88d0
--- /dev/null
+++ b/clang/test/CodeGenCXX/dependent-template-alias.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -gtemplate-alias %s -gsimple-template-names=simple \
+// RUN: | FileCheck %s
+
+//// Check that -gtemplate-alias falls back to DW_TAG_typedef emission
+//// for instantiation dependent type aliases.
+
+template <int>
+using A = int;
+
+template<int I>
+struct S {
+ using AA = A<I>;
+ AA aa;
+};
+
+S<0> s;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[AA:[0-9]+]], size: 32)
+// CHECK: [[AA]] = !DIDerivedType(tag: DW_TAG_typedef, name: "AA", file: ![[#]], line: [[#]], baseType: ![[A:[0-9]+]])
+// CHECK: [[A]] = !DIDerivedType(tag: DW_TAG_typedef, name: "A<I>", file: ![[#]], line: [[#]], baseType: ![[int:[0-9]+]])
+// CHECK: [[int]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
Comment in the code should probably mention this as a FIXME and include a reference to the issue? Also, there's another bug here - the DW_TAG_typedef is in the CU scope, instead of the struct scope. But if the struct is a non-template, the typedef is in the struct scope as it should be, not the CU scope... |
Sure, added in f78949a
That does looks odd - I can reproduce it with normal (language-level) typedefs too (rather than with template aliases): https://godbolt.org/z/GsGKqhKzz. I can open a separate issue? Now that I think about it, I recall @CarlosAlbertoEnciso running into something similar a while ago... I'm sure a bug was filed about something similar but I can't find it. Does this ring any bells @CarlosAlbertoEnciso? |
Thanks!
Yep! |
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in #90032 Fixes #89774
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in #90032 Fixes #89774
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in #90032 Fixes #89774
…#143291) The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in llvm/llvm-project#90032 Fixes llvm/llvm-project#89774
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in llvm#90032 Fixes llvm#89774
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in llvm#90032 Fixes llvm#89774
The dependency from the type sugar of the underlying type of a Typedef were not being considered for the dependency of the TypedefType itself. A TypedefType should be instantiation dependent if it involves non-instantiated template parameters, even if they don't contribute to the canonical type. Besides, a TypedefType should be instantiation dependent if it is declared in a dependent context, but fixing that would have performance consequences, as otherwise non-dependent typedef declarations would need to be transformed during instantiation as well. This removes the workaround added in llvm#90032 Fixes llvm#89774
Workaround for issue #89774 until it can be properly fixed.
When
-gtemplate-alias
is specified Clang emits a DW_TAG_template_alias for template aliases. This patch avoids an assertion failure by falling back to the-gno-template-alias
(default) behaviour, emitting a DW_TAG_typedef, if the alias is instantiation dependent.