On Wed, Feb 23, 2022 at 05:01:45PM +0100, Marcel Vollweiler wrote:
> gcc/cp/ChangeLog:
> 
>       * pt.cc (tsubst_omp_clauses): Add OMP_CLAUSE_HAS_DEVICE_ADDR.
>       * semantics.cc (finish_omp_clauses): Handle PARM_DECL and
>       NON_LVALUE_EXPR.
> 
> gcc/ChangeLog:
> 
>       * gimplify.cc (gimplify_scan_omp_clauses): Handle NON_LVALUE_EXPR.
>       (gimplify_adjust_omp_clauses): Likewise.
>       * omp-low.cc (scan_sharing_clauses): Likewise.
>       (lower_omp_target): Likewise.
> 
> libgomp/ChangeLog:
> 
>       * testsuite/libgomp.c++/target-has-device-addr-7.C: New test.
>       * testsuite/libgomp.c++/target-has-device-addr-8.C: New test.
>       * testsuite/libgomp.c++/target-has-device-addr-9.C: New test.
> 
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -17652,6 +17652,7 @@ tsubst_omp_clauses (tree clauses, enum 
> c_omp_region_type ort,
>       case OMP_CLAUSE_USE_DEVICE_PTR:
>       case OMP_CLAUSE_USE_DEVICE_ADDR:
>       case OMP_CLAUSE_IS_DEVICE_PTR:
> +     case OMP_CLAUSE_HAS_DEVICE_ADDR:
>       case OMP_CLAUSE_INCLUSIVE:
>       case OMP_CLAUSE_EXCLUSIVE:
>         OMP_CLAUSE_DECL (nc)
> @@ -17797,6 +17798,7 @@ tsubst_omp_clauses (tree clauses, enum 
> c_omp_region_type ort,
>         case OMP_CLAUSE_USE_DEVICE_PTR:
>         case OMP_CLAUSE_USE_DEVICE_ADDR:
>         case OMP_CLAUSE_IS_DEVICE_PTR:
> +       case OMP_CLAUSE_HAS_DEVICE_ADDR:
>         case OMP_CLAUSE_INCLUSIVE:
>         case OMP_CLAUSE_EXCLUSIVE:
>         case OMP_CLAUSE_ALLOCATE:

This part is ok.

> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 0cb17a6..452ecfd 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -8534,11 +8534,14 @@ finish_omp_clauses (tree clauses, enum 
> c_omp_region_type ort)
>           {
>             if (handle_omp_array_sections (c, ort))
>               remove = true;
> +           else if (TREE_CODE (TREE_CHAIN (t)) == PARM_DECL)
> +             t = TREE_CHAIN (t);
>             else
>               {
>                 t = OMP_CLAUSE_DECL (c);
>                 while (TREE_CODE (t) == INDIRECT_REF
> -                      || TREE_CODE (t) == ARRAY_REF)
> +                      || TREE_CODE (t) == ARRAY_REF
> +                      || TREE_CODE (t) == NON_LVALUE_EXPR)
>                   t = TREE_OPERAND (t, 0);
>               }
>           }

This is wrong.
When processing_template_decl, handle_omp_array_sections often punts, keeps
things as is because if something is dependent, we can't do much about it.
The else if (TREE_CODE (TREE_CHAIN (t)) == PARM_DECL) is obviously wrong,
there is really nothing specific about PARM_DECLs (just that you used
exactly that in the testcase), nor about array section with exactly one
dimension.  What is done elsewhere is look through all TREE_LISTs to find
the base expression, and if that expression is a VAR_DECL/PARM_DECL, nice,
we can do further processing, if processing_template_decl and it is
something different, just defer and otherwise error out.

So I think you want:
--- gcc/cp/semantics.cc.jj      2022-05-05 11:56:16.160443828 +0200
+++ gcc/cp/semantics.cc 2022-05-05 15:52:39.651211448 +0200
@@ -8553,14 +8553,23 @@ finish_omp_clauses (tree clauses, enum c
              else
                {
                  t = OMP_CLAUSE_DECL (c);
+                 if (TREE_CODE (t) == TREE_LIST)
+                   {
+                     while (TREE_CODE (t) == TREE_LIST)
+                       t = TREE_CHAIN (t);
+                   }
                  while (TREE_CODE (t) == INDIRECT_REF
                         || TREE_CODE (t) == ARRAY_REF)
                    t = TREE_OPERAND (t, 0);
                }
            }
-         bitmap_set_bit (&is_on_device_head, DECL_UID (t));
          if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
-           cxx_mark_addressable (t);
+           {
+             bitmap_set_bit (&is_on_device_head, DECL_UID (t));
+             if (!processing_template_decl
+                 && !cxx_mark_addressable (t))
+               remove = true;
+           }
          goto check_dup_generic_t;
 
        case OMP_CLAUSE_USE_DEVICE_ADDR:
instead, as I said look through the TREE_LISTs, then only use DECL_UID
on actual VAR_DECLs/PARM_DECLs not random other expressions and
never call cxx_mark_addressable when processing_template_decl (and remove
clause if cxx_mark_addressable fails).
Note, check_dup_generic_t will do among other things:
          if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
              && (!field_ok || TREE_CODE (t) != FIELD_DECL))
            {
              if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
                break;
              ... error ...
            }
