]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Reorganize per-scope lambda discriminators
authorNathan Sidwell <nathan@acm.org>
Mon, 31 Oct 2022 10:11:28 +0000 (06:11 -0400)
committerNathan Sidwell <nathan@acm.org>
Tue, 1 Nov 2022 10:04:48 +0000 (06:04 -0400)
We currently use a per-extra-scope counter to discriminate multiple
lambdas in a particular such scope.  This is not ABI compliant.  This
patch merely refactors the existing code to make it easier to drop in
a conformant mangling -- there's no functional change here.  I rename
the LAMBDA_EXPR_DISCIMINATOR to LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR,
foreshadowing that there'll be a new discriminator.  To provide ABI
warnings we'll need to calculate both, and that requires some
repacking of the lambda_expr's fields.  Finally, although we end up
calling the discriminator setter and the scope recorder (nearly)
always consecutively, it's clearer to handle it as two separate
operations.  That also allows us to remove the instantiation
special-case for a null extra-scope.

gcc/cp/
* cp-tree.h (LAMBDA_EXPR_DISCRIMINATOR): Rename to ...
(LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR): ... here.
(struct tree_lambda_expr): Make default_capture_mode &
discriminator_scope bitfields.
(record_null_lambda_scope) Delete.
(record_lambda_scope_discriminator): Declare.
* lambda.cc (struct lambda_discriminator): New struct.
(lambda_scope, lambda_scope_stack): Adjust types.
(lambda_count): Delete.
(struct tree_int): Delete.
(start_lambda_scope, finish_lambda_scope): Adjust.
(record_lambda_scope): Only record the scope.
(record_lambda_scope_discriminator): New.
* mangle.cc (write_closure_type_name): Adjust.
* module.cc (trees_out::core_vals): Likewise,
(trees_in::core_vals): Likewise.
* parser.cc (cp_parser_lambda_expression): Call
record_lambda_scope_discriminator.
* pt.cc (tsubst_lambda_expr): Adjust record_lambda_scope caling.  Call
record_lambda_scope_discriminator. Commonize control flow on tsubsting
the operator function.
libcc1/
* libcp1plugin.cc (plugin_start_closure): Adjust.
gcc/testsuite/
* g++.dg/abi/lambda-sig1-17.C: New.
* g++.dg/abi/lambda-sig1.h: New.
* g++.dg/cpp1y/lambda-mangle-1.C: Extracted to ...
* g++.dg/cpp1y/lambda-mangle-1.h: ... here.
* g++.dg/cpp1y/lambda-mangle-1-11.C: New
* g++.dg/cpp1y/lambda-mangle-1-17.C

12 files changed:
gcc/cp/cp-tree.h
gcc/cp/lambda.cc
gcc/cp/mangle.cc
gcc/cp/module.cc
gcc/cp/parser.cc
gcc/cp/pt.cc
gcc/testsuite/g++.dg/abi/lambda-sig1-17.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/lambda-sig1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-17.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.h [moved from gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C with 98% similarity]
libcc1/libcp1plugin.cc

index 6d84514e4c0f30dd6859d9e1ec75e275e955eb16..4c0bacb91da1f3ca1dc7bb9fe09449a5be5a82d5 100644 (file)
@@ -1500,9 +1500,10 @@ enum cp_lambda_default_capture_mode_type {
 #define LAMBDA_EXPR_EXTRA_SCOPE(NODE) \
   (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope)
 
-/* If EXTRA_SCOPE, this is the number of the lambda within that scope.  */
-#define LAMBDA_EXPR_DISCRIMINATOR(NODE) \
-  (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator)
+/* Lambdas in the same extra scope might need a discriminating count.
+   This is a single per-scope count.  */
+#define LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR(NODE) \
+  (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_scope)
 
 /* During parsing of the lambda, a vector of capture proxies which need
    to be pushed once we're done processing a nested lambda.  */
@@ -1530,8 +1531,8 @@ struct GTY (()) tree_lambda_expr
   tree regen_info;
   vec<tree, va_gc> *pending_proxies;
   location_t locus;
-  enum cp_lambda_default_capture_mode_type default_capture_mode : 8;
-  short int discriminator;
+  enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
+  unsigned discriminator_scope : 15; // Per-scope discriminator
 };
 
 /* Non-zero if this template specialization has access violations that
@@ -7778,10 +7779,10 @@ extern tree cp_build_vec_convert                (tree, location_t, tree,
                                                 tsubst_flags_t);
 extern tree cp_build_bit_cast                  (location_t, tree, tree,
                                                 tsubst_flags_t);
-extern void start_lambda_scope                 (tree);
-extern void record_lambda_scope                        (tree);
-extern void record_null_lambda_scope           (tree);
+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 tree start_lambda_function              (tree fn, tree lambda_expr);
 extern void finish_lambda_function             (tree body);
 extern bool regenerated_lambda_fn_p            (tree);
index e9d5d4dc1c52a816219891363cfd48b9889af0f3..d2673e2ceebadaa4dadb3e374b0cccf69ed34892 100644 (file)
@@ -1444,79 +1444,77 @@ is_lambda_ignored_entity (tree val)
   return false;
 }
 
-/* Lambdas that appear in variable initializer or default argument scope
-   get that in their mangling, so we need to record it.  We might as well
-   use the count for function and namespace scopes as well.  */
-static GTY(()) tree lambda_scope;
-static GTY(()) int lambda_count;
-struct GTY(()) tree_int
+/* 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.  */
+struct GTY(()) lambda_discriminator
 {
-  tree t;
-  int i;
+  tree scope;
+  unsigned nesting; // Inside a function, VAR_DECLs get the function
+                   // as scope. This counts that nesting.
+  unsigned count;   // The per-scope counter.
 };
