Hi! When gimplifying ANNOTATE_EXPR, gimplify_expr used create_tmp_var_raw, which unfortunately (among tons of other desirable things) doesn't set DECL_CONTEXT on the temporary var and tree-nested.c then ICEs on it because of that. The following patch fixes that. Unfortunately, on the second (invalid) testcase this started to ICE during error recovery, so the patch emits the IFN_ANNOTATE internal call only if the cond doesn't have obviously bogus type.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-01-17 Jakub Jelinek <ja...@redhat.com> PR middle-end/59706 * gimplify.c (gimplify_expr): Use create_tmp_var instead of create_tmp_var_raw. If cond doesn't have integral type, don't add the IFN_ANNOTATE builtin at all. * gfortran.dg/pr59706.f90: New test. * g++.dg/ext/pr59706.C: New test. --- gcc/gimplify.c.jj 2014-01-08 10:23:24.000000000 +0100 +++ gcc/gimplify.c 2014-01-17 16:51:12.324526084 +0100 @@ -7491,7 +7491,14 @@ gimplify_expr (tree *expr_p, gimple_seq { tree cond = TREE_OPERAND (*expr_p, 0); tree id = TREE_OPERAND (*expr_p, 1); - tree tmp = create_tmp_var_raw (TREE_TYPE(cond), NULL); + tree type = TREE_TYPE (cond); + if (!INTEGRAL_TYPE_P (type)) + { + *expr_p = cond; + ret = GS_OK; + break; + } + tree tmp = create_tmp_var (type, NULL); gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); gimple call = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, id); --- gcc/testsuite/gfortran.dg/pr59706.f90.jj 2014-01-17 17:19:23.665900803 +0100 +++ gcc/testsuite/gfortran.dg/pr59706.f90 2014-01-17 17:17:48.000000000 +0100 @@ -0,0 +1,10 @@ +! PR middle-end/59706 +! { dg-do compile } + + integer i + do concurrent (i=1:2) + end do +contains + subroutine foo + end +end --- gcc/testsuite/g++.dg/ext/pr59706.C.jj 2014-01-17 17:23:46.999556115 +0100 +++ gcc/testsuite/g++.dg/ext/pr59706.C 2014-01-17 17:20:53.000000000 +0100 @@ -0,0 +1,21 @@ +// PR middle-end/59706 +// { dg-do compile } + +extern struct S s; +struct T { T (); ~T (); int t; } t; + +void +foo () +{ + #pragma GCC ivdep + while (s) // { dg-error "could not convert" } + ; +} + +void +bar () +{ + #pragma GCC ivdep + while (t) // { dg-error "could not convert" } + ; +} Jakub