From: Jakub Jelinek Date: Wed, 17 Oct 2018 10:49:14 +0000 (+0200) Subject: c-parser.c (c_finish_taskloop_clauses): New function. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa6eab80c9638073f3a15ce80cdfaf8780879fb0;p=thirdparty%2Fgcc.git c-parser.c (c_finish_taskloop_clauses): New function. * 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 --- diff --git a/gcc/c/ChangeLog.gomp b/gcc/c/ChangeLog.gomp index d759f0d8a78e..e4fcbc43c571 100644 --- a/gcc/c/ChangeLog.gomp +++ b/gcc/c/ChangeLog.gomp @@ -1,3 +1,11 @@ +2018-10-17 Jakub Jelinek + + * 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 * c-typeck.c (handle_omp_array_sections): Call save_expr on array diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 8c3e2568b515..84036a9c049e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -18823,6 +18823,41 @@ c_parser_omp_requires (c_parser *parser) error_at (loc, "% 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 % 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 % 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 @@ -18880,6 +18915,8 @@ c_parser_omp_taskloop (location_t loc, c_parser *parser, 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; @@ -18898,6 +18935,7 @@ c_parser_omp_taskloop (location_t loc, c_parser *parser, 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); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 9f03ff7defdf..70ec23baadd7 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13343,6 +13343,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) 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); @@ -13358,6 +13359,28 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) 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)) diff --git a/gcc/cp/ChangeLog.gomp b/gcc/cp/ChangeLog.gomp index 88c01445757a..7d853b9f9d2a 100644 --- a/gcc/cp/ChangeLog.gomp +++ b/gcc/cp/ChangeLog.gomp @@ -1,3 +1,8 @@ +2018-10-17 Jakub Jelinek + + * semantics.c (finish_omp_reduction_clause): Call save_expr for + whole array reduction sizes. + 2018-10-16 Jakub Jelinek * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_IN_REDUCTION and diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 23d4e51ed042..894fec13cf09 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5567,6 +5567,7 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) 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); diff --git a/gcc/testsuite/ChangeLog.gomp b/gcc/testsuite/ChangeLog.gomp index 6e143f3118c1..d134e31b3d2a 100644 --- a/gcc/testsuite/ChangeLog.gomp +++ b/gcc/testsuite/ChangeLog.gomp @@ -1,3 +1,7 @@ +2018-10-17 Jakub Jelinek + + * gcc.dg/gomp/reduction-2.c: New test. + 2018-10-16 Jakub Jelinek * c-c++-common/gomp/clauses-1.c (r2): New variable. diff --git a/gcc/testsuite/gcc.dg/gomp/reduction-2.c b/gcc/testsuite/gcc.dg/gomp/reduction-2.c new file mode 100644 index 000000000000..f8ac8b6bbfec --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/reduction-2.c @@ -0,0 +1,30 @@ +/* { 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); + } +}