On 10/07/2013 07:02 AM, Jakub Jelinek wrote:
duplicates anywhere, but during error diagnostics.  Without those two decl.c
hunks (either of them), pushdecl will sometimes return a different decl from
the original or error_mark_node, and the original fndecl passed to it has
ggc_free called on it, thus any further use of it ICEs or may ICE.

Right.

Perhaps if pushdecl returns error_mark_node,
then I'd should expect that the error has been reported already and if
it returns some other FUNCTION_DECL, then I should report it myself,

Makes sense.

but a problem with that is that there are multiple locations that call
pushdecl (two in parser.c, one in pt.c) and more importantly, that for
the diagnostics the new fndecl is ggc_freed and thus I can't use it
for the diagnostics anymore.

True, though probably input_location is enough.

Trying to set DECL_CONTEXT to non-NULL for block_scope UDRs leads to
immediate ICEs as I said earlier, again on udr-3.C testcase:

pushdecl_maybe_friend_1 clearly doesn't expect anything to be in function scope,
and from what I remember from writing the UDR patch, it certainly wasn't the
only spot.

Right. Looking at the code again I see that block-scope function declarations have namespace DECL_CONTEXT and then have DECL_LOCAL_FUNCTION_P set on them. That probably makes sense for UDR functions as well.

Normal C++ lookup behavior is to check for ambiguity, so I think
that's the best bet for what the eventual defined semantics will be.

No response from omp-lang yet, so I'm not changing this yet.

Please do change it. The current behavior is just wrong, and we should set a good example for others to follow. It's ok to fix this in a follow-up patch.

Unfortunately it didn't work, again on the udr-3.C testcase.
mark_used was already called during instantiation of the decl, DECL_ODR_USED
got set on it, but it was actually deferred, then when mark_used is called
again on it, it is ignored.  I'd need to clear DECL_ODR_USED explicitly
and call mark_used, perhaps that would work.

If deferring it is a problem you can add UDRs to the group of things which are always instantiated immediately in mark_used:

  /* Normally, we can wait until instantiation-time to synthesize DECL.
     However, if DECL is a static data member initialized with a constant
     or a constexpr function, we need it right now because a reference to
     such a data member or a call to such function is not value-dependent.
     For a function that uses auto in the return type, we need to instantiate
     it to find out its type.  */
  if ((decl_maybe_constant_var_p (decl)
       || (TREE_CODE (decl) == FUNCTION_DECL
           && DECL_DECLARED_CONSTEXPR_P (decl))
       || undeduced_auto_decl (decl))
      && DECL_LANG_SPECIFIC (decl)
      && DECL_TEMPLATE_INFO (decl)
      && !uses_template_parms (DECL_TI_ARGS (decl)))

As for not using INIT_EXPR and just use DECL_EXPR gimplification, the problem
is that we do not actually gimplify it with the OMP_PRIV decl which has that
DECL_INITIAL from the parsing, but a different one - the original var referenced
by the clause, and that can have completely different DECL_INITIAL, or none at
all.

Ah, OK.

+       error_at (loc, "predeclared arithmetic type in %qT"
+       error_at (loc, "reference type in %qT"

"%qT in"

Jason

Reply via email to