public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* c++: per-scope, per-signature lambda discriminators
@ 2022-11-01 21:46 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2022-11-01 21:46 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 588 bytes --]


This implements ABI-compliant lambda discriminators.  Not only do we
have per-scope counters, but we also distinguish by lambda signature.
Only lambdas with the same signature will need non-zero
discriminators.  As the discriminator is signature-dependent, we have
to process the lambda function's declaration before we can determine
it.  For templated and generic lambdas the signature is that of the
uninstantiated lambda -- not separate for each instantiation.

With this change, gcc and clang now produce the same lambda manglings
for all these testcases.

nathan

-- 
Nathan Sidwell

[-- Attachment #2: 0001-c-per-scope-per-signature-lambda-discriminators.patch --]
[-- Type: text/x-patch, Size: 24047 bytes --]

From 2b0e81d5cc2f7e1d773f6c502bd65b097f392675 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell <nathan@acm.org>
Date: Mon, 31 Oct 2022 06:11:28 -0400
Subject: [PATCH] c++: per-scope, per-signature lambda discriminators

This implements ABI-compliant lambda discriminators.  Not only do we
have per-scope counters, but we also distinguish by lambda signature.
Only lambdas with the same signature will need non-zero
discriminators.  As the discriminator is signature-dependent, we have
to process the lambda function's declaration before we can determine
it.  For templated and generic lambdas the signature is that of the
uninstantiated lambda -- not separate for each instantiation.

With this change, gcc and clang now produce the same lambda manglings
for all these testcases.

	gcc/cp/
	* cp-tree.h (LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR): New.
	(struct tree_lambda_expr): Add discriminator_sig bitfield.
	(recrd_lambda_scope_sig_discriminator): Declare.
	* lambda.cc (struct lambda_sig_count): New.
	(lambda_discriminator): Add signature vector.
	(start_lambda_scope): Adjust.
	(compare_lambda_template_head, compare_lambda_sig): New.
	(record_lambda_scope_sig_discriminator): New.
	* mangle.cc (write_closure_type): Use the scope-sig discriminator for
	ABI >= 18.  Emit abi mangling warning if needed.
	* module.cc (trees_out::core_vals): Stream the new discriminator.
	(trees_in::core_vals): Likewise.
	* parser.cc (cp_parser_lambda_declarator_opt): Call
	record_lambda_scope_sig_discriminator.
	* pt.cc (tsubst_lambda_expr): Likewise.
	libcc1/
	* libcp1plugin.cc (plugin_start_lambda_closure_class_type):
	Initialize the per-scope, per-signature discriminator.
	gcc/testsuite/
	* g++.dg/abi/lambda-sig1-18.C: New.
	* g++.dg/abi/lambda-sig1-18vs17.C: New.
	* g++.dg/cpp1y/lambda-mangle-1-18.C: New.
---
 gcc/cp/cp-tree.h                              |   7 +-
 gcc/cp/lambda.cc                              | 148 +++++++++++++++++-
 gcc/cp/mangle.cc                              |   8 +-
 gcc/cp/module.cc                              |   2 +
 gcc/cp/parser.cc                              |   1 +
 gcc/cp/pt.cc                                  |   1 +
 gcc/testsuite/g++.dg/abi/lambda-sig1-18.C     |  34 ++++
 gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C |  40 +++++
 .../g++.dg/cpp1y/lambda-mangle-1-18.C         |  26 +++
 libcc1/libcp1plugin.cc                        |   1 +
 10 files changed, 265 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/abi/lambda-sig1-18.C
 create mode 100644 gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4c0bacb91da..d13bb3d4c0e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1501,9 +1501,12 @@ enum cp_lambda_default_capture_mode_type {
   (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope)
 
 /* Lambdas in the same extra scope might need a discriminating count.
-   This is a single per-scope count.  */
+   For ABI 17, we have single per-scope count, for ABI 18, we have
+   per-scope, per-signature numbering.  */
 #define LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR(NODE) \
   (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_scope)
+#define LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR(NODE) \
+  (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_sig)
 
 /* During parsing of the lambda, a vector of capture proxies which need
    to be pushed once we're done processing a nested lambda.  */
@@ -1533,6 +1536,7 @@ struct GTY (()) tree_lambda_expr
   location_t locus;
   enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
   unsigned discriminator_scope : 15; // Per-scope discriminator
+  unsigned discriminator_sig : 15; // Per-scope, per-signature discriminator
 };
 
 /* Non-zero if this template specialization has access violations that
@@ -7783,6 +7787,7 @@ extern void start_lambda_scope			(tree decl);
 extern void finish_lambda_scope			(void);
 extern void record_lambda_scope			(tree lambda);
 extern void record_lambda_scope_discriminator	(tree lambda);
+extern void record_lambda_scope_sig_discriminator (tree lambda, tree fn);
 extern tree start_lambda_function		(tree fn, tree lambda_expr);
 extern void finish_lambda_function		(tree body);
 extern bool regenerated_lambda_fn_p		(tree);
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index d2673e2ceeb..c7a9268251b 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1447,13 +1447,21 @@ is_lambda_ignored_entity (tree val)
 /* Lambdas that appear in variable initializer or default argument
    scope get that in their mangling, so we need to record it.  Also,
    multiple lambdas in the same scope may need a mangling
-   discriminator.  Record in the same data structure.  */
+   discriminator.  In ABI <= 17, there is a single per-scope sequence
+   number.  In ABI >= 18, there are per-scope per-signature sequence
+   numbers.  */
+struct GTY(()) lambda_sig_count
+{
+  tree fn; // The lambda fn whose sig this is.
+  unsigned count;
+};
 struct GTY(()) lambda_discriminator
 {
   tree scope;
   unsigned nesting; // Inside a function, VAR_DECLs get the function
   		    // as scope. This counts that nesting.
   unsigned count;   // The per-scope counter.
+  vec<lambda_sig_count, va_gc> *discriminators; // Per-signature counters
 };
 // The current scope.
 static GTY(()) lambda_discriminator lambda_scope;
@@ -1475,6 +1483,7 @@ start_lambda_scope (tree decl)
       lambda_scope.scope = decl;
       lambda_scope.nesting = 0;
       lambda_scope.count = 0;
+      lambda_scope.discriminators = nullptr;
     }
 }
 
