From 2b0e81d5cc2f7e1d773f6c502bd65b097f392675 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell 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 *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_), +// 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