[gcc r13-10473] c++: fix reporting routines re-entered [PR119303]

Marek Polacek via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:25ff510563240750c56922809bcb6ff8cca3f5c6

commit r13-10473-g25ff510563240750c56922809bcb6ff8cca3f5c6
Author: Marek Polacek <[email protected]>
Date:   Wed May 14 10:34:44 2025 -0400

    c++: fix reporting routines re-entered [PR119303]
    
    We crash while we call warning_at ("inline function used but never defined")
    since it invokes dump_template_bindings -> tsubst -> ... -> convert_like ->
    ... -> c_common_truthvalue_conversion -> warning_at ("enum constant in boolean
                                                         context")
    
    cp_truthvalue_conversion correctly gets complain=0 but it calls
    c_common_truthvalue_conversion from c-family which doesn't have
    a similar parameter.
    
    We can fix this by tweaking diagnostic_context::report_diagnostic to
    check for recursion after checking if the diagnostic was enabled.
    
            PR c++/116960
            PR c++/119303
    
    gcc/ChangeLog:
    
            * diagnostic.cc (diagnostic_context::report_diagnostic): Check for
            non-zero m_lock later, after checking diagnostic_enabled.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/lambda-uneval26.C: New test.
            * g++.dg/warn/undefined2.C: New test.
    
    Reviewed-by: Jason Merrill <[email protected]>
    (cherry picked from commit 9ce96b683a40a12299c1d0e02727e747c00ad883)

Diff:
---
 gcc/diagnostic.cc                            | 24 ++++++++++++------------
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C | 10 ++++++++++
 gcc/testsuite/g++.dg/warn/undefined2.C       | 14 ++++++++++++++
 3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index a3d84cf0bfae..080cf87b4589 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -1517,18 +1517,6 @@ diagnostic_report_diagnostic (diagnostic_context *context,
   if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
     return false;
 
-  if (context->lock > 0)
-    {
-      /* If we're reporting an ICE in the middle of some other error,
-	 try to flush out the previous error, then let this one
-	 through.  Don't do this more than once.  */
-      if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
-	  && context->lock == 1)
-	pp_newline_and_flush (context->printer);
-      else
-	error_recursion (context);
-    }
-
   /* If the user requested that warnings be treated as errors, so be
      it.  Note that we do this before the next block so that
      individual warnings can be overridden back to warnings with
@@ -1553,6 +1541,18 @@ diagnostic_report_diagnostic (diagnostic_context *context,
   if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
     diagnostic_check_max_errors (context);
 
+  if (context->lock > 0)
+    {
+      /* If we're reporting an ICE in the middle of some other error,
+	 try to flush out the previous error, then let this one
+	 through.  Don't do this more than once.  */
+      if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
+	  && context->lock == 1)
+	pp_newline_and_flush (context->printer);
+      else
+	error_recursion (context);
+    }
+
   context->lock++;
 
   if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C
new file mode 100644
index 000000000000..3e3097bedcbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval26.C
@@ -0,0 +1,10 @@
+// PR c++/116960
+// { dg-do compile { target c++20 } }
+
+template<auto>
+using Foo = decltype([](auto) { return 0; }(0));
+
+template<typename...>
+Foo<[] {}> foo() {}   // { dg-warning "no return statement" }
+
+auto t = foo();
diff --git a/gcc/testsuite/g++.dg/warn/undefined2.C b/gcc/testsuite/g++.dg/warn/undefined2.C
new file mode 100644
index 000000000000..1b2ec353adb9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/undefined2.C
@@ -0,0 +1,14 @@
+// PR c++/119303
+
+template <class> struct c {
+  enum { d = 4 };
+};
+template <bool> struct e {
+  typedef void g;
+};
+template <class _Tp>
+inline typename e<!c<_Tp>::d>::g bar(_Tp); // { dg-warning "used but never defined" }
+
+int x;
+
+void foo() { bar(x); }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.