@@ -1504,6 +1513,116 @@ record_lambda_scope (tree lambda)
     }
 }
 
+// Compare lambda template heads TMPL_A and TMPL_B, used for both
+// templated lambdas, and template template parameters of said lambda.
+
+static bool
+compare_lambda_template_head (tree tmpl_a, tree tmpl_b)
+{
+  // We only need one level of template parms
+  tree inner_a = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_a));
+  tree inner_b = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_b));
+
+  // We only compare explicit template parms, ignoring trailing
+  // synthetic ones.
+  int len_a = TREE_VEC_LENGTH (inner_a);
+  int len_b = TREE_VEC_LENGTH (inner_b);
+  
+  for (int ix = 0, len = MAX (len_a, len_b); ix != len; ix++)
+    {
+      tree parm_a = NULL_TREE;
+      if (ix < len_a)
+	{
+	  parm_a = TREE_VEC_ELT (inner_a, ix);
+	  if (parm_a == error_mark_node)
+	    return false;
+	  parm_a = TREE_VALUE (parm_a);
+	  if (DECL_VIRTUAL_P (parm_a))
+	    parm_a = NULL_TREE;
+	}
+      
+      tree parm_b = NULL_TREE;
+      if (ix < len_b)
+	{
+	  parm_b = TREE_VEC_ELT (inner_b, ix);
+	  if (parm_b == error_mark_node)
+	    return false;
+	  parm_b = TREE_VALUE (parm_b);
+	  if (DECL_VIRTUAL_P (parm_b))
+	    parm_b = NULL_TREE;
+	}
+
+      if (!parm_a && !parm_b)
+	// we're done
+	break;
+
+      if (!(parm_a && parm_b))
+	return false;
+
+      if (TREE_CODE (parm_a) != TREE_CODE (parm_b))
+	return false;
+
+      if (TREE_CODE (parm_a) == PARM_DECL)
+	{
+	  if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_a))
+	      != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_b)))
+	    return false;
+
+	  if (!same_type_p (TREE_TYPE (parm_a), TREE_TYPE (parm_b)))
+	    return false;
+	}
+      else 
+	{
+	  if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_a))
+	      != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_b)))
+	    return false;
+
+	  if (TREE_CODE (parm_a) != TEMPLATE_DECL)
+	    gcc_checking_assert (TREE_CODE (parm_a) == TYPE_DECL);
+	  else if (!compare_lambda_template_head (parm_a, parm_b))
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+// Compare lambda signatures FN_A and FN_B, they may be TEMPLATE_DECLs too.
+
+static bool
+compare_lambda_sig (tree fn_a, tree fn_b)
+{
+  if (TREE_CODE (fn_a) == TEMPLATE_DECL
+      && TREE_CODE (fn_b) == TEMPLATE_DECL)
+    {
+      if (!compare_lambda_template_head (fn_a, fn_b))
+	return false;
+      fn_a = DECL_TEMPLATE_RESULT (fn_a);
+      fn_b = DECL_TEMPLATE_RESULT (fn_b);
+    }
+  else if (TREE_CODE (fn_a) == TEMPLATE_DECL
+	   || TREE_CODE (fn_b) == TEMPLATE_DECL)
+    return false;
+
+  if (fn_a == error_mark_node
+      || fn_b == error_mark_node)
+    return false;
+
+  for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
+	 args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
+       args_a || args_b;
+       args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
+    {
+      if (!args_a || !args_b)
+	return false;
+      // This check also deals with differing varadicness
+      if (!same_type_p (TREE_VALUE (args_a), TREE_VALUE (args_b)))
+	return false;
+    }
+
+  return true;
+}
+
 // Record the per-scope discriminator of LAMBDA.  If the extra scope
 // is empty, we must use the empty scope counter, which might not be
 // the live one.
