Hi!
On Fri, Sep 20, 2013 at 12:00:41PM -0400, Jason Merrill wrote:
Thanks for the review, I'll try to get to most of that next week.
> On 09/12/2013 04:55 AM, Jakub Jelinek wrote:
> >- if (t1 != t2)
> >+ if (t1 != t2 && !DECL_OMP_DECLARE_REDUCTION_P (newdecl))
> > return 0;
>
> What's the theory here? Why should decls_match return true for
> reductions with mismatching templates?
In templates the UDRs are always FUNCTION_DECLs in classes or
at function block scope, the above one liner was I believe for the latter,
where without it duplicate_decls was returning incorrectly 0; the UDRs
from mismatching templates would actually never be seen by duplicate_decls,
but t1 was different from t2. That was before the changes to
add the mangled names to the UDR DECL_NAMEs though, I can try to remove it
and see if the whole testsuite still passes.
> >+ && ! (DECL_OMP_DECLARE_REDUCTION_P (newdecl)
> >+ && DECL_CONTEXT (newdecl) == NULL_TREE
> >+ && DECL_CONTEXT (olddecl) == current_function_decl))
>
> And this looks like you need to set DECL_CONTEXT sooner on reductions.
I know it is ugly, but setting FUNCTION_DECL DECL_CONTEXT too early resulted
in all kinds of problems, when the C++ frontend doesn't support nested
functions. So the patch doesn't set DECL_CONTEXT until it is pushdecled
into the block scope. The combiner/initializer expressions can't use vars
other than omp_{out,in,priv,orig}, so the UDRs aren't really nested in the
C nested function sense, and after all, after parsing the FUNCTION_DECL
for UDRs is just a container holding the expressions and artificial
VAR_DECLs, and is a FUNCTION_DECL so that normal C++ lookups can be
performed on it.
But like with the above, perhaps it isn't needed anymore, as with the
mangled type names in DECL_NAMEs we shouldn't really use overloads for UDRs.
> >+ if (TREE_CODE (argtype) == REFERENCE_TYPE)
> >+ error_at (DECL_SOURCE_LOCATION (t),
> >+ "function, array or reference type in "
> >+ "%<#pragma omp declare reduction%>");
>
> Let's just say "reference type", since we know that's what it is.
That is true, but I wanted to match the same error message elsewhere,
otherwise the error will be different (more specific) for instantiation
vs. in non-template code. Though, I could of course in that second spot
just special case REFERENCE_TYPE with a separate error message
and just have one about function or array type.
>
> >+ && DECL_CONTEXT (pattern_decl)
> >+ && TREE_CODE (DECL_CONTEXT (pattern_decl))
> >+ == FUNCTION_DECL)
>
> This is DECL_FUNCTION_SCOPE_P.
>
> >+ return TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
> >+ || is_invisiref_parm (decl);
>
> Needs parens to protect indentation.
>
> >+/* Instantiate the special body of the artificial DECL_OMP_DECLARE_REDUCTION
> >+ function. */
>
> We could use documentation of what this special body looks like,
> either here, in cp_check_omp_declare_reduction, or elsewhere.
3xOk.
>
> >+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
> >+ {
> >+ id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo));
> >+ if (id != NULL_TREE)
> >+ return id;
>
> This should check for ambiguity rather than returning the first match.
I believe I need to discuss that on omp-lang, what exactly is the intended
behavior (and get the standard clarified). Returning the first base class
is an option (and, depth-first vs. breadth-first?), or erroring out if more
than one base class has an UDR is another.
> >+ Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
> >+ DECL_EXPR. */
>
> Why not let the DECL_EXPR handle initialization?
I can try that.
> Let's break out the finish_omp_clauses reduction code into a
> separate function, as it's rather large.
Will try that.
>
> >+ if (DECL_TEMPLATE_INFO (id))
> >+ id = instantiate_decl (id, /*defer_ok*/0, true);
>
> Let's use mark_used instead.
Will that always instantiate it?
Jakub