On 6/4/25 11:18 AM, Patrick Palka wrote:
On Wed, 21 May 2025, Jason Merrill wrote:
On 5/20/25 11:28 AM, Patrick Palka wrote:
On Mon, 19 May 2025, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/15/14?
Whoops, CI reports I missed a testsuite adjustment expecting an
additional error in other/default13.C, which seems reasonable. Here's
an updated patch.
OK.
Thanks. On second thought, the extra expected error in default13.C
seems unnecessary to me. We can avoid it if we propagate
error_mark_node upon TREE_TYPE substitution failure only when in a
SFINAE context, otherwise we can assume we already issued an error,
and return a PARM_DECL anyway, for sake of error recovery.
Also I noticed that tsubst_tree_list and tsubst_arg_types return
error_mark_node upon TREE_CHAIN substitution failure rather than
returning something with TREE_CHAIN set to error_mark_node, so
I think we should do the same when substituting a chain of
PARM_DECLs for consistency.
So I think I prefer the following version of the patch. Does it look OK
for trunk/15/14?
OK.
-- >8 --
Subject: [PATCH] c++: substituting fn parm redeclared with dep alias tmpl
[PR120224]
PR c++/120224
gcc/cp/ChangeLog:
* pt.cc (tsubst_function_decl): Return error_mark_node if
substituting into the formal parameter list failed.
(tsubst_decl) <case PARM_DECL>: Return error_mark_node
upon TREE_TYPE substitution failure, when in a SFINAE
context. Return error_mark_node upon DECL_CHAIN substitution
failure.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/alias-decl-80.C: New test.
Reviewed-by: Jason Merrill <ja...@redhat.com>
---
gcc/cp/pt.cc | 14 ++++++++++++--
gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C | 21 +++++++++++++++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index c5a3abe6d8b9..b5c877a385f5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -14983,6 +14983,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t
complain,
if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t))
parms = DECL_CHAIN (parms);
parms = tsubst (parms, args, complain, t);
+ if (parms == error_mark_node)
+ return error_mark_node;
for (tree parm = parms; parm; parm = DECL_CHAIN (parm))
DECL_CONTEXT (parm) = r;
if (closure && DECL_IOBJ_MEMBER_FUNCTION_P (t))
@@ -15555,6 +15557,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain,
/* We're dealing with a normal parameter. */
type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (type == error_mark_node && !(complain & tf_error))
+ RETURN (error_mark_node);
+
type = type_decays_to (type);
TREE_TYPE (r) = type;
cp_apply_type_quals_to_decl (cp_type_quals (type), r);
@@ -15592,8 +15597,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t
complain,
/* If cp_unevaluated_operand is set, we're just looking for a
single dummy parameter, so don't keep going. */
if (DECL_CHAIN (t) && !cp_unevaluated_operand)
- DECL_CHAIN (r) = tsubst (DECL_CHAIN (t), args,
- complain, DECL_CHAIN (t));
+ {
+ tree chain = tsubst (DECL_CHAIN (t), args,
+ complain, DECL_CHAIN (t));
+ if (chain == error_mark_node)
+ RETURN (error_mark_node);
+ DECL_CHAIN (r) = chain;
+ }
/* FIRST_R contains the start of the chain we've built. */
r = first_r;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
new file mode 100644
index 000000000000..9c0eadc967c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-80.C
@@ -0,0 +1,21 @@
+// PR c++/120224
+// { dg-do compile { target c++11 } }
+
+template<class> using void_t = void;
+
+template<class T>
+void f(void*); // #1
+
+template<class T>
+void f(void_t<typename T::type>*) { } // { dg-error "not a class" } defn of #1
+
+template<class T>
+void g(int, void*); // #2
+
+template<class T>
+void g(int, void_t<typename T::type>*) { } // { dg-error "not a class" } defn
of #2
+
+int main() {
+ f<int>(0); // { dg-error "no match" }
+ g<int>(0, 0); // { dg-error "no match" }
+}