* c-parser.c (c_finish_taskloop_clauses): New function.
(c_parser_omp_taskloop): Use it.
* c-typeck.c (c_finish_omp_clauses): Call save_expr for whole array
reduction sizes. Diagnose reductions with zero sized elements or
variable length structures.
* semantics.c (finish_omp_reduction_clause): Call save_expr for
whole array reduction sizes.
* gcc.dg/gomp/reduction-2.c: New test.
From-SVN: r265236
+2018-10-17 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_finish_taskloop_clauses): New function.
+ (c_parser_omp_taskloop): Use it.
+ * c-typeck.c (c_finish_omp_clauses): Call save_expr for whole array
+ reduction sizes. Diagnose reductions with zero sized elements or
+ variable length structures.
+
2018-10-16 Jakub Jelinek <jakub@redhat.com>
* c-typeck.c (handle_omp_array_sections): Call save_expr on array
error_at (loc, "%<pragma omp requires%> requires at least one clause");
}
+/* Helper function for c_parser_omp_taskloop.
+ Disallow zero sized or potentially zero sized task reductions. */
+
+static tree
+c_finish_taskloop_clauses (tree clauses)
+{
+ tree *pc = &clauses;
+ for (tree c = clauses; c; c = *pc)
+ {
+ bool remove = false;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ {
+ tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
+ if (integer_zerop (TYPE_SIZE_UNIT (type)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "zero sized type %qT in %<reduction%> clause", type);
+ remove = true;
+ }
+ else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "variable sized type %qT in %<reduction%> clause",
+ type);
+ remove = true;
+ }
+ }
+ if (remove)
+ *pc = OMP_CLAUSE_CHAIN (c);
+ else
+ pc = &OMP_CLAUSE_CHAIN (c);
+ }
+ return clauses;
+}
+
/* OpenMP 4.5:
#pragma omp taskloop taskloop-clause[optseq] new-line
for-loop
TREE_TYPE (ret) = void_type_node;
OMP_FOR_BODY (ret) = block;
OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+ OMP_FOR_CLAUSES (ret)
+ = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
SET_EXPR_LOCATION (ret, loc);
add_stmt (ret);
return ret;
clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
}
+ clauses = c_finish_taskloop_clauses (clauses);
block = c_begin_compound_stmt (true);
ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
block = c_end_compound_stmt (loc, block, true);
break;
}
size = size_binop (MINUS_EXPR, size, size_one_node);
+ size = save_expr (size);
tree index_type = build_index_type (size);
tree atype = build_array_type (type, index_type);
tree ptype = build_pointer_type (type);
remove = true;
break;
}
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
+ || OMP_CLAUSE_REDUCTION_TASK (c))
+ {
+ /* Disallow zero sized or potentially zero sized task
+ reductions. */
+ if (integer_zerop (TYPE_SIZE_UNIT (type)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "zero sized type %qT in %qs clause", type,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ break;
+ }
+ else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "variable sized type %qT in %qs clause", type,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ break;
+ }
+ }
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE
&& (FLOAT_TYPE_P (type)
|| TREE_CODE (type) == COMPLEX_TYPE))
+2018-10-17 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_reduction_clause): Call save_expr for
+ whole array reduction sizes.
+
2018-10-16 Jakub Jelinek <jakub@redhat.com>
* pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_IN_REDUCTION and
return true;
}
size = size_binop (MINUS_EXPR, size, size_one_node);
+ size = save_expr (size);
tree index_type = build_index_type (size);
tree atype = build_array_type (type, index_type);
tree ptype = build_pointer_type (type);
+2018-10-17 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/gomp/reduction-2.c: New test.
+
2018-10-16 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/clauses-1.c (r2): New variable.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+struct S {};
+void foo (void *, void *);
+void bar (void *, void *);
+void baz (void *);
+#pragma omp declare reduction(+:struct S:foo (&omp_out, &omp_in))initializer(bar(&omp_priv, &omp_orig))
+
+void
+test1 (void)
+{
+ struct S s;
+ int i;
+ #pragma omp parallel reduction(+:s)
+ baz (&s);
+ #pragma omp parallel reduction(task, +:s) /* { dg-error "zero sized type 'struct S' in 'reduction' clause" } */
+ baz (&s);
+ #pragma omp taskloop reduction(+:s) /* { dg-error "zero sized type 'struct S' in 'reduction' clause" } */
+ for (i = 0; i < 1; i++)
+ baz (&s);
+ #pragma omp taskloop simd reduction(+:s) /* { dg-error "zero sized type 'struct S' in 'reduction' clause" } */
+ for (i = 0; i < 1; i++)
+ baz (&s);
+ #pragma omp taskgroup task_reduction(+:s) /* { dg-error "zero sized type 'struct S' in 'task_reduction' clause" } */
+ {
+ #pragma omp task in_reduction(+:s) /* { dg-error "zero sized type 'struct S' in 'in_reduction' clause" } */
+ baz (&s);
+ }
+}