Hi!

On 2017-04-26T13:08:11-0700, Cesar Philippidis <ce...@codesourcery.com> wrote:
> This patches updates the c and c++ FEs to report consistent error
> messages for invalid reductions involving array elements, struct
> members, and class members. Most of those variables were already
> rejected by the generic OpenMP code, but this patch makes the error
> messages more precise for OpenACC. It also fixes an ICE involving
> invalid struct member reductions in c.
>
> I've committed this patch to gomp-4_0-branch.

It then got into openacc-gcc-8-branch in commit
16ead336bc86fade855e0ec2edfc257286f429b6 "[OpenACC] Update error messages
for c and c++ reductions", was proposed for GCC trunk in
<http://mid.mail-archive.com/ae587152-072d-52b0-0129-99de0ed40d03@codesourcery.com>
"various OpenACC reduction enhancements" (together with other, unrelated
changes...), and got into openacc-gcc-9-branch in commit
533beb2ec19f8486e4b1b645a153746f96b41f04 "Various OpenACC reduction
enhancements - FE changes" (together with other, unrelated changes...).


At least in their og8 incarnation (have not yet verified other
branches/patches), I find these changes cause quite a serious regression
in the C front end.  Given the buggy:

    #pragma acc routine vector
    int f(int n)
    {
      int plus = 0;
      int minus = 0;
    #pragma acc loop reduction(+:plus, -:minus)
      for (int i = 0; i < n; ++i)
        ++plus, --minus;
    
      return plus * minus;
    }

..., where we used to (and still do for C++) diagnose:

    [...]: In function 'f':
    [...]:6:35: error: expected ')' before '-' token
     #pragma acc loop reduction(+:plus, -:minus)
                               ~       ^~
                                       )

..., with the patch applied, this doesn't get any diagnostic anymore, so
wrong-code gets generated.


Grüße
 Thomas


>       gcc/c/
>       * c-parser.c (c_parser_omp_variable_list): New c_omp_region_type
>       argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
>       OpenACC.
>       (c_parser_omp_clause_reduction): Update call to
>       c_parser_omp_variable_list.  Propage OpenACC errors as necessary.
>       (c_parser_oacc_all_clauses): Update call to
>       p_parser_omp_clause_reduction.
>       (c_parser_omp_all_clauses): Likewise.
>       (c_parser_cilk_all_clauses): Likewise.
>
>       gcc/cp/
>       * parser.c (cp_parser_omp_var_list_no_open): New c_omp_region_type
>       argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
>       OpenACC.
>       (cp_parser_omp_clause_reduction): Update call to
>       cp_parser_omp_variable_list.  Propage OpenACC errors as necessary.
>       (cp_parser_oacc_all_clauses): Update call to
>       cp_parser_omp_clause_reduction..
>       (cp_parser_omp_all_clauses): Liekwise.
>       (cp_parser_cilk_simd_all_clauses): Likewise.
>
>       gcc/testsuite/
>       * c-c++-common/goacc/reduction-7.c: New test.
>       * g++.dg/goacc/reductions-1.C: New test.

> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index 05b9774..b1af31f 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -10618,7 +10618,8 @@ c_parser_oacc_wait_list (c_parser *parser, location_t 
> clause_loc, tree list)
>  static tree
>  c_parser_omp_variable_list (c_parser *parser,
>                           location_t clause_loc,
> -                         enum omp_clause_code kind, tree list)
> +                         enum omp_clause_code kind, tree list,
> +                         enum c_omp_region_type ort = C_ORT_OMP)
>  {
>    if (c_parser_next_token_is_not (parser, CPP_NAME)
>        || c_parser_peek_token (parser)->id_kind != C_ID_ID)
> @@ -10674,6 +10675,22 @@ c_parser_omp_variable_list (c_parser *parser,
>             /* FALLTHROUGH  */
>           case OMP_CLAUSE_DEPEND:
>           case OMP_CLAUSE_REDUCTION:
> +           if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_ACC)
> +             {
> +               switch (c_parser_peek_token (parser)->type)
> +                 {
> +                 case CPP_OPEN_PAREN:
> +                 case CPP_OPEN_SQUARE:
> +                 case CPP_DOT:
> +                 case CPP_DEREF:
> +                   error ("invalid reduction variable");
> +                   t = error_mark_node;
> +                 default:;
> +                   break;
> +                 }
> +               if (t == error_mark_node)
> +                 break;
> +             }
>             while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
>               {
>                 tree low_bound = NULL_TREE, length = NULL_TREE;
> @@ -12039,9 +12056,12 @@ c_parser_omp_clause_private (c_parser *parser, tree 
> list)
>       identifier  */
>  
>  static tree
> -c_parser_omp_clause_reduction (c_parser *parser, tree list)
> +c_parser_omp_clause_reduction (c_parser *parser, tree list,
> +                            enum c_omp_region_type ort)
>  {
>    location_t clause_loc = c_parser_peek_token (parser)->location;
> +  bool seen_error = false;
> +
>    if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
>      {
>        enum tree_code code = ERROR_MARK;
> @@ -12104,7 +12124,13 @@ c_parser_omp_clause_reduction (c_parser *parser, 
> tree list)
>         tree nl, c;
>  
>         nl = c_parser_omp_variable_list (parser, clause_loc,
> -                                        OMP_CLAUSE_REDUCTION, list);
> +                                        OMP_CLAUSE_REDUCTION, list, ort);
> +       if (c_parser_peek_token (parser)->type != CPP_CLOSE_PAREN)
> +         {
> +           seen_error = true;
> +           goto cleanup;
> +         }
> +
>         for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
>           {
>             tree d = OMP_CLAUSE_DECL (c), type;
> @@ -12133,14 +12159,16 @@ c_parser_omp_clause_reduction (c_parser *parser, 
> tree list)
>                 || !(INTEGRAL_TYPE_P (type)
>                      || TREE_CODE (type) == REAL_TYPE
>                      || TREE_CODE (type) == COMPLEX_TYPE))
> -             OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
> +               OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
>                 = c_omp_reduction_lookup (reduc_id,
>                                           TYPE_MAIN_VARIANT (type));
>           }
>  
>         list = nl;
>       }
> -      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
> +    cleanup:
> +      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
> +                              seen_error ? NULL : "expected %<)%>");
>      }
>    return list;
>  }
> @@ -13272,7 +13300,7 @@ c_parser_oacc_all_clauses (c_parser *parser, 
> omp_clause_mask mask,
>         c_name = "private";
>         break;
>       case PRAGMA_OACC_CLAUSE_REDUCTION:
> -       clauses = c_parser_omp_clause_reduction (parser, clauses);
> +       clauses = c_parser_omp_clause_reduction (parser, clauses, C_ORT_ACC);
>         c_name = "reduction";
>         break;
>       case PRAGMA_OACC_CLAUSE_SEQ:
> @@ -13432,7 +13460,7 @@ c_parser_omp_all_clauses (c_parser *parser, 
> omp_clause_mask mask,
>         c_name = "private";
>         break;
>       case PRAGMA_OMP_CLAUSE_REDUCTION:
> -       clauses = c_parser_omp_clause_reduction (parser, clauses);
> +       clauses = c_parser_omp_clause_reduction (parser, clauses, C_ORT_OMP);
>         c_name = "reduction";
>         break;
>       case PRAGMA_OMP_CLAUSE_SCHEDULE:
> @@ -17764,7 +17792,7 @@ c_parser_cilk_all_clauses (c_parser *parser)
>         break;
>       case PRAGMA_CILK_CLAUSE_REDUCTION:
>         /* Use the OpenMP counterpart.  */
> -       clauses = c_parser_omp_clause_reduction (parser, clauses);
> +       clauses = c_parser_omp_clause_reduction (parser, clauses, C_ORT_CILK);
>         break;
>       default:
>         c_parser_error (parser, "expected %<#pragma simd%> clause");
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 4080b8a..b082feb 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -30009,7 +30009,8 @@ check_no_duplicate_clause (tree clauses, enum 
> omp_clause_code code,
>  
>  static tree
>  cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
> -                             tree list, bool *colon)
> +                             tree list, bool *colon,
> +                             enum c_omp_region_type ort = C_ORT_OMP)
>  {
>    cp_token *token;
>    bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
> @@ -30082,6 +30083,21 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, 
> enum omp_clause_code kind,
>             /* FALLTHROUGH.  */
>           case OMP_CLAUSE_DEPEND:
>           case OMP_CLAUSE_REDUCTION:
> +           if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_ACC)
> +             {
> +               switch (cp_lexer_peek_token (parser->lexer)->type)
> +                 {
> +                 case CPP_OPEN_PAREN:
> +                 case CPP_OPEN_SQUARE:
> +                 case CPP_DOT:
> +                 case CPP_DEREF:
> +                   error ("invalid reduction variable");
> +                   decl = error_mark_node;
> +                   goto skip_comma;
> +                 default:;
> +                   break;
> +                 }
> +             }
>             while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
>               {
>                 tree low_bound = NULL_TREE, length = NULL_TREE;
> @@ -31215,7 +31231,8 @@ cp_parser_omp_clause_ordered (cp_parser *parser,
>       id-expression  */
>  
>  static tree
> -cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
> +cp_parser_omp_clause_reduction (cp_parser *parser, tree list,
> +                             enum c_omp_region_type ort)
>  {
>    enum tree_code code = ERROR_MARK;
>    tree nlist, c, id = NULL_TREE;
> @@ -31296,7 +31313,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, 
> tree list)
>      goto resync_fail;
>  
>    nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list,
> -                                       NULL);
> +                                       NULL, ort);
>    for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
>      {
>        OMP_CLAUSE_REDUCTION_CODE (c) = code;
> @@ -32426,7 +32443,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, 
> omp_clause_mask mask,
>         c_name = "private";
>         break;
>       case PRAGMA_OACC_CLAUSE_REDUCTION:
> -       clauses = cp_parser_omp_clause_reduction (parser, clauses);
> +       clauses = cp_parser_omp_clause_reduction (parser, clauses, C_ORT_ACC);
>         c_name = "reduction";
>         break;
>       case PRAGMA_OACC_CLAUSE_SEQ:
> @@ -32618,7 +32635,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
> omp_clause_mask mask,
>         c_name = "private";
>         break;
>       case PRAGMA_OMP_CLAUSE_REDUCTION:
> -       clauses = cp_parser_omp_clause_reduction (parser, clauses);
> +       clauses = cp_parser_omp_clause_reduction (parser, clauses, C_ORT_OMP);
>         c_name = "reduction";
>         break;
>       case PRAGMA_OMP_CLAUSE_SCHEDULE:
> @@ -38038,7 +38055,7 @@ cp_parser_cilk_simd_all_clauses (cp_parser *parser, 
> cp_token *pragma_token)
>                                         clauses);
>        else if (c_kind == PRAGMA_CILK_CLAUSE_REDUCTION)
>       /* Use the OMP 4.0 equivalent function.  */
> -     clauses = cp_parser_omp_clause_reduction (parser, clauses);
> +     clauses = cp_parser_omp_clause_reduction (parser, clauses, C_ORT_CILK);
>        else
>       {
>         clauses = error_mark_node;
> diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-7.c 
> b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
> new file mode 100644
> index 0000000..5d48dda
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
> @@ -0,0 +1,113 @@
> +/* Exercise invalid reductions on array and struct members.  */
> +
> +/* { dg-compile } */
> +
> +void
> +test_parallel ()
> +{
> +  struct {
> +    int a;
> +    float b[5];
> +  } s1, s2[10];
> +
> +  int i;
> +  double z[100];
> +
> +#pragma acc parallel reduction(+:s1.a) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.a += 1;
> +
> +#pragma acc parallel reduction(+:s1.b[3]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.b[3] += 1;
> +
> +#pragma acc parallel reduction(+:s2[2].a) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[2].a += 1;
> +
> +#pragma acc parallel reduction(+:s2[3].b[4]) /* { dg-error "invalid 
> reduction variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[3].b[4] += 1;
> +
> +#pragma acc parallel reduction(+:z[5]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    z[5] += 1;
> +}
> +
> +void
> +test_combined ()
> +{
> +  struct {
> +    int a;
> +    float b[5];
> +  } s1, s2[10];
> +
> +  int i;
> +  double z[100];
> +
> +#pragma acc parallel loop reduction(+:s1.a) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.a += 1;
> +
> +#pragma acc parallel loop reduction(+:s1.b[3]) /* { dg-error "invalid 
> reduction variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.b[3] += 1;
> +
> +#pragma acc parallel loop reduction(+:s2[2].a) /* { dg-error "invalid 
> reduction variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[2].a += 1;
> +
> +#pragma acc parallel loop reduction(+:s2[3].b[4]) /* { dg-error "invalid 
> reduction variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[3].b[4] += 1;
> +
> +#pragma acc parallel loop reduction(+:z[5]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    z[5] += 1;
> +
> +}
> +
> +void
> +test_loops ()
> +{
> +  struct {
> +    int a;
> +    float b[5];
> +  } s1, s2[10];
> +
> +  int i;
> +  double z[100];
> +
> +#pragma acc parallel
> +  {
> +#pragma acc loop reduction(+:s1.a) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.a += 1;
> +
> +#pragma acc loop reduction(+:s1.b[3]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s1.b[3] += 1;
> +
> +#pragma acc loop reduction(+:s2[2].a) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[2].a += 1;
> +
> +#pragma acc loop reduction(+:s2[3].b[4]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    s2[3].b[4] += 1;
> +
> +#pragma acc loop reduction(+:z[5]) /* { dg-error "invalid reduction 
> variable" } */
> +  for (i = 0; i < 10; i++)
> +    z[5] += 1;
> +  }
> +}
> +
> +int
> +main ()
> +{
> +  test_parallel ();
> +  test_combined ();
> +  test_loops ();
> +
> +  return 0;
> +}
> diff --git a/gcc/testsuite/g++.dg/goacc/reductions-1.C 
> b/gcc/testsuite/g++.dg/goacc/reductions-1.C
> new file mode 100644
> index 0000000..50a6e5e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/goacc/reductions-1.C
> @@ -0,0 +1,550 @@
> +// Test for invalid reduction variables.
> +
> +// { dg-do compile }
> +
> +class C1
> +{
> +  int b, d[10];
> +
> +public:
> +  int a, c[10];
> +
> +  C1 () { a = 0; b = 0; }
> +  int& get_b () { return b; }
> +  int* get_d () { return d; }
> +};
> +
> +template <typename T>
> +class C2
> +{
> +  T b, d[10];
> +
> +public:
> +  T a, c[10];
> +
> +  C2 () { a = 0; b = 0; }
> +  T& get_b () { return b; }
> +  T* get_d () { return d; }
> +};
> +
> +struct S1
> +{
> +  int a, b, c[10], d[10];
> +
> +  S1 () { a = 0; b = 0; }
> +  int& get_b () { return b; }
> +  int* get_d () { return d; }
> +};
> +
> +template <typename T>
> +struct S2
> +{
> +  T a, b, c[10], d[10];
> +
> +  S2 () { a = 0; b = 0; }
> +  T& get_b () { return b; }
> +  T* get_d () { return d; }
> +};
> +
> +template <typename T>
> +void
> +test_parallel ()
> +{
> +  int i, a[10];
> +  T b[10];
> +  C1 c1, c1a[10];
> +  C2<T> c2, c2a[10];
> +  S1 s1, s1a[10];
> +  S2<float> s2, s2a[10];
> +
> +  // Reductions on class members.
> +
> +#pragma acc parallel reduction(+:c1.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.a += 1;
> +
> +#pragma acc parallel reduction(+:c1.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.get_b () += 1;
> +
> +#pragma acc parallel reduction(+:c1.c[1]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.c[1] += 1;
> +
> +#pragma acc parallel reduction(+:c1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.get_d ()[1] += 1;
> +
> +#pragma acc parallel reduction(+:c1a[1].a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].a += 1;
> +
> +#pragma acc parallel reduction(+:c1a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].get_b () += 1;
> +
> +#pragma acc parallel reduction(+:c1a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].c[1] += 1;
> +
> +#pragma acc parallel reduction(+:c1a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on a template class member.
> +
> +#pragma acc parallel reduction(+:c2.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.a += 1;
> +
> +#pragma acc parallel reduction(+:c2.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.get_b () += 1;
> +
> +#pragma acc parallel reduction(+:c2.c[1]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.c[1] += 1;
> +
> +#pragma acc parallel reduction(+:c2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.get_d ()[1] += 1;
> +
> +
> +#pragma acc parallel reduction(+:c2a[1].a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].a += 1;
> +
> +#pragma acc parallel reduction(+:c2a[1].get_b ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].get_b () += 1;
> +
> +#pragma acc parallel reduction(+:c2a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].c[1] += 1;
> +
> +#pragma acc parallel reduction(+:c2a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on struct element.
> +
> +#pragma acc parallel reduction(+:s1.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.a += 1;
> +
> +#pragma acc parallel reduction(+:s1.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.get_b () += 1;
> +
> +#pragma acc parallel reduction(+:s1.c[1]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.c[1] += 1;
> +
> +#pragma acc parallel reduction(+:s1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.get_d ()[1] += 1;
> +
> +#pragma acc parallel reduction(+:s1a[1].a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].a += 1;
> +
> +#pragma acc parallel reduction(+:s1a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].get_b () += 1;
> +
> +#pragma acc parallel reduction(+:s1a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].c[1] += 1;
> +
> +#pragma acc parallel reduction(+:s1a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on a template struct element.
> +
> +#pragma acc parallel reduction(+:s2.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.a += 1;
> +
> +#pragma acc parallel reduction(+:s2.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.get_b () += 1;
> +
> +#pragma acc parallel reduction(+:s2.c[1]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.c[1] += 1;
> +
> +#pragma acc parallel reduction(+:s2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.get_d ()[1] += 1;
> +
> +#pragma acc parallel reduction(+:s2a[1].a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].a += 1;
> +
> +#pragma acc parallel reduction(+:s2a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].get_b () += 1;
> +
> +#pragma acc parallel reduction(+:s2a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].c[1] += 1;
> +
> +#pragma acc parallel reduction(+:s2a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on arrays.
> +
> +#pragma acc parallel reduction(+:a[10]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    a[10] += 1;
> +
> +#pragma acc parallel reduction(+:b[10]) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    b[10] += 1;
> +}
> +
> +template <typename T>
> +void
> +test_combined ()
> +{
> +  int i, a[10];
> +  T b[10];
> +  C1 c1, c1a[10];
> +  C2<T> c2, c2a[10];
> +  S1 s1, s1a[10];
> +  S2<float> s2, s2a[10];
> +
> +  // Reductions on class members.
> +
> +#pragma acc parallel loop reduction(+:c1.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.a += 1;
> +
> +#pragma acc parallel loop reduction(+:c1.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:c1.c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:c1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1.get_d ()[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:c1a[1].a) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].a += 1;
> +
> +#pragma acc parallel loop reduction(+:c1a[1].get_b ()) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:c1a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:c1a[1].get_d ()[1]) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c1a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on a template class member.
> +
> +#pragma acc parallel loop reduction(+:c2.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.a += 1;
> +
> +#pragma acc parallel loop reduction(+:c2.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:c2.c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:c2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2.get_d ()[1] += 1;
> +
> +
> +#pragma acc parallel loop reduction(+:c2a[1].a) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].a += 1;
> +
> +#pragma acc parallel loop reduction(+:c2a[1].get_b ()[1]) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:c2a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:c2a[1].get_d ()[1]) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    c2a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on struct element.
> +
> +#pragma acc parallel loop reduction(+:s1.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.a += 1;
> +
> +#pragma acc parallel loop reduction(+:s1.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:s1.c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1.get_d ()[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s1a[1].a) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].a += 1;
> +
> +#pragma acc parallel loop reduction(+:s1a[1].get_b ()) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:s1a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s1a[1].get_d ()[1]) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s1a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on a template struct element.
> +
> +#pragma acc parallel loop reduction(+:s2.a) // { dg-error "invalid reduction 
> variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.a += 1;
> +
> +#pragma acc parallel loop reduction(+:s2.get_b ()) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:s2.c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2.get_d ()[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s2a[1].a) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].a += 1;
> +
> +#pragma acc parallel loop reduction(+:s2a[1].get_b ()) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].get_b () += 1;
> +
> +#pragma acc parallel loop reduction(+:s2a[1].c[1]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].c[1] += 1;
> +
> +#pragma acc parallel loop reduction(+:s2a[1].get_d ()[1]) // { dg-error 
> "invalid reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    s2a[1].get_d ()[1] += 1;
> +
> +
> +  // Reductions on arrays.
> +
> +#pragma acc parallel loop reduction(+:a[10]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    a[10] += 1;
> +
> +#pragma acc parallel loop reduction(+:b[10]) // { dg-error "invalid 
> reduction variable" }
> +  for (i = 0; i < 100; i++)
> +    b[10] += 1;
> +}
> +
> +template <typename T>
> +void
> +test_loop ()
> +{
> +  int i, a[10];
> +  T b[10];
> +  C1 c1, c1a[10];
> +  C2<T> c2, c2a[10];
> +  S1 s1, s1a[10];
> +  S2<float> s2, s2a[10];
> +
> +  // Reductions on class members.
> +
> +  #pragma acc parallel
> +  {
> +
> +#pragma acc loop reduction(+:c1.a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c1.a += 1;
> +
> +#pragma acc loop reduction(+:c1.get_b ()) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c1.get_b () += 1;
> +
> +#pragma acc loop reduction(+:c1.c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c1.c[1] += 1;
> +
> +#pragma acc loop reduction(+:c1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c1.get_d ()[1] += 1;
> +
> +#pragma acc loop reduction(+:c1a[1].a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c1a[1].a += 1;
> +
> +#pragma acc loop reduction(+:c1a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c1a[1].get_b () += 1;
> +
> +#pragma acc loop reduction(+:c1a[1].c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c1a[1].c[1] += 1;
> +
> +#pragma acc loop reduction(+:c1a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c1a[1].get_d ()[1] += 1;
> +
> +
> +    // Reductions on a template class member.
> +
> +#pragma acc loop reduction(+:c2.a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c2.a += 1;
> +
> +#pragma acc loop reduction(+:c2.get_b ()) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c2.get_b () += 1;
> +
> +#pragma acc loop reduction(+:c2.c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c2.c[1] += 1;
> +
> +#pragma acc loop reduction(+:c2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c2.get_d ()[1] += 1;
> +
> +
> +#pragma acc loop reduction(+:c2a[1].a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c2a[1].a += 1;
> +
> +#pragma acc loop reduction(+:c2a[1].get_b ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c2a[1].get_b () += 1;
> +
> +#pragma acc loop reduction(+:c2a[1].c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      c2a[1].c[1] += 1;
> +
> +#pragma acc loop reduction(+:c2a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      c2a[1].get_d ()[1] += 1;
> +
> +
> +    // Reductions on struct element.
> +
> +#pragma acc loop reduction(+:s1.a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s1.a += 1;
> +
> +#pragma acc loop reduction(+:s1.get_b ()) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s1.get_b () += 1;
> +
> +#pragma acc loop reduction(+:s1.c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s1.c[1] += 1;
> +
> +#pragma acc loop reduction(+:s1.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s1.get_d ()[1] += 1;
> +
> +#pragma acc loop reduction(+:s1a[1].a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s1a[1].a += 1;
> +
> +#pragma acc loop reduction(+:s1a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s1a[1].get_b () += 1;
> +
> +#pragma acc loop reduction(+:s1a[1].c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s1a[1].c[1] += 1;
> +
> +#pragma acc loop reduction(+:s1a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s1a[1].get_d ()[1] += 1;
> +
> +
> +    // Reductions on a template struct element.
> +
> +#pragma acc loop reduction(+:s2.a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s2.a += 1;
> +
> +#pragma acc loop reduction(+:s2.get_b ()) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s2.get_b () += 1;
> +
> +#pragma acc loop reduction(+:s2.c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s2.c[1] += 1;
> +
> +#pragma acc loop reduction(+:s2.get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s2.get_d ()[1] += 1;
> +
> +#pragma acc loop reduction(+:s2a[1].a) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s2a[1].a += 1;
> +
> +#pragma acc loop reduction(+:s2a[1].get_b ()) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s2a[1].get_b () += 1;
> +
> +#pragma acc loop reduction(+:s2a[1].c[1]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      s2a[1].c[1] += 1;
> +
> +#pragma acc loop reduction(+:s2a[1].get_d ()[1]) // { dg-error "invalid 
> reduction variable" }
> +    for (i = 0; i < 100; i++)
> +      s2a[1].get_d ()[1] += 1;
> +
> +
> +    // Reductions on arrays.
> +
> +#pragma acc loop reduction(+:a[10]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      a[10] += 1;
> +
> +#pragma acc loop reduction(+:b[10]) // { dg-error "invalid reduction 
> variable" }
> +    for (i = 0; i < 100; i++)
> +      b[10] += 1;
> +  }
> +}
> +
> +int
> +main ()
> +{
> +  test_parallel<double> ();
> +  test_combined<long> ();
> +  test_loop<short> ();
> +
> +  return 0;
> +}

Attachment: signature.asc
Description: PGP signature

Reply via email to