so with processing_template_decl it will just defer it for later,
but otherwise if t is something invalid it will diagnose it.
But one really shouldn't rely on t being VAR_DECL/PARM_DECL before
that checking is done...

With your pt.cc change and my semantics.cc change, all your new testcases
look fine.

> diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
> index f570daa..b1bb5be 100644
> --- a/gcc/gimplify.cc
> +++ b/gcc/gimplify.cc
> @@ -10285,7 +10285,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
> *pre_p,
>       case OMP_CLAUSE_HAS_DEVICE_ADDR:
>         decl = OMP_CLAUSE_DECL (c);
>         while (TREE_CODE (decl) == INDIRECT_REF
> -              || TREE_CODE (decl) == ARRAY_REF)
> +              || TREE_CODE (decl) == ARRAY_REF
> +              || TREE_CODE (decl) == NON_LVALUE_EXPR)
>           decl = TREE_OPERAND (decl, 0);
>         flags = GOVD_EXPLICIT;
>         goto do_add_decl;
> @@ -11443,7 +11444,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, 
> gimple_seq body, tree *list_p,
>       case OMP_CLAUSE_HAS_DEVICE_ADDR:
>         decl = OMP_CLAUSE_DECL (c);
>         while (TREE_CODE (decl) == INDIRECT_REF
> -              || TREE_CODE (decl) == ARRAY_REF)
> +              || TREE_CODE (decl) == ARRAY_REF
> +              || TREE_CODE (decl) == NON_LVALUE_EXPR)
>           decl = TREE_OPERAND (decl, 0);
>         n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
>         remove = n == NULL || !(n->value & GOVD_SEEN);
> diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
> index 77176ef..30cc9b6 100644
> --- a/gcc/omp-low.cc
> +++ b/gcc/omp-low.cc
> @@ -1384,7 +1384,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
>               }
>             else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
>               {
> -               if (TREE_CODE (decl) == INDIRECT_REF)
> +               if (TREE_CODE (decl) == INDIRECT_REF
> +                   || TREE_CODE (decl) == NON_LVALUE_EXPR)
>                   decl = TREE_OPERAND (decl, 0);
>                 install_var_field (decl, true, 3, ctx);
>               }
> @@ -1747,7 +1748,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
>         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
>           {
>             while (TREE_CODE (decl) == INDIRECT_REF
> -                  || TREE_CODE (decl) == ARRAY_REF)
> +                  || TREE_CODE (decl) == ARRAY_REF
> +                  || TREE_CODE (decl) == NON_LVALUE_EXPR)
>               decl = TREE_OPERAND (decl, 0);
>           }
>  
> @@ -12847,7 +12849,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
> omp_context *ctx)
>       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
>         {
>           while (TREE_CODE (var) == INDIRECT_REF
> -                || TREE_CODE (var) == ARRAY_REF)
> +                || TREE_CODE (var) == ARRAY_REF
> +                || TREE_CODE (var) == NON_LVALUE_EXPR)
>             var = TREE_OPERAND (var, 0);
>         }
>       map_cnt++;
> @@ -13337,7 +13340,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
> omp_context *ctx)
>           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
>             {
>               while (TREE_CODE (ovar) == INDIRECT_REF
> -                    || TREE_CODE (ovar) == ARRAY_REF)
> +                    || TREE_CODE (ovar) == ARRAY_REF
> +                    || TREE_CODE (ovar) == NON_LVALUE_EXPR)
>                 ovar = TREE_OPERAND (ovar, 0);
>             }
>           var = lookup_decl_in_outer_ctx (ovar, ctx);
> @@ -13607,7 +13611,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
> omp_context *ctx)
>               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
>                 {
>                   while (TREE_CODE (var) == INDIRECT_REF
> -                        || TREE_CODE (var) == ARRAY_REF)
> +                        || TREE_CODE (var) == ARRAY_REF
> +                        || TREE_CODE (var) == NON_LVALUE_EXPR)
>                     var = TREE_OPERAND (var, 0);
>                 }
>               x = build_receiver_ref (var, false, ctx);

So all the gimplify.cc and omp-low.cc changes look suspicious.
NON_LVALUE_EXPR shouldn't show up there...

        Jakub

Reply via email to