From: Patrick Palka <ppalka@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: jason@redhat.com, Patrick Palka <ppalka@redhat.com>
Subject: [PATCH] c++: reference variable as default targ [PR101463]
Date: Fri, 5 Jan 2024 15:01:16 -0500 [thread overview]
Message-ID: <20240105200116.1382389-1-ppalka@redhat.com> (raw)
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this
look OK for trunk?
-- >8 --
Here during default template argument substitution we wrongly consider
the (substituted) default arguments v and vt<int> as value-dependent[1]
which ultimately leads to deduction failure for the calls.
The bogus value_dependent_expression_p result aside, I noticed
type_unification_real during default targ substitution keeps track of
whether all previous targs are known and non-dependent, as is the case
for these calls. And in such cases it should be safe to avoid checking
dependence of the substituted default targ and just assume it's not.
This patch implements this optimization, which lets us accept both
testcases by sidestepping the value_dependent_expression_p issue
altogether.
[1]: The reason we consider these reference variables value-dependent is
due to a workaround in value_dependent_expression_p:
case VAR_DECL:
...
else if (TYPE_REF_P (TREE_TYPE (expression)))
/* FIXME cp_finish_decl doesn't fold reference initializers. */
return true;
...
added by r5-5022-g51d72abe5ea04e. I'm not sure if this workaround
is needed anymore, but naively removing it seems safe as far as
bootstrap+regtest is concerned (the only change is that we issue more
-Wmissing-braces warnings ahead of time in cpp0x/initlist123.C), and
lets us accept the first testcase.
Unfortunately we still reject the second testcase (in which v and vt are
additionally constexpr) for the same reason (bogus value dependence) due
to the subsequent check in v_d_e_p:
...
/* We have a constexpr variable and we're processing a template. When
there's lifetime extension involved (for which finish_compound_literal
used to create a temporary), we'll not be able to evaluate the
variable until instantiating, so pretend it's value-dependent. */
else if (DECL_DECLARED_CONSTEXPR_P (expression)
&& !TREE_CONSTANT (expression))
return true;
And TREE_CONSTANT isn't set for v and vt<int> because of a workaround in
cp_finish_decl:
if (decl_maybe_constant_var_p (decl)
/* FIXME setting TREE_CONSTANT on refs breaks the back end. */
&& !TYPE_REF_P (type))
TREE_CONSTANT (decl) = true;
Naively removing this workaround lets us accept the second testcase, but
it re-introduces an ICE in g++.dg/opt/pr78373.C.
PR c++/101463
gcc/cp/ChangeLog:
* pt.cc (type_unification_real): Avoid checking dependence of
a substituted default template argument if we can assume it's
non-dependent.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/nontype6.C: New test.
* g++.dg/cpp1z/nontype6a.C: New test.
---
gcc/cp/pt.cc | 9 +++++++--
gcc/testsuite/g++.dg/cpp1z/nontype6.C | 24 ++++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp1z/nontype6a.C | 25 +++++++++++++++++++++++++
3 files changed, 56 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype6.C
create mode 100644 gcc/testsuite/g++.dg/cpp1z/nontype6a.C
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7208c721b0b..b801ce1f18c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -23304,6 +23304,7 @@ type_unification_real (tree tparms,
might be instantiation-dependent like access (87480). */
processing_template_decl_sentinel s (!any_dependent_targs);
tree substed = NULL_TREE;
+ tristate dependent_p = tristate::unknown ();
if (saw_undeduced == 1 && !any_dependent_targs)
{
/* First instatiate in template context, in case we still
@@ -23312,8 +23313,9 @@ type_unification_real (tree tparms,
substed = tsubst_template_arg (arg, full_targs, complain,
NULL_TREE);
--processing_template_decl;
+ dependent_p = uses_template_parms (substed);
if (substed != error_mark_node
- && !uses_template_parms (substed))
+ && dependent_p.is_false ())
/* We replaced all the tparms, substitute again out of
template context. */
substed = NULL_TREE;
@@ -23321,8 +23323,11 @@ type_unification_real (tree tparms,
if (!substed)
substed = tsubst_template_arg (arg, full_targs, complain,
NULL_TREE);
+ if (dependent_p.is_unknown ())
+ dependent_p = (processing_template_decl
+ && uses_template_parms (substed));
- if (!uses_template_parms (substed))
+ if (dependent_p.is_false ())
arg = convert_template_argument (parm, substed, full_targs,
complain, i, NULL_TREE);
else if (saw_undeduced == 1)
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype6.C b/gcc/testsuite/g++.dg/cpp1z/nontype6.C
new file mode 100644
index 00000000000..06cd234cc61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype6.C
@@ -0,0 +1,24 @@
+// PR c++/101463
+// { dg-do compile { target c++17 } }
+
+int a;
+
+int& v = a;
+
+template<const int& = v>
+void f(int) { }
+
+template<class T, int& = v>
+void g(T) { }
+
+template<class T>
+int& vt = a;
+
+template<class T, int& = vt<T>>
+void h(T) { }
+
+int main() {
+ f(0);
+ g(0);
+ h(0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype6a.C b/gcc/testsuite/g++.dg/cpp1z/nontype6a.C
new file mode 100644
index 00000000000..8bc40a0505c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype6a.C
@@ -0,0 +1,25 @@
+// PR c++/101463
+// A version of nontype6.C where v and vt are constexpr.
+// { dg-do compile { target c++17 } }
+
+int a;
+
+constexpr int& v = a;
+
+template<const int& = v>
+void f(int) { }
+
+template<class T, const int& = v>
+void g(T) { }
+
+template<class T>
+constexpr int& vt = a;
+
+template<class T, const int& = vt<T>>
+void h(T) { }
+
+int main() {
+ f(0);
+ g(0);
+ h(0);
+}
--
2.43.0.254.ga26002b628
next reply other threads:[~2024-01-05 20:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-05 20:01 Patrick Palka [this message]
2024-01-09 19:27 ` Jason Merrill
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=20240105200116.1382389-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).