On Thu, Jul 7, 2016 at 12:32 PM, Jason Merrill <ja...@redhat.com> wrote:
> Hmm, I wonder if walk_tree_1 should walk into DECL_EXPR like it does into
> BIND_EXPR_VARS.  But your patch is OK.
>
> Jason
>
>
> On Fri, Jul 1, 2016 at 11:23 AM, Jakub Jelinek <ja...@redhat.com> wrote:
>>
>> Hi!
>>
>> As mentioned in the PR, we ICE on these testcases because PTRMEM_CST for
>> non-static var DECL_INITIAL is now supposed to be replaced during
>> genericization, but for some artifical vars the initializers are actually
>> never genericized.
>>
>> For user variables, the VAR_DECLs should appear in BIND_EXPR_VARS and
>> walk_tree walks those when walking the corresponding BIND_EXPR.
>> So I think walking the initializers for non-artificial vars is a waste of
>> time, though genericization is using a pointer-set and thus shouldn't walk
>> anything multiple times, so if you think dropping the DECL_ARTIFICIAL
>> is desirable, I can try to test that.
>> The walking is only done on DECL_EXPR.
>>
>> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/6.2?
>>
>> 2016-07-01  Jakub Jelinek  <ja...@redhat.com>
>>             Kai Tietz  <ktiet...@googlemail.com>
>>
>>         PR c++/70869
>>         PR c++/71054
>>         * cp-gimplify.c (cp_genericize_r): For DECL_EXPR for non-static
>>         artificial vars, genericize their initializers.
>>
>>         * g++.dg/cpp0x/pr70869.C: New test.
>>         * g++.dg/cpp0x/pr71054.C: New test.
>>
>> --- gcc/cp/cp-gimplify.c.jj     2016-06-15 09:17:22.000000000 +0200
>> +++ gcc/cp/cp-gimplify.c        2016-07-01 14:36:16.222764199 +0200
>> @@ -1304,7 +1304,15 @@ cp_genericize_r (tree *stmt_p, int *walk
>>      {
>>        tree d = DECL_EXPR_DECL (stmt);
>>        if (TREE_CODE (d) == VAR_DECL)
>> -       gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P
>> (d));
>> +       {
>> +         gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P
>> (d));
>> +         /* User var initializers should be genericized during containing
>> +            BIND_EXPR genericization when walk_tree walks DECL_INITIAL
>> +            of BIND_EXPR_VARS.  Artificial temporaries might not be
>> +            mentioned there though, so walk them now.  */
>> +         if (DECL_ARTIFICIAL (d) && !TREE_STATIC (d) && DECL_INITIAL (d))
>> +           cp_walk_tree (&DECL_INITIAL (d), cp_genericize_r, data, NULL);
>> +       }
>>      }
>>    else if (TREE_CODE (stmt) == OMP_PARALLEL
>>            || TREE_CODE (stmt) == OMP_TASK
>> --- gcc/testsuite/g++.dg/cpp0x/pr70869.C.jj     2016-07-01
>> 14:45:47.737806235 +0200
>> +++ gcc/testsuite/g++.dg/cpp0x/pr70869.C        2016-07-01
>> 14:45:09.000000000 +0200
>> @@ -0,0 +1,25 @@
>> +// PR c++/70869
>> +// { dg-do run { target c++11 } }
>> +
>> +#include <initializer_list>
>> +
>> +struct A
>> +{
>> +  int f () { return 1; }
>> +  int g () { return 2; }
>> +  int h () { return 3; }
>> +};
>> +
>> +int
>> +main ()
>> +{
>> +  int cnt = 0;
>> +  for (const auto &m : { &A::f, &A::g, &A::h })
>> +    {
>> +      A a;
>> +      if ((a.*m) () != ++cnt)
>> +       __builtin_abort ();
>> +    }
>> +  if (cnt != 3)
>> +    __builtin_abort ();
>> +}
>> --- gcc/testsuite/g++.dg/cpp0x/pr71054.C.jj     2016-07-01
>> 14:53:31.650154643 +0200
>> +++ gcc/testsuite/g++.dg/cpp0x/pr71054.C        2016-07-01
>> 14:53:25.000000000 +0200
>> @@ -0,0 +1,21 @@
>> +// PR c++/71054
>> +// { dg-do compile { target c++11 } }
>> +
>> +#include <initializer_list>
>> +
>> +template <typename D, typename T = decltype (&D::U)>
>> +struct S
>> +{
>> +  struct A
>> +  {
>> +    int a;
>> +    int b;
>> +    T p;
>> +  };
>> +  S () { std::initializer_list<A> a{ {0, 0, &D::V} }; }
>> +};
>> +struct R {
>> +  void V (int);
>> +  void U (int);
>> +};
>> +S<R> b;
>>
>>         Jakub
>
>

Reply via email to