c++: Handle error_mark_node in mark_used and mark_single_function

Message ID 20251207233608.1078876-2-egas.g.ribeiro@tecnico.ulisboa.pt
State New
Headers
Series c++: Handle error_mark_node in mark_used and mark_single_function |

Commit Message

Egas Ribeiro Dec. 7, 2025, 11:36 p.m. UTC
  These functions should return false for error_mark_node to properly
propagate errors from callers.

gcc/cp/ChangeLog:

	* decl2.cc (mark_single_function): Return false for error_mark_node.
	(mark_used): Likewise.

gcc/testsuite/ChangeLog:

	* g++.dg/DRs/dr3061.C: Remove cascading error expectation.
	* g++.dg/cpp0x/initlist31.C: Likewise.

Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
---
 gcc/cp/decl2.cc                         | 7 ++++++-
 gcc/testsuite/g++.dg/DRs/dr3061.C       | 2 +-
 gcc/testsuite/g++.dg/cpp0x/initlist31.C | 2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)
  

Comments

Jason Merrill Dec. 19, 2025, 11:15 a.m. UTC | #1
On 12/8/25 7:36 AM, Egas Ribeiro wrote:
> These functions should return false for error_mark_node to properly
> propagate errors from callers.
> 
> gcc/cp/ChangeLog:
> 
> 	* decl2.cc (mark_single_function): Return false for error_mark_node.
> 	(mark_used): Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/DRs/dr3061.C: Remove cascading error expectation.
> 	* g++.dg/cpp0x/initlist31.C: Likewise.
> 
> Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
> ---
>   gcc/cp/decl2.cc                         | 7 ++++++-
>   gcc/testsuite/g++.dg/DRs/dr3061.C       | 2 +-
>   gcc/testsuite/g++.dg/cpp0x/initlist31.C | 2 +-
>   3 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
> index 8ec9740c8a9..5c254506153 100644
> --- a/gcc/cp/decl2.cc
> +++ b/gcc/cp/decl2.cc
> @@ -6301,6 +6301,9 @@ mark_single_function (tree expr, tsubst_flags_t complain)
>     expr = maybe_undo_parenthesized_ref (expr);
>     expr = tree_strip_any_location_wrapper (expr);
>   
> +  if (expr == error_mark_node)
> +    return false;
> +
>     if (is_overloaded_fn (expr) == 1
>         && !mark_used (expr, complain)
>         && !(complain & tf_error))
> @@ -6343,10 +6346,12 @@ fn_template_being_defined (tree decl)
>   bool
>   mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
>   {
> +  if (decl == error_mark_node)
> +    return false;

I added a blank line here.

>     /* If we're just testing conversions or resolving overloads, we
>        don't want any permanent effects like forcing functions to be
>        output or instantiating templates.  */
> -  if ((complain & tf_conv))
> +  if (complain & tf_conv)

I dropped this unrelated change; the extra parens aren't necessary but 
they are expressive, so no need to remove them.

Applied with those tweaks, thanks!

>       return true;
>   
>     /* If DECL is a BASELINK for a single function, then treat it just
> diff --git a/gcc/testsuite/g++.dg/DRs/dr3061.C b/gcc/testsuite/g++.dg/DRs/dr3061.C
> index 728829848f5..bd8b74cdafb 100644
> --- a/gcc/testsuite/g++.dg/DRs/dr3061.C
> +++ b/gcc/testsuite/g++.dg/DRs/dr3061.C
> @@ -12,7 +12,7 @@ foo ()
>     template for (int x : { 1, })		// { dg-warning "'template for' only available with" "" { target c++23_down } }
>       ;
>     for (int x : { , })			// { dg-error "expected primary-expression before ',' token" }
> -    ;					// { dg-error "unable to deduce" "" { target *-*-* } .-1 }
> +    ;
>     template for (int x : { , })		// { dg-warning "'template for' only available with" "" { target c++23_down } }
>       ;					// { dg-error "expected primary-expression before ',' token" "" { target *-*-* } .-1 }
>   }
> diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist31.C b/gcc/testsuite/g++.dg/cpp0x/initlist31.C
> index a8a29f9c853..6d88edb397f 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/initlist31.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/initlist31.C
> @@ -9,5 +9,5 @@ void f() {
>     auto y =
>     {
>       string(Equation()) // { dg-error "12:'Equation' was not declared" }
> -  }; // { dg-error "unable to deduce" }
> +  };
>   }
  

Patch

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 8ec9740c8a9..5c254506153 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -6301,6 +6301,9 @@  mark_single_function (tree expr, tsubst_flags_t complain)
   expr = maybe_undo_parenthesized_ref (expr);
   expr = tree_strip_any_location_wrapper (expr);
 
+  if (expr == error_mark_node)
+    return false;
+
   if (is_overloaded_fn (expr) == 1
       && !mark_used (expr, complain)
       && !(complain & tf_error))
@@ -6343,10 +6346,12 @@  fn_template_being_defined (tree decl)
 bool
 mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
 {
+  if (decl == error_mark_node)
+    return false;
   /* If we're just testing conversions or resolving overloads, we
      don't want any permanent effects like forcing functions to be
      output or instantiating templates.  */
-  if ((complain & tf_conv))
+  if (complain & tf_conv)
     return true;
 
   /* If DECL is a BASELINK for a single function, then treat it just
diff --git a/gcc/testsuite/g++.dg/DRs/dr3061.C b/gcc/testsuite/g++.dg/DRs/dr3061.C
index 728829848f5..bd8b74cdafb 100644
--- a/gcc/testsuite/g++.dg/DRs/dr3061.C
+++ b/gcc/testsuite/g++.dg/DRs/dr3061.C
@@ -12,7 +12,7 @@  foo ()
   template for (int x : { 1, })		// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;
   for (int x : { , })			// { dg-error "expected primary-expression before ',' token" }
-    ;					// { dg-error "unable to deduce" "" { target *-*-* } .-1 }
+    ;
   template for (int x : { , })		// { dg-warning "'template for' only available with" "" { target c++23_down } }
     ;					// { dg-error "expected primary-expression before ',' token" "" { target *-*-* } .-1 }
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist31.C b/gcc/testsuite/g++.dg/cpp0x/initlist31.C
index a8a29f9c853..6d88edb397f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist31.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist31.C
@@ -9,5 +9,5 @@  void f() {
   auto y =
   {
     string(Equation()) // { dg-error "12:'Equation' was not declared" }
-  }; // { dg-error "unable to deduce" }
+  };
 }