@@ -1517,6 +1636,33 @@ record_lambda_scope_discriminator (tree lambda)
   LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda) = slot->count++;
 }
 
+// Record the per-scope per-signature discriminator of LAMBDA.  If the
+// extra scope is empty, we must use the empty scope counter, which
+// might not be the live one.
+
+void
+record_lambda_scope_sig_discriminator (tree lambda, tree fn)
+{
+  auto *slot = (vec_safe_is_empty (lambda_scope_stack)
+		|| LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+		? &lambda_scope : lambda_scope_stack->begin ());
+  gcc_checking_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == slot->scope);
+
+  // A linear search, we're not expecting this to be a big list, and
+  // this avoids needing a signature hash function.
+  lambda_sig_count *sig;
+  if (unsigned ix = vec_safe_length (slot->discriminators))
+    for (sig = slot->discriminators->begin (); ix--; sig++)
+      if (compare_lambda_sig (fn, sig->fn))
+	goto found;
+  {
+    lambda_sig_count init = {fn, 0};
+    sig = vec_safe_push (slot->discriminators, init);
+  }
+ found:
+  LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda) = sig->count++;
+}
+
 tree
 start_lambda_function (tree fco, tree lambda_expr)
 {
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index a62c9756c91..e97428e8f30 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -1810,7 +1810,13 @@ write_closure_type_name (const tree type)
 
   write_method_parms (parms, /*method_p=*/1, fn);
   write_char ('E');
-  write_compact_number (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
+  if ((LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+       != LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda))
+      && abi_warn_or_compat_version_crosses (18))
+    G.need_abi_warning = true;
+  write_compact_number (abi_version_at_least (18)
+			? LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+			: LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
 }
 
 /* Convert NUMBER to ascii using base BASE and generating at least
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index df05b524136..0e9af318ba4 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6328,6 +6328,7 @@ trees_out::core_vals (tree t)
 	{
 	  WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
 	  WU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+	  WU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
 	}
       break;
 
@@ -6820,6 +6821,7 @@ trees_in::core_vals (tree t)
       RUC (cp_lambda_default_capture_mode_type,
 	   ((lang_tree_node *)t)->lambda_expression.default_capture_mode);
       RU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+      RU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
       break;
 
     case OVERLOAD:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e0e3cf3eaf6..fd59de491cd 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -11712,6 +11712,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       fco = finish_fully_implicit_template (parser, fco);
 
     finish_member_declaration (fco);
+    record_lambda_scope_sig_discriminator (lambda_expr, fco);
 
     obstack_free (&declarator_obstack, p);
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index fc6279c00a3..c3fc56a13ff 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19912,6 +19912,7 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	  goto out;
 	}
       finish_member_declaration (inst);
+      record_lambda_scope_sig_discriminator (r, inst);
 
       tree fn = oldtmpl ? DECL_TEMPLATE_RESULT (inst) : inst;
 
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C b/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C
new file mode 100644
index 00000000000..88692edaaef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/lambda-sig1-18.C
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++20 } }
+// { dg-options -fabi-version=18 }
+
+#include "lambda-sig1.h"
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyfT_E_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyfT_E0_clIiEEDafS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE1_clEf:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E0_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyfT_E1_clIiEEDafS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlTyT_E1_clIiEEDaS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE_clEi:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE0_clEi:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyiT_E_clIiEEDaiS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyiT_E0_clIiEEDaiS1_:} } }
+
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C b/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C
new file mode 100644
index 00000000000..b191fb3ab0f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/lambda-sig1-18vs17.C
@@ -0,0 +1,40 @@
+// { dg-do compile { target c++20 } }
+// { dg-options {-fabi-version=18 -Wabi=17} }
+
+#include "lambda-sig1.h"
+
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E7_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E1_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E5_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E1_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE6_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE1_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE6_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE1_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE6_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE1_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E4_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E0_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE3_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE0_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE3_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE0_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE3_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfT_E1_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyfT_E_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE0_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENUlfE0_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENUlfE_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj1EE2FnEvENKUlfE_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfT_E4_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyfT_E0_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE3_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE0_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENUlfE3_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENUlfE0_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE3_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfT_E1_clIiEEDafS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyfT_E_clIiEEDafS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE0_cvPFvfEEv'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE_cvPFvfEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENUlfE0_4_FUNEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENUlfE_4_FUNEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf'\) and '-fabi-version=18' \('_ZZN1XIfLj0EE2FnEvENKUlfE_clEf'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliT_E4_clIiEEDaiS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyiT_E0_clIiEEDaiS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUlT_E2_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyT_E0_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE3_cvPFviEEv'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE0_cvPFviEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENUliE3_4_FUNEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENUliE0_4_FUNEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE3_clEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE0_clEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliT_E1_clIiEEDaiS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyiT_E_clIiEEDaiS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUlT_E_clIiEEDaS1_'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE0_cvPFviEEv'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE_cvPFviEEv'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENUliE0_4_FUNEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENUliE_4_FUNEi'\) [^\n]*\n} }
+// { dg-regexp {[^\n]*lambda-sig1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZZN1XIiLj0EE2FnEvENKUliE0_clEi'\) and '-fabi-version=18' \('_ZZN1XIiLj0EE2FnEvENKUliE_clEi'\) [^\n]*\n} }
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C
new file mode 100644
index 00000000000..22ad15ea33c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-18.C
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options -fabi-version=18 }
+
+// PRs 78621
+
+#include "lambda-mangle-1.h"
+
+// We erroneously mangled lambda auto parms as-if template parameters (T<n>_),
+// rather than auto (Da). Fixed in abi version 11
+
+// ABI 18 uses per-scope per-signature lambda discriminator
+
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRiRT_E_EOS1_S2_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_R1XIiEE_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlPA5_T_E_EOS0_RS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_E_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRiRT_E_EvS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_R1XIiEE_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPA5_T_E_EvRS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPfS1_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPT_PT0_E_EvRS1_RS3_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E_Z3FoovEUlS1_S3_E0_EvRS0_RS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E_EvRS3_RS5_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E_EvRT_RT0_:" } }
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index b0f0cb96626..e232aaceef9 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -1656,6 +1656,7 @@ plugin_start_closure_class_type (cc1_plugin::connection *self,
   /* Instead of calling record_lambda_scope, do this:  */
   LAMBDA_EXPR_EXTRA_SCOPE (lambda_expr) = extra_scope;
   LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda_expr) = discriminator;
+  LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda_expr) = discriminator;
 
   tree decl = TYPE_NAME (type);
   determine_visibility (decl);
-- 
2.38.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-01 21:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-01 21:46 c++: per-scope, per-signature lambda discriminators Nathan Sidwell

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).