From: Patrick Palka <ppalka@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: jason@redhat.com, Patrick Palka <ppalka@redhat.com>
Subject: [PATCH] c++: NSDMI instantiation from template context [PR109506]
Date: Thu, 27 Apr 2023 12:39:56 -0400 [thread overview]
Message-ID: <20230427163956.3051552-1-ppalka@redhat.com> (raw)
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
next reply other threads:[~2023-04-27 16:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-27 16:39 Patrick Palka [this message]
2023-04-27 22:35 ` Sam James
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230427163956.3051552-1-ppalka@redhat.com \
--to=ppalka@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).