On 1/18/26 2:56 PM, Jason Merrill wrote:
On 1/15/26 9:35 PM, Lucas Chollet wrote:
The patch fixes a bug in the detection of the usage of static variables inside generic lambdas. It does so by forcing the instantiation of generic lambdas within their enclosing scope. This ensures that the scope's static variables
usage is computed correctly.

Hmm, we shouldn't need to instantiate in order to know we've named a variable.  I notice in finish_id_expression_1 that we have

      /* A use in unevaluated operand might not be instantiated appropriately          if tsubst_copy builds a dummy parm, or if we never instantiate a          generic lambda, so mark it now.  */
      if (processing_template_decl && cp_unevaluated_operand)
        mark_type_use (decl);

...where the comment mentions generic lambdas, but the code doesn't handle this case.  Maybe add a check for generic_lambda_fn_p (current_function_decl)?

I'm pushing this modified version.  Thanks!


From 04ec3d4712519e32f85c034ff4237fcd5f9fbe39 Mon Sep 17 00:00:00 2001
From: Lucas Chollet <[email protected]>
Date: Mon, 26 Jan 2026 18:16:53 +0800
Subject: [PATCH] c++: Fix false positive with -Wunused [PR114450]
To: [email protected]

The patch fixes a bug in the detection of the usage of static variables
inside generic lambdas.  The comment in finish_id_expression_1 already
mentions this case, but the code didn't actually handle it.

	PR c++/114450

gcc/cp/ChangeLog:

	* lambda.cc (generic_lambda_fn_p): Handle null argument.
	* semantics.cc (finish_id_expression_1): Check for generic lambda.

gcc/testsuite/ChangeLog:

	* g++.dg/warn/Wunused-var-42.C: New test.

Co-authored-by: Jason Merrill <[email protected]>
---
 gcc/cp/lambda.cc                           |  2 +-
 gcc/cp/semantics.cc                        |  4 ++-
 gcc/testsuite/g++.dg/warn/Wunused-var-42.C | 33 ++++++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wunused-var-42.C

diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 402d5f7110a..e1ff304ffe8 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1153,7 +1153,7 @@ prepare_op_call (tree fn, int nargs)
 bool
 generic_lambda_fn_p (tree callop)
 {
-  return (LAMBDA_FUNCTION_P (callop)
+  return (callop && LAMBDA_FUNCTION_P (callop)
 	  && DECL_TEMPLATE_INFO (callop)
 	  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (callop)));
 }
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 0a15b32a16d..35bc48e49dc 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4814,7 +4814,9 @@ finish_id_expression_1 (tree id_expression,
       /* A use in unevaluated operand might not be instantiated appropriately
 	 if tsubst_copy builds a dummy parm, or if we never instantiate a
 	 generic lambda, so mark it now.  */
-      if (processing_template_decl && cp_unevaluated_operand)
+      if (processing_template_decl
+	  && (cp_unevaluated_operand
+	      || generic_lambda_fn_p (current_function_decl)))
 	mark_type_use (decl);
 
       /* Disallow uses of local variables from containing functions, except
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-42.C b/gcc/testsuite/g++.dg/warn/Wunused-var-42.C
new file mode 100644
index 00000000000..35c438bbcc7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-42.C
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wunused" }
+
+template <typename F>
+void f (F &&d)
+{
+  static unsigned context;
+  d(context);
+}
+
+void g ()
+{
+  static int b;
+  f([](auto c) { return c <= b; });
+}
+
+void h ()
+{
+  static int b = 0; // { dg-warning "unused variable" }
+  f([](auto c) { return c <= 0; });
+}
+
+void i ()
+{
+  static int b = 0;
+  [](auto c) { return c <= b; };
+}
+
+void j ()
+{
+  static int b = 0; // { dg-warning "unused variable" }
+  [](auto c) { return c <= 0; };
+}
-- 
2.52.0

Reply via email to