On 2/8/19 1:58 AM, Alexandre Oliva wrote:
On Feb  7, 2019, Jason Merrill <ja...@redhat.com> wrote:

+     PR c++/86322.  */

Wrong PR number.

Thanks

+  if (local_specializations)
+    if (tree r = retrieve_local_specialization (t))
+      return r;

Hmm, I would expect this to do the wrong thing for pack expansion of a
lambda, giving us only one rather than one per element of the
expansion.

Oooh.  Indeed, I hadn't realized this was possible.

I think we should separate local_specializations arising from different
pack expansion bindings, considering they won't always appear in tsubst
args:


diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0177d7f77891..9f954698f454 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11698,6 +11698,10 @@ gen_elem_of_pack_expansion_instantiation (tree pattern,
        ARGUMENT_PACK_SELECT_INDEX (aps) = index;
      }
+ // Any local specialization bindings arising from this substitution
+  // cannot be reused for a different INDEX.
+  local_specialization_stack lss (lss_copy);
+
    /* Substitute into the PATTERN with the (possibly altered)
       arguments.  */
    if (pattern == in_decl)


For instance, in lambda-variadic5.C we should get three
instantiations of the "print" function template; can you add that
check to the test?

This causes lambda-variadic5.C to get 6 separate lambdas, instead of 2,
so it passes after the following patchlet:

diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C
index 97f64cd761a7..1f931757b72f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C
@@ -1,5 +1,7 @@
  // PR c++/47226
  // { dg-do compile { target c++11 } }
+// { dg-options "-fdump-tree-original" }
+// { dg-final { scan-tree-dump-times "::<lambda\\(\\)> \\(null\\)" 6 
"original" } }
template<class T>
  void print(const T&) {}


Now, should I adjust lambda-variadic5.C to check for the presence of the
expencted count of lambdas in compiler dumps?

Sounds good.

Thinking of how to test for it drew my attention to issues about lambda
naming, that may have implications on ABI and duplicate code removal.
There are two issues I'm concerned with:

- we increment lambda_cnt when introducing a lambda within a generic,
   and then increment it again as we specialize, partially or fully, each
   lambda expr/object/type set.  This makes for gaps in numbering of full
   specializations and, being a global counter, does not ensure the
   assignment of the same symbol name to corresponding instantiations in
   separate translation units

We shouldn't use that name in any symbol shared between translation units.

- we don't seem to attempt to reuse lambdas across different
   specializations of argument pack expansions.

Right, we shouldn't reuse them (other than via identical code folding optimizations).

   I guess that's ok, we
   don't attempt to reuse them across different specializations of the
   enclosing template function or class either, but, unlike enclosing
   contexts, different argument pack indices do not mandate different
   mangled names.  This came up because I was thinking of having a
   sub-map in local_specializations, so that the lambda would map to
   another map in which we could look up template arguments to find a
   specific instance.  That wouldn't work, in part because args does not
   provide the entire set of substitutions, and in another part because
   we don't seem to be able to identify, in patterns undergoing
   substitution but before actually performing the substitution, the set
   of (implied?) template arguments that might affect the substitution
   result.

Indeed. When I was fixing lambdas in pack expansions I thought about making lambdas in pack expansions implicit templates with the parameters matching the packs in the pack expansion, but the current implementation matches the specification better I think.

Here's the patch I'm testing.  OK if it passes?

OK.

Jason

Reply via email to