-static GTY(()) vec<tree_int, va_gc> *lambda_scope_stack;
+// The current scope.
+static GTY(()) lambda_discriminator lambda_scope;
+// Stack of previous scopes.
+static GTY(()) vec<lambda_discriminator, va_gc> *lambda_scope_stack;
+
+// Push DECL as lambda extra scope, also new discriminator counters.
 
 void
 start_lambda_scope (tree decl)
 {
-  tree_int ti;
-  gcc_assert (decl);
-  /* Once we're inside a function, we ignore variable scope and just push
-     the function again so that popping works properly.  */
+  gcc_checking_assert (decl);
   if (current_function_decl && TREE_CODE (decl) == VAR_DECL)
-    decl = current_function_decl;
-  ti.t = lambda_scope;
-  ti.i = lambda_count;
-  vec_safe_push (lambda_scope_stack, ti);
-  if (lambda_scope != decl)
+    // If we're inside a function, we ignore variable scope.  Don't push.
+    lambda_scope.nesting++;
+  else
     {
-      /* Don't reset the count if we're still in the same function.  */
-      lambda_scope = decl;
-      lambda_count = 0;
+      vec_safe_push (lambda_scope_stack, lambda_scope);
+      lambda_scope.scope = decl;
+      lambda_scope.nesting = 0;
+      lambda_scope.count = 0;
     }
 }
 
+// Pop from the current lambda extra scope.
+
 void
-record_lambda_scope (tree lambda)
+finish_lambda_scope (void)
 {
-  LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
-  LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
-  if (lambda_scope)
+  if (!lambda_scope.nesting--)
     {
-      tree closure = LAMBDA_EXPR_CLOSURE (lambda);
-      gcc_checking_assert (closure);
-      maybe_key_decl (lambda_scope, TYPE_NAME (closure));
+      lambda_scope = lambda_scope_stack->last ();
+      lambda_scope_stack->pop ();
     }
 }
 
-/* This lambda is an instantiation of a lambda in a template default argument
-   that got no LAMBDA_EXPR_EXTRA_SCOPE, so this shouldn't either.  But we do
-   need to use and increment the global count to avoid collisions.  */
+// Record the current lambda scope into LAMBDA
 
 void
-record_null_lambda_scope (tree lambda)
+record_lambda_scope (tree lambda)
 {
-  if (vec_safe_is_empty (lambda_scope_stack))
-    record_lambda_scope (lambda);
-  else
+  LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope.scope;
+  if (lambda_scope.scope)
     {
-      tree_int *p = lambda_scope_stack->begin();
-      LAMBDA_EXPR_EXTRA_SCOPE (lambda) = p->t;
-      LAMBDA_EXPR_DISCRIMINATOR (lambda) = p->i++;
+      tree closure = LAMBDA_EXPR_CLOSURE (lambda);
+      gcc_checking_assert (closure);
+      maybe_key_decl (lambda_scope.scope, TYPE_NAME (closure));
     }
-  gcc_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == NULL_TREE);
 }
 
+// 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.
+
 void
-finish_lambda_scope (void)
+record_lambda_scope_discriminator (tree lambda)
 {
-  tree_int *p = &lambda_scope_stack->last ();
-  if (lambda_scope != p->t)
-    {
-      lambda_scope = p->t;
-      lambda_count = p->i;
-    }
-  lambda_scope_stack->pop ();
+  auto *slot = (vec_safe_is_empty (lambda_scope_stack)
+               || LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+               ? &lambda_scope : lambda_scope_stack->begin ());
+  LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda) = slot->count++;
 }
 
 tree
