* [PATCH] c++: NSDMI instantiation from template context [PR109506]
@ 2023-04-27 16:39 Patrick Palka
2023-04-27 22:35 ` Sam James
0 siblings, 1 reply; 2+ messages in thread
From: Patrick Palka @ 2023-04-27 16:39 UTC (permalink / raw)
To: gcc-patches; +Cc: jason, Patrick Palka
The testcase from this PR fails to link when -fchecking=2 with the error:
/usr/bin/ld: /tmp/ccpHiXEY.o: in function `bar<int>::bar()':
...: undefined reference to `foo<int>::foo()'
ultimately because we end up instantiating the NSDMI for bar<int>::alloc_
from the template context func1<T> for which in_template_function is
true and thus mark_used is inhibited from scheduling other templates for
instantiation. So we end up never instantiating foo<int>'s ctor.
Although maybe_instantiate_nsdmi_init does call push_to_top_level, which
would have gotten us out of the template context, it doesn't happen in
this case because currently_open_class (ctx) is true, thanks to an
earlier call to push_scope from synthesized_method_walk.
We could perhaps arrange to call push_to_top_level unconditionally in
maybe_instantiate_nsdmi_init or even from from synthesized_method_walk,
but that seems rather heavyweight for this situation. Ideally we just
want a way to allow mark_used to work here despite being in a template
context.
To that end, this patch first generalizes the in_template_function test
in mark_used to instead test current_template_parms, which has two
benefits: it works for all template contexts, not just function template
contexts, and it can be cheaply disabled by simply clearing
current_template_parms. This patch then makes us disable this test from
maybe_instantiate_nsdmi_init.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk? This doesn't seem worth backporting since the bug seems to
manifest only with -fchecking=2.
PR c++/109506
gcc/cp/ChangeLog:
* decl2.cc (mark_used): Check current_template_parms instead
of in_template_function.
* init.cc (maybe_instantiate_nsdmi_init): Clear
current_template_parms before instantiating.
gcc/testsuite/ChangeLog:
* g++.dg/warn/Waddress-of-packed-member2.C: No longer expect
a "used but never defined" warning due to the use from an
uninstantiated template.
* g++.dg/template/non-dependent25.C: New test.
---
gcc/cp/decl2.cc | 6 ++++-
gcc/cp/init.cc | 3 +++
gcc/testsuite/g++.dg/cpp0x/nsdmi-template26.C | 23 +++++++++++++++++++
.../g++.dg/warn/Waddress-of-packed-member2.C | 2 +-
4 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template26.C
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 9594be4092c..b9d37d76bf6 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5781,7 +5781,11 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
&& DECL_OMP_DECLARE_REDUCTION_P (decl)))
maybe_instantiate_decl (decl);
- if (processing_template_decl || in_template_function ())
+ /* We don't want to instantiate templates based on uses from other
+ uninstantiated templates. Since processing_template_decl is cleared
+ during instantiate_non_dependent_expr, we check current_template_parms
+ as well. */
+ if (processing_template_decl || current_template_parms)
return true;
/* Check this too in case we're within instantiate_non_dependent_expr. */
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 1dd24e30d7c..ef32ef2a8c2 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -610,6 +610,9 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
push_deferring_access_checks (dk_no_deferred);
pushed = true;
}
+ /* Make sure current_template_parms is cleared so that mark_used
+ is uninhibited. */
+ auto ctpo = make_temp_override (current_template_parms, NULL_TREE);
/* If we didn't push_to_top_level, still step out of constructor
scope so build_base_path doesn't try to use its __in_chrg. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template26.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template26.C
new file mode 100644
index 00000000000..d9e17ea6724
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template26.C
@@ -0,0 +1,23 @@
+// PR c++/109506
+// { dg-do link { target c++11 } }
+// { dg-additional-options "-fchecking=2" }
+
+template<class T>
+struct foo {
+ foo() { };
+};
+
+template<class T>
+class bar {
+ foo<int> alloc_{};
+};
+
+template<class T>
+bar<int> func1() {
+ return bar<int>{};
+}
+
+int main() {
+ func1<int>();
+}
+
diff --git a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
index e9bf7cac04c..d619b28cfe1 100644
--- a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
+++ b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member2.C
@@ -1,7 +1,7 @@
// PR c++/89973
// { dg-do compile { target c++14 } }
-constexpr int a(); // { dg-warning "used but never defined" }
+constexpr int a();
template <typename>
constexpr void *b = a(); // { dg-error "invalid conversion" }
--
2.40.1.423.g2807bd2c10
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] c++: NSDMI instantiation from template context [PR109506]
2023-04-27 16:39 [PATCH] c++: NSDMI instantiation from template context [PR109506] Patrick Palka
@ 2023-04-27 22:35 ` Sam James
0 siblings, 0 replies; 2+ messages in thread
From: Sam James @ 2023-04-27 22:35 UTC (permalink / raw)
To: ppalka; +Cc: gcc-patches, jason
[-- Attachment #1: Type: text/plain, Size: 249 bytes --]
FWIW, we'd love to be able to backport this to GCC 13 (maybe 12, but no
big deal there) in Gentoo so we can continue doing large testing builds with
a lot of checking enabled, given this affects Chromium.
But it's no big deal if it's too invasive.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 377 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-04-27 22:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-27 16:39 [PATCH] c++: NSDMI instantiation from template context [PR109506] Patrick Palka
2023-04-27 22:35 ` Sam James
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).