[gomp4] C++ OpenMP user defined reductions (take 2)

Jason Merrill jason@redhat.com
Wed Oct 9 15:12:00 GMT 2013


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



More information about the Gcc-patches mailing list