https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123597

--- Comment #6 from Tobias Burnus <burnus at gcc dot gnu.org> ---
The problem seems to be related to 'pushdecl' (called during template
substitution in pt.cc) putting 'sum' into the same scope as the
'long int j' iteration variable.
Only the
  '<<cleanup_point int sum = 99;>>;'
remains at the original place.

I bet the problem occurs due to the following in parser.cc's
cp_parser_omp_for_loop

  /* Do the substitution from the inside out.  */
  for (unsigned int i = count - 1; i > 0; i--)
    if (data.init_placeholderv[i])
      for (unsigned int j = i; j > 0; j--)
        if (data.body_blockv[j - 1])
          {
            substitute_in_tree (&data.body_blockv[j - 1],
                                data.init_placeholderv[i],
                                data.body_blockv[i], false);
/*...*/     break;
          }

Which moves the body of the inner omp-for loop (body_blockv[1]) to
the outermost nest-for loop.


My feeling - which might be wrong - is that the 'sum' variable is
originally created with a binding in the inner omp-for loop and that's
saved in IDENTIFIER_BINDING (decl) = ...

As the code is now moved, the code is no longer in that binding - and
find_local_binding - invoked via 'pushdecl' during the t-expr substitution
cannot find it anymore and then adds it to the current_binding_level which is
the one of OMP_FOR (i.e. before the for loops) instead of in the binding of the
body.

This would also explain why 'collapse(1)' works as the scope is already OK -
and I guess, without dependent type, the binding does not matter as no
'pushdecl' is called for it again.

Disclaimer: My suspicion might be also wrong as I have not fully understood how
current_binding_level is handled nor have I fully dug through the code nor
walked it properly in 'gdb'.

Reply via email to