@@ -1648,6 +1646,10 @@ prune_lambda_captures (tree body)
     }
 }
 
+// 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
 finish_lambda_function (tree body)
 {
index e39621876ef9206bd3b638a91ec9944568cad04a..a62c9756c9161622830b8c2dcf45d958f09c3779 100644 (file)
@@ -1810,7 +1810,7 @@ write_closure_type_name (const tree type)
 
   write_method_parms (parms, /*method_p=*/1, fn);
   write_char ('E');
-  write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
+  write_compact_number (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
 }
 
 /* Convert NUMBER to ascii using base BASE and generating at least
index 9957df510e6b4c0635b1a3864d87f4886f0f4e7f..df05b524136fbe5571c1585e99d6ded82bf33aea 100644 (file)
@@ -6327,7 +6327,7 @@ trees_out::core_vals (tree t)
       if (streaming_p ())
        {
          WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
-         WU (((lang_tree_node *)t)->lambda_expression.discriminator);
+         WU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
        }
       break;
 
@@ -6819,7 +6819,7 @@ trees_in::core_vals (tree t)
        = state->read_location (*this);
       RUC (cp_lambda_default_capture_mode_type,
           ((lang_tree_node *)t)->lambda_expression.default_capture_mode);
-      RU (((lang_tree_node *)t)->lambda_expression.discriminator);
+      RU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
       break;
 
     case OVERLOAD:
index 6da32801bab42ac356137e4961b82f8cd702dc42..e0e3cf3eaf6c128055b1ff091f00083855510358 100644 (file)
@@ -11035,6 +11035,7 @@ cp_parser_lambda_expression (cp_parser* parser)
     return error_mark_node;
 
   record_lambda_scope (lambda_expr);
+  record_lambda_scope_discriminator (lambda_expr);
 
   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   determine_visibility (TYPE_NAME (type));
@@ -11085,9 +11086,7 @@ cp_parser_lambda_expression (cp_parser* parser)
       ok = false;
 
     if (ok)
-      {
-       cp_parser_lambda_body (parser, lambda_expr);
-      }
+      cp_parser_lambda_body (parser, lambda_expr);
     else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
       {
        if (cp_parser_skip_to_closing_brace (parser))
index 51bfbbcd36dc0a7bd4fdafe0068c5dd7d602dfd6..fc6279c00a3e6c6592a2831d90641be7c5e708c1 100644 (file)
@@ -19866,21 +19866,13 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   if (type == error_mark_node)
     return error_mark_node;
 
-  if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE)
-    {
-      /* A lambda in a default argument outside a class gets no
-        LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI.  But
-        tsubst_default_argument calls start_lambda_scope, so we need to
-        specifically ignore it here, and use the global scope.  */
-      record_null_lambda_scope (r);
-
-      /* If we're pushed into another scope (PR105652), fix it.  */
-      if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
-       TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
-         = TYPE_CONTEXT (TREE_TYPE (t));
-    }
-  else
+  if (LAMBDA_EXPR_EXTRA_SCOPE (t))
     record_lambda_scope (r);
+  else if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
+    /* If we're pushed into another scope (PR105652), fix it.  */
+    TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
+      = TYPE_CONTEXT (TREE_TYPE (t));
+  record_lambda_scope_discriminator (r);
 
   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   determine_visibility (TYPE_NAME (type));
@@ -19911,29 +19903,17 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       fntype = build_memfn_type (fntype, type,
                                 type_memfn_quals (fntype),
                                 type_memfn_rqual (fntype));
-      tree fn, tmpl;
-      if (oldtmpl)
+      tree inst = (oldtmpl
+                  ? tsubst_template_decl (oldtmpl, args, complain, fntype)
+                  : tsubst_function_decl (oldfn, args, complain, fntype));
+      if (inst == error_mark_node)
        {
-         tmpl = tsubst_template_decl (oldtmpl, args, complain, fntype);
-         if (tmpl == error_mark_node)
-           {
-             r = error_mark_node;
-             goto out;
-           }
-         fn = DECL_TEMPLATE_RESULT (tmpl);
-         finish_member_declaration (tmpl);
-       }
-      else
-       {
-         tmpl = NULL_TREE;
-         fn = tsubst_function_decl (oldfn, args, complain, fntype);
-         if (fn == error_mark_node)
-           {
-             r = error_mark_node;
-             goto out;
-           }
-         finish_member_declaration (fn);
+         r = error_mark_node;
+         goto out;
        }
