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