+      finish_member_declaration (inst);
+
+      tree fn = oldtmpl ? DECL_TEMPLATE_RESULT (inst) : inst;
 
       /* Let finish_function set this.  */
       DECL_DECLARED_CONSTEXPR_P (fn) = false;
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1-17.C b/gcc/testsuite/g++.dg/abi/lambda-sig1-17.C
new file mode 100644 (file)
index 0000000..cb71209
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++20 } }
+// { dg-options -fabi-version=17 }
+
+#include "lambda-sig1.h"
+
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE0_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfE3_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfT_E1_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlfT_E4_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlT_E2_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj0EE2FnEvENKUlT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE0_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE3_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfE6_clEf:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfT_E1_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfT_E4_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlfT_E7_clIiEEDafS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlT_E2_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlT_E5_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIfLj1EE2FnEvENKUlT_E_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE0_clEi:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliE3_clEi:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliT_E1_clIiEEDaiS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUliT_E4_clIiEEDaiS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlT_E2_clIiEEDaS1_:} } }
+// { dg-final { scan-assembler {_ZZN1XIiLj0EE2FnEvENKUlT_E_clIiEEDaS1_:} } }
diff --git a/gcc/testsuite/g++.dg/abi/lambda-sig1.h b/gcc/testsuite/g++.dg/abi/lambda-sig1.h
new file mode 100644 (file)
index 0000000..a8b77ae
--- /dev/null
@@ -0,0 +1,42 @@
+template<typename T, unsigned I> struct X 
+{
+  void Fn () 
+  {
+    {
+      auto v1 = []<typename U> (U) {};
+      auto v2 = [] (T) {};
+      auto v3 = []<typename U> (T, U) {};
+
+      v1 (1);
+      v2 (1);
+      v3 (1, 2);
+    }
+    if constexpr (I) 
+      {
+       auto v1 = []<typename U> (U) {};
+       auto v2 = [] (T) {};
+       auto v3 = []<typename U> (T, U) {};
+
+       v1 (1);
+       v2 (1);
+       v3 (1, 2);
+      }
+    {
+      auto v1 = []<typename U> (U) {};
+      auto v2 = [] (T) {};
+      auto v3 = []<typename U> (T, U) {};
+
+      v1 (1);
+      v2 (1);
+      v3 (1, 2);
+    }
+    
+  };
+};
+
+void f (X<int, 0> &x, X<float, 0> &y, X<float, 1> &z)
+{
+  x.Fn ();
+  y.Fn ();
+  z.Fn ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-11.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-11.C
new file mode 100644 (file)
index 0000000..9847587
--- /dev/null
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options -fabi-version=11 }
+
+// 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
+
+
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRiRT_E0_EOS1_S2_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_R1XIiEE1_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlPA5_T_E2_EOS0_RS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_E_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRiRT_E0_EvS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_R1XIiEE1_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPA5_T_E2_EvRS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPfS1_E3_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPT_PT0_E4_EvRS1_RS3_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E4_Z3FoovEUlS1_S3_E5_EvRS0_RS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E1_EvRT_RT0_:" } }
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-17.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1-17.C
new file mode 100644 (file)
index 0000000..31af5b8
--- /dev/null
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options -fabi-version=17 }
+
+// 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
+// Up to abi version 17 we had a single per-scope discriminator
+
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRiRT_E0_EOS1_S2_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_R1XIiEE1_EOS0_S1_:" } }
+// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlPA5_T_E2_EOS0_RS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_E_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRiRT_E0_EvS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_R1XIiEE1_EvS1_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPA5_T_E2_EvRS0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPfS1_E3_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPT_PT0_E4_EvRS1_RS3_:" } }
+// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E4_Z3FoovEUlS1_S3_E5_EvRS0_RS2_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_:" } }
+// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E1_EvRT_RT0_:" } }
similarity index 98%
rename from gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C
rename to gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.h
index 8f135358465beb97eb76b55384b26aa6e8b4a869..c91ce0186d832e4983f07f27ad4b645e5a5ed7bb 100644 (file)
@@ -23,7 +23,7 @@ template<typename S, typename T>
 {
 }
 
-void Foo ()
+inline void Foo ()
 {
   auto lam = [](auto &) { };
   auto lam_1 = [](int &, auto &) { };
@@ -70,6 +70,7 @@ template<typename X> void Bar ()
 void Baz ()
 {
   Bar<short> ();
+  Foo ();
 }
 
 // { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } }
index e2d5039a0a1f3b2a18db7ac7fca696dab52a4fcc..b0f0cb96626750a2f80b4c62ff4d022279c46e97 100644 (file)
@@ -1655,7 +1655,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_DISCRIMINATOR (lambda_expr) = discriminator;
+  LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda_expr) = discriminator;
 
   tree decl = TYPE_NAME (type);
   determine_visibility (decl);