diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-15 11:22:33 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-15 11:22:33 +0000 |
commit | c7b90083fc30ca513362af4146f2d74593e361b9 (patch) | |
tree | 2edd507fa9d839c9250de47fd7cb5ef53820ab03 /gcc/cp | |
parent | 71630517b50379f514fc7aa3e478adf7a800e153 (diff) | |
download | gcc-c7b90083fc30ca513362af4146f2d74593e361b9.tar.gz |
2016-04-15 Basile Starynkevitch <basile@starynkevitch.net>
{{merging with even more of GCC 6, using subversion 1.9
svn merge -r229783:229820 ^/trunk
}}
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@235016 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 116 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 328 | ||||
-rw-r--r-- | gcc/cp/pt.c | 76 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 344 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 8 |
7 files changed, 661 insertions, 220 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86c3653aff6..57de3e6b639 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,119 @@ +2015-11-05 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/67846 + * parser.c (cp_parser_lambda_body): Check lambda_return_type + return value. + * typeck2.c (cxx_incomplete_type_diagnostic): Print member or + member function used invalidly. + +2015-11-05 Jakub Jelinek <jakub@redhat.com> + Ilya Verbin <ilya.verbin@intel.com> + + * cp-tree.h (finish_omp_for): Add ORIG_INITS argument. + (omp_privatize_field): Add SHARED argument. + * parser.c: Include context.h. + (cp_parser_omp_clause_schedule): Parse schedule + modifiers, diagnose monotonic together with nonmonotonic. + (cp_parser_omp_clause_linear): Add DECLARE_SIMD argument. Parse + parameter name as linear step as id-expression rather than expression. + (cp_parser_omp_all_clauses): Adjust caller. + (cp_parser_omp_for_loop_init): Add ORIG_INIT argument, + initialize it. Adjust omp_privatize_field caller. + (cp_parser_omp_for_loop): Compute orig_inits, pass it's address + to finish_omp_for. + (OMP_DISTRIBUTE_CLAUSE_MASK): Add lastprivate clause. + (cp_parser_omp_target_data, + cp_parser_omp_target_enter_data, + cp_parser_omp_target_exit_data): Allow GOMP_MAP_ALWAYS_POINTER + and GOMP_MAP_FIRSTPRIVATE_REFERENCE. + (cp_parser_omp_target): Likewise. Evaluate num_teams and + thread_limit expressions on combined target teams before the target. + (cp_parser_omp_declare_target): If decl has "omp declare target" or + "omp declare target link" attribute, and cgraph or varpool node already + exists, then set corresponding flags. Call finish_omp_clauses + in the parenthesized extended-list syntax case. Call + cp_parser_require_pragma_eol instead of cp_parser_skip_to_pragma_eol. + (cp_parser_omp_end_declare_target): Call cp_parser_require_pragma_eol + instead of cp_parser_skip_to_pragma_eol. + * decl2.c (cplus_decl_attributes): Don't diagnose block scope vars + inside declare target. + * pt.c (tsubst_omp_clauses): If OMP_CLAUSE_LINEAR_VARIABLE_STRIDE, + use tsubst_omp_clause_decl instead of tsubst_expr on + OMP_CLAUSE_LINEAR_STEP. Handle non-static data members in shared + clauses. + (tsubst_omp_for_iterator): Adjust omp_privatize_field caller. + (tsubst_find_omp_teams): New function. + (tsubst_expr): Evaluate num_teams and thread_limit expressions on + combined target teams before the target. Use OMP_FOR_ORIG_DECLS for + all OpenMP/OpenACC/Cilk+ looping constructs. Adjust finish_omp_for + caller. + * semantics.c (omp_privatize_field): Add SHARED argument, if true, + always create artificial var and never put it into the hash table + or vector. + (handle_omp_array_sections_1): Adjust omp_privatize_field caller. + Allow non-zero low-bound on OMP_CLAUSE_REDUCTION array sections. + (handle_omp_array_sections): For structure element + based array sections use GOMP_MAP_ALWAYS_POINTER instead of + GOMP_MAP_FIRSTPRIVATE_POINTER. Encode low-bound into the MEM_REF, + either into the constant offset, or for variable low-bound using + POINTER_PLUS_EXPR. + (finish_omp_clauses): Adjust omp_privatize_field caller. Drop + generic_field_head, structure elements are now always mapped even + as array section bases, diagnose same var in data sharing and + mapping clauses. For references map what they refer to using + GOMP_MAP_ALWAYS_POINTER for structure elements and + GOMP_MAP_FIRSTPRIVATE_REFERENCE otherwise. Diagnose if linear step + on declare simd is neither a constant nor a uniform parameter. + Allow non-static data members on shared clauses. Look through + POINTER_PLUS_EXPR for array section reductions. Diagnose nonmonotonic + modifier on kinds other than dynamic or guided or nonmonotonic + modifier together with ordered clause. Diagnose the same var or + function appearing multiple times on the same directive. Fix up + wording for the to clause if t is neither a FUNCTION_DECL nor a + VAR_DECL, use special wording for OVERLOADs and TEMPLATE_ID_EXPR. + (handle_omp_for_class_iterator): Add ORIG_DECLS argument. Call + c_omp_check_loop_iv_exprs on cond. + (finish_omp_for): Add ORIG_INITS argument. Call + c_omp_check_loop_iv_exprs on ORIG_INITS elements. Adjust + handle_omp_for_class_iterator caller. Call c_omp_check_loop_iv. + Call add_stmt. + (finish_omp_atomic): Adjust c_finish_omp_atomic caller. + +2015-11-04 Cesar Philippidis <cesar@codesourcery.com> + + * (cp_parser_oacc_single_int_clause): New function. + (cp_parser_oacc_clause_vector_length): Delete. + (cp_parser_omp_clause_num_gangs): Delete. + (cp_parser_omp_clause_num_workers): Delete. + (cp_parser_oacc_all_clauses): Use cp_parser_oacc_single_int_clause + for num_gangs, num_workers and vector_length. + +2015-11-04 Mikhail Maltsev <maltsevm@gmail.com> + + * call.c (validate_conversion_obstack): Define unconditionally. + * constexpr.c (maybe_constant_value, fold_non_dependent_expr): Use + gcc_checking_assert. + * cp-tree.h: Use CHECKING_P instead of ENABLE_CHECKING. + * decl2.c (cxx_post_compilation_parsing_cleanups): Use flag_checking. + * mangle.c (add_substitution): Likewise. + * method.c (maybe_explain_implicit_delete): Likewise. + * parser.c (cp_parser_template_argument_list): Remove conditional + compilation. + * pt.c (check_unstripped_args): Rename to... + (verify_unstripped_args): ... this and remove conditional compilation. + (retrieve_specialization): Guard call of verify_unstripped_args with + flag_checking. + (template_parm_to_arg): Remove conditional compilation. + (template_parms_to_args, coerce_template_parameter_pack, + coerce_template_parms): Likewise. + (tsubst_copy): Use flag_checking. + (type_unification_real): Remove conditional compilation. + (build_non_dependent_expr): Use flag_checking. + * tree.c (build_target_expr): Remove conditional compilation, use + gcc_checking_assert. + * typeck.c (comptypes): Likewise. + * typeck2.c (digest_init_r): Likewise. + 2015-11-03 Jason Merrill <jason@redhat.com> * pt.c (struct find_parameter_pack_data): Add diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 17111884e2b..c578262677d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6327,7 +6327,7 @@ extern tree begin_omp_task (void); extern tree finish_omp_task (tree, tree); extern tree finish_omp_for (location_t, enum tree_code, tree, tree, tree, tree, tree, - tree, tree, tree); + tree, tree, vec<tree> *, tree); extern void finish_omp_atomic (enum tree_code, enum tree_code, tree, tree, tree, tree, tree, bool); @@ -6337,7 +6337,7 @@ extern void finish_omp_taskwait (void); extern void finish_omp_taskyield (void); extern void finish_omp_cancel (tree); extern void finish_omp_cancellation_point (tree); -extern tree omp_privatize_field (tree); +extern tree omp_privatize_field (tree, bool); extern tree begin_transaction_stmt (location_t, tree *, int); extern void finish_transaction_stmt (tree, tree, int, tree); extern tree build_transaction_expr (location_t, tree, int, tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 01d46070a80..846eca213bf 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1448,11 +1448,6 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) && DECL_CLASS_SCOPE_P (*decl)) error ("%q+D static data member inside of declare target directive", *decl); - else if (VAR_P (*decl) - && (DECL_FUNCTION_SCOPE_P (*decl) - || (current_function_decl && !DECL_EXTERNAL (*decl)))) - error ("%q+D in block scope inside of declare target directive", - *decl); else if (!processing_template_decl && VAR_P (*decl) && !cp_omp_mappable_type (TREE_TYPE (*decl))) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 313a8453c54..6eb68ebc42f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "omp-low.h" #include "gomp-constants.h" #include "c-family/c-indentation.h" +#include "context.h" /* The lexer. */ @@ -9886,7 +9887,12 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) if (cp_parser_parse_definitely (parser)) { if (!processing_template_decl) - apply_deduced_return_type (fco, lambda_return_type (expr)); + { + tree type = lambda_return_type (expr); + apply_deduced_return_type (fco, type); + if (type == error_mark_node) + expr = error_mark_node; + } /* Will get error here if type not deduced yet. */ finish_return_stmt (expr); @@ -29591,6 +29597,39 @@ cp_parser_oacc_simple_clause (cp_parser * /* parser */, return c; } + /* OpenACC: + num_gangs ( expression ) + num_workers ( expression ) + vector_length ( expression ) */ + +static tree +cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code, + const char *str, tree list) +{ + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + tree t = cp_parser_assignment_expression (parser, NULL, false, false); + + if (t == error_mark_node + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + { + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + + check_no_duplicate_clause (list, code, str, loc); + + tree c = build_omp_clause (loc, code); + OMP_CLAUSE_OPERAND (c, 0) = t; + OMP_CLAUSE_CHAIN (c) = list; + return c; +} + /* OpenACC: gang [( gang-arg-list )] @@ -29714,45 +29753,6 @@ cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind, return list; } -/* OpenACC: - vector_length ( expression ) */ - -static tree -cp_parser_oacc_clause_vector_length (cp_parser *parser, tree list) -{ - tree t, c; - location_t location = cp_lexer_peek_token (parser->lexer)->location; - bool error = false; - - if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - return list; - - t = cp_parser_condition (parser); - if (t == error_mark_node || !INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - error_at (location, "expected positive integer expression"); - error = true; - } - - if (error || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) - { - cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, - /*or_comma=*/false, - /*consume_paren=*/true); - return list; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_VECTOR_LENGTH, "vector_length", - location); - - c = build_omp_clause (location, OMP_CLAUSE_VECTOR_LENGTH); - OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; - - return list; -} - /* OpenACC 2.0 Parse wait clause or directive parameters. */ @@ -30131,42 +30131,6 @@ cp_parser_omp_clause_nowait (cp_parser * /*parser*/, return c; } -/* OpenACC: - num_gangs ( expression ) */ - -static tree -cp_parser_omp_clause_num_gangs (cp_parser *parser, tree list) -{ - tree t, c; - location_t location = cp_lexer_peek_token (parser->lexer)->location; - - if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - return list; - - t = cp_parser_condition (parser); - - if (t == error_mark_node - || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) - cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, - /*or_comma=*/false, - /*consume_paren=*/true); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - error_at (location, "expected positive integer expression"); - return list; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_NUM_GANGS, "num_gangs", location); - - c = build_omp_clause (location, OMP_CLAUSE_NUM_GANGS); - OMP_CLAUSE_NUM_GANGS_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; - - return list; -} - /* OpenMP 2.5: num_threads ( expression ) */ @@ -30375,43 +30339,6 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list, return list; } -/* OpenACC: - num_workers ( expression ) */ - -static tree -cp_parser_omp_clause_num_workers (cp_parser *parser, tree list) -{ - tree t, c; - location_t location = cp_lexer_peek_token (parser->lexer)->location; - - if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - return list; - - t = cp_parser_condition (parser); - - if (t == error_mark_node - || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) - cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, - /*or_comma=*/false, - /*consume_paren=*/true); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - error_at (location, "expected positive integer expression"); - return list; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_NUM_WORKERS, "num_gangs", - location); - - c = build_omp_clause (location, OMP_CLAUSE_NUM_WORKERS); - OMP_CLAUSE_NUM_WORKERS_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; - - return list; -} - /* OpenMP 2.5: ordered @@ -30578,31 +30505,44 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) OpenMP 4.5: schedule ( schedule-modifier : schedule-kind ) - schedule ( schedule-modifier : schedule-kind , expression ) + schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression ) schedule-modifier: - simd */ + simd + monotonic + nonmonotonic */ static tree cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location) { tree c, t; + int modifiers = 0, nmodifiers = 0; if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE); - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { tree id = cp_lexer_peek_token (parser->lexer)->u.value; const char *p = IDENTIFIER_POINTER (id); - if (strcmp ("simd", p) == 0 - && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)) + if (strcmp ("simd", p) == 0) + OMP_CLAUSE_SCHEDULE_SIMD (c) = 1; + else if (strcmp ("monotonic", p) == 0) + modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC; + else if (strcmp ("nonmonotonic", p) == 0) + modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC; + else + break; + cp_lexer_consume_token (parser->lexer); + if (nmodifiers++ == 0 + && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else { - OMP_CLAUSE_SCHEDULE_SIMD (c) = 1; - cp_lexer_consume_token (parser->lexer); - cp_lexer_consume_token (parser->lexer); + cp_parser_require (parser, CPP_COLON, RT_COLON); + break; } } @@ -30643,6 +30583,16 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location goto invalid_kind; cp_lexer_consume_token (parser->lexer); + if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC + | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) + == (OMP_CLAUSE_SCHEDULE_MONOTONIC + | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) + { + error_at (location, "both %<monotonic%> and %<nonmonotonic%> modifiers " + "specified"); + modifiers = 0; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) { cp_token *token; @@ -30668,6 +30618,10 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN)) goto resync_fail; + OMP_CLAUSE_SCHEDULE_KIND (c) + = (enum omp_clause_schedule_kind) + (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers); + check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location); OMP_CLAUSE_CHAIN (c) = list; return c; @@ -30860,7 +30814,7 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree list) static tree cp_parser_omp_clause_linear (cp_parser *parser, tree list, - bool is_cilk_simd_fn) + bool is_cilk_simd_fn, bool declare_simd) { tree nlist, c, step = integer_one_node; bool colon; @@ -30904,7 +30858,30 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list, if (colon) { - step = cp_parser_expression (parser); + step = NULL_TREE; + if (declare_simd + && cp_lexer_next_token_is (parser->lexer, CPP_NAME) + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + cp_parser_parse_tentatively (parser); + step = cp_parser_id_expression (parser, /*template_p=*/false, + /*check_dependency_p=*/true, + /*template_p=*/NULL, + /*declarator_p=*/false, + /*optional_p=*/false); + if (step != error_mark_node) + step = cp_parser_lookup_name_simple (parser, step, token->location); + if (step == error_mark_node) + { + step = NULL_TREE; + cp_parser_abort_tentative_parse (parser); + } + else if (!cp_parser_parse_definitely (parser)) + step = NULL_TREE; + } + if (!step) + step = cp_parser_expression (parser); if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL) { @@ -31423,6 +31400,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, { location_t here; pragma_omp_clause c_kind; + omp_clause_code code; const char *c_name; tree prev = clauses; @@ -31489,12 +31467,16 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, c_name = "if"; break; case PRAGMA_OACC_CLAUSE_NUM_GANGS: - clauses = cp_parser_omp_clause_num_gangs (parser, clauses); + code = OMP_CLAUSE_NUM_GANGS; c_name = "num_gangs"; + clauses = cp_parser_oacc_single_int_clause (parser, code, c_name, + clauses); break; case PRAGMA_OACC_CLAUSE_NUM_WORKERS: - clauses = cp_parser_omp_clause_num_workers (parser, clauses); c_name = "num_workers"; + code = OMP_CLAUSE_NUM_WORKERS; + clauses = cp_parser_oacc_single_int_clause (parser, code, c_name, + clauses); break; case PRAGMA_OACC_CLAUSE_PRESENT: clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses); @@ -31535,8 +31517,10 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, c_name, clauses); break; case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: - clauses = cp_parser_oacc_clause_vector_length (parser, clauses); c_name = "vector_length"; + code = OMP_CLAUSE_VECTOR_LENGTH; + clauses = cp_parser_oacc_single_int_clause (parser, code, c_name, + clauses); break; case PRAGMA_OACC_CLAUSE_WAIT: clauses = cp_parser_oacc_clause_wait (parser, clauses); @@ -31584,7 +31568,6 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, tree clauses = NULL; bool first = true; cp_token *token = NULL; - bool cilk_simd_fn = false; while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)) { @@ -31798,9 +31781,15 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, c_name = "aligned"; break; case PRAGMA_OMP_CLAUSE_LINEAR: - if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0) - cilk_simd_fn = true; - clauses = cp_parser_omp_clause_linear (parser, clauses, cilk_simd_fn); + { + bool cilk_simd_fn = false, declare_simd = false; + if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0) + cilk_simd_fn = true; + else if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0) + declare_simd = true; + clauses = cp_parser_omp_clause_linear (parser, clauses, + cilk_simd_fn, declare_simd); + } c_name = "linear"; break; case PRAGMA_OMP_CLAUSE_DEPEND: @@ -32583,6 +32572,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, tree &this_pre_body, vec<tree, va_gc> *for_block, tree &init, + tree &orig_init, tree &decl, tree &real_decl) { @@ -32680,6 +32670,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, cp_finish_decl (decl, init, !is_non_constant_init, asm_specification, LOOKUP_ONLYCONVERTING); + orig_init = init; if (CLASS_TYPE_P (TREE_TYPE (decl))) { vec_safe_push (for_block, this_pre_body); @@ -32740,7 +32731,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, decl = cp_parser_lookup_name_simple (parser, name, token->location); if (TREE_CODE (decl) == FIELD_DECL) - add_private_clause = omp_privatize_field (decl); + add_private_clause = omp_privatize_field (decl, false); } cp_parser_abort_tentative_parse (parser); cp_parser_parse_tentatively (parser); @@ -32757,6 +32748,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser, cp_parser_parse_definitely (parser); cp_parser_require (parser, CPP_EQ, RT_EQ); rhs = cp_parser_assignment_expression (parser); + orig_init = rhs; finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs), decl, NOP_EXPR, rhs, @@ -32786,13 +32778,14 @@ static tree cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, tree *cclauses) { - tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret; + tree init, orig_init, cond, incr, body, decl, pre_body = NULL_TREE, ret; tree real_decl, initv, condv, incrv, declv; tree this_pre_body, cl, ordered_cl = NULL_TREE; location_t loc_first; bool collapse_err = false; int i, collapse = 1, ordered = 0, count, nbraces = 0; vec<tree, va_gc> *for_block = make_tree_vector (); + auto_vec<tree, 4> orig_inits; for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) @@ -32859,13 +32852,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return NULL; - init = decl = real_decl = NULL; + init = orig_init = decl = real_decl = NULL; this_pre_body = push_stmt_list (); add_private_clause = cp_parser_omp_for_loop_init (parser, code, this_pre_body, for_block, - init, decl, real_decl); + init, orig_init, decl, real_decl); cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); if (this_pre_body) @@ -32997,6 +32990,11 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, TREE_VEC_ELT (initv, i) = init; TREE_VEC_ELT (condv, i) = cond; TREE_VEC_ELT (incrv, i) = incr; + if (orig_init) + { + orig_inits.safe_grow_cleared (i + 1); + orig_inits[i] = orig_init; + } if (i == count - 1) break; @@ -33054,7 +33052,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, ret = NULL_TREE; else ret = finish_omp_for (loc_first, code, declv, NULL, initv, condv, incrv, - body, pre_body, clauses); + body, pre_body, &orig_inits, clauses); while (nbraces) { @@ -33699,6 +33697,7 @@ cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok) #define OMP_DISTRIBUTE_CLAUSE_MASK \ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) @@ -33894,6 +33893,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok) map_seen = 3; break; case GOMP_MAP_FIRSTPRIVATE_POINTER: + case GOMP_MAP_FIRSTPRIVATE_REFERENCE: + case GOMP_MAP_ALWAYS_POINTER: break; default: map_seen |= 1; @@ -33985,6 +33986,8 @@ cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok, map_seen = 3; break; case GOMP_MAP_FIRSTPRIVATE_POINTER: + case GOMP_MAP_FIRSTPRIVATE_REFERENCE: + case GOMP_MAP_ALWAYS_POINTER: break; default: map_seen |= 1; @@ -34072,6 +34075,8 @@ cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok, map_seen = 3; break; case GOMP_MAP_FIRSTPRIVATE_POINTER: + case GOMP_MAP_FIRSTPRIVATE_REFERENCE: + case GOMP_MAP_ALWAYS_POINTER: break; default: map_seen |= 1; @@ -34242,6 +34247,33 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok, tree body = finish_omp_structured_block (sb); if (ret == NULL_TREE) return false; + if (ccode == OMP_TEAMS && !processing_template_decl) + { + /* For combined target teams, ensure the num_teams and + thread_limit clause expressions are evaluated on the host, + before entering the target construct. */ + tree c; + for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; + c; c = OMP_CLAUSE_CHAIN (c)) + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) + && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST) + { + tree expr = OMP_CLAUSE_OPERAND (c, 0); + expr = force_target_expr (TREE_TYPE (expr), expr, tf_none); + if (expr == error_mark_node) + continue; + tree tmp = TARGET_EXPR_SLOT (expr); + add_stmt (expr); + OMP_CLAUSE_OPERAND (c, 0) = expr; + tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (tc) = tmp; + OMP_CLAUSE_CHAIN (tc) + = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; + cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc; + } + } tree stmt = make_node (OMP_TARGET); TREE_TYPE (stmt) = void_type_node; OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; @@ -34308,6 +34340,8 @@ check_clauses: case GOMP_MAP_ALWAYS_TOFROM: case GOMP_MAP_ALLOC: case GOMP_MAP_FIRSTPRIVATE_POINTER: + case GOMP_MAP_FIRSTPRIVATE_REFERENCE: + case GOMP_MAP_ALWAYS_POINTER: break; default: error_at (OMP_CLAUSE_LOCATION (*pc), @@ -34839,11 +34873,12 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok) { clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE, clauses); - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + clauses = finish_omp_clauses (clauses, true); + cp_parser_require_pragma_eol (parser, pragma_tok); } else { - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + cp_parser_require_pragma_eol (parser, pragma_tok); scope_chain->omp_declare_target_attribute++; return; } @@ -34873,7 +34908,22 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok) continue; } if (!at1) - DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + { + symtab_node *node = symtab_node::get (t); + DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + if (node != NULL) + { + node->offloadable = 1; +#ifdef ENABLE_OFFLOADING + g->have_offload = true; + if (is_a <varpool_node *> (node)) + { + vec_safe_push (offload_vars, t); + node->force_output = 1; + } +#endif + } + } } } @@ -34910,7 +34960,7 @@ cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok) cp_parser_skip_to_pragma_eol (parser, pragma_tok); return; } - cp_parser_skip_to_pragma_eol (parser, pragma_tok); + cp_parser_require_pragma_eol (parser, pragma_tok); if (!scope_chain->omp_declare_target_attribute) error_at (pragma_tok->location, "%<#pragma omp end declare target%> without corresponding " diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bc1ba2f38d8..554e081762e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14425,7 +14425,6 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields, = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, in_decl); break; - case OMP_CLAUSE_LINEAR: case OMP_CLAUSE_ALIGNED: OMP_CLAUSE_DECL (nc) = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, @@ -14433,12 +14432,25 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields, OMP_CLAUSE_OPERAND (nc, 1) = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl, /*integral_constant_expression_p=*/false); - if (OMP_CLAUSE_CODE (oc) == OMP_CLAUSE_LINEAR - && OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE) + break; + case OMP_CLAUSE_LINEAR: + OMP_CLAUSE_DECL (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, + in_decl); + if (OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE) { gcc_assert (!linear_no_step); linear_no_step = nc; } + else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (oc)) + OMP_CLAUSE_LINEAR_STEP (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_LINEAR_STEP (oc), args, + complain, in_decl); + else + OMP_CLAUSE_LINEAR_STEP (nc) + = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain, + in_decl, + /*integral_constant_expression_p=*/false); break; case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_DEFAULT: @@ -14462,6 +14474,7 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields, if (allow_fields) switch (OMP_CLAUSE_CODE (nc)) { + case OMP_CLAUSE_SHARED: case OMP_CLAUSE_PRIVATE: case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_LASTPRIVATE: @@ -14641,7 +14654,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv, && DECL_NAME (v) == this_identifier) { decl = TREE_OPERAND (decl, 1); - decl = omp_privatize_field (decl); + decl = omp_privatize_field (decl, false); } /* FALLTHRU */ default: @@ -14822,6 +14835,27 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv, #undef RECUR } +/* Helper function of tsubst_expr, find OMP_TEAMS inside + of OMP_TARGET's body. */ + +static tree +tsubst_find_omp_teams (tree *tp, int *walk_subtrees, void *) +{ + *walk_subtrees = 0; + switch (TREE_CODE (*tp)) + { + case OMP_TEAMS: + return *tp; + case BIND_EXPR: + case STATEMENT_LIST: + *walk_subtrees = 1; + break; + default: + break; + } + return NULL_TREE; +} + /* Like tsubst_copy for expressions, etc. but also does semantic processing. */ @@ -15246,7 +15280,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (OMP_FOR_INIT (t) != NULL_TREE) { declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); - if (TREE_CODE (t) == OMP_FOR && OMP_FOR_ORIG_DECLS (t)) + if (OMP_FOR_ORIG_DECLS (t)) orig_declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); @@ -15273,7 +15307,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (OMP_FOR_INIT (t) != NULL_TREE) t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv, orig_declv, initv, condv, incrv, body, pre_body, - clauses); + NULL, clauses); else { t = make_node (TREE_CODE (t)); @@ -15324,6 +15358,36 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, t = copy_node (t); OMP_BODY (t) = stmt; OMP_CLAUSES (t) = tmp; + if (TREE_CODE (t) == OMP_TARGET && OMP_TARGET_COMBINED (t)) + { + tree teams = cp_walk_tree (&stmt, tsubst_find_omp_teams, NULL, NULL); + if (teams) + { + /* For combined target teams, ensure the num_teams and + thread_limit clause expressions are evaluated on the host, + before entering the target construct. */ + tree c; + for (c = OMP_TEAMS_CLAUSES (teams); + c; c = OMP_CLAUSE_CHAIN (c)) + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) + && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST) + { + tree expr = OMP_CLAUSE_OPERAND (c, 0); + expr = force_target_expr (TREE_TYPE (expr), expr, tf_none); + if (expr == error_mark_node) + continue; + tmp = TARGET_EXPR_SLOT (expr); + add_stmt (expr); + OMP_CLAUSE_OPERAND (c, 0) = expr; + tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (tc) = tmp; + OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t); + OMP_TARGET_CLAUSES (t) = tc; + } + } + } add_stmt (t); break; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b9f8545a7bc..d9f4fc525ca 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4323,19 +4323,20 @@ omp_note_field_privatization (tree f, tree t) dummy VAR_DECL. */ tree -omp_privatize_field (tree t) +omp_privatize_field (tree t, bool shared) { tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE); if (m == error_mark_node) return error_mark_node; - if (!omp_private_member_map) + if (!omp_private_member_map && !shared) omp_private_member_map = new hash_map<tree, tree>; if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) { gcc_assert (TREE_CODE (m) == INDIRECT_REF); m = TREE_OPERAND (m, 0); } - tree &v = omp_private_member_map->get_or_insert (t); + tree vb = NULL_TREE; + tree &v = shared ? vb : omp_private_member_map->get_or_insert (t); if (v == NULL_TREE) { v = create_temporary_var (TREE_TYPE (m)); @@ -4344,7 +4345,8 @@ omp_privatize_field (tree t) DECL_OMP_PRIVATIZED_MEMBER (v) = 1; SET_DECL_VALUE_EXPR (v, m); DECL_HAS_VALUE_EXPR_P (v) = 1; - omp_private_member_vec.safe_push (t); + if (!shared) + omp_private_member_vec.safe_push (t); } return v; } @@ -4447,7 +4449,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION && TREE_CODE (TREE_CHAIN (t)) == FIELD_DECL) - TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t)); + TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t), false); ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types, maybe_zero_len, first_non_one, is_omp); if (ret == error_mark_node || ret == NULL_TREE) @@ -4516,13 +4518,6 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, && (TREE_CODE (length) != INTEGER_CST || integer_onep (length))) first_non_one++; } - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION - && !integer_zerop (low_bound)) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%<reduction%> array section has to be zero-based"); - return error_mark_node; - } if (TREE_CODE (type) == ARRAY_TYPE) { if (length == NULL_TREE @@ -4863,7 +4858,24 @@ handle_omp_array_sections (tree c, bool is_omp) t = convert_from_reference (t); else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) t = build_fold_addr_expr (t); - t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0)); + tree t2 = build_fold_addr_expr (first); + t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c), + ptrdiff_type_node, t2); + t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR, + ptrdiff_type_node, t2, + fold_convert_loc (OMP_CLAUSE_LOCATION (c), + ptrdiff_type_node, t)); + if (tree_fits_shwi_p (t2)) + t = build2 (MEM_REF, type, t, + build_int_cst (ptype, tree_to_shwi (t2))); + else + { + t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c), + sizetype, t2); + t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR, + TREE_TYPE (t), t, t2); + t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0)); + } OMP_CLAUSE_DECL (c) = t; return false; } @@ -4892,9 +4904,20 @@ handle_omp_array_sections (tree c, bool is_omp) } tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (c2, is_omp ? GOMP_MAP_FIRSTPRIVATE_POINTER - : GOMP_MAP_POINTER); - if (!is_omp && !cxx_mark_addressable (t)) + if (!is_omp) + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER); + else if (TREE_CODE (t) == COMPONENT_REF) + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER); + else if (REFERENCE_REF_P (t) + && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF) + { + t = TREE_OPERAND (t, 0); + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER); + } + else + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); + if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER + && !cxx_mark_addressable (t)) return false; OMP_CLAUSE_DECL (c2) = t; t = build_fold_addr_expr (first); @@ -4912,15 +4935,18 @@ handle_omp_array_sections (tree c, bool is_omp) OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c); OMP_CLAUSE_CHAIN (c) = c2; ptr = OMP_CLAUSE_DECL (c2); - if (!is_omp + if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER && TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (ptr)))) { tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER); + OMP_CLAUSE_SET_MAP_KIND (c3, OMP_CLAUSE_MAP_KIND (c2)); OMP_CLAUSE_DECL (c3) = ptr; - OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr); + if (OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ALWAYS_POINTER) + OMP_CLAUSE_DECL (c2) = build_simple_mem_ref (ptr); + else + OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr); OMP_CLAUSE_SIZE (c3) = size_zero_node; OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2); OMP_CLAUSE_CHAIN (c2) = c3; @@ -5645,11 +5671,12 @@ tree finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) { bitmap_head generic_head, firstprivate_head, lastprivate_head; - bitmap_head aligned_head, map_head, map_field_head, generic_field_head; + bitmap_head aligned_head, map_head, map_field_head; tree c, t, *pc; tree safelen = NULL_TREE; bool branch_seen = false; bool copyprivate_seen = false; + bool ordered_seen = false; bitmap_obstack_initialize (NULL); bitmap_initialize (&generic_head, &bitmap_default_obstack); @@ -5658,7 +5685,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) bitmap_initialize (&aligned_head, &bitmap_default_obstack); bitmap_initialize (&map_head, &bitmap_default_obstack); bitmap_initialize (&map_field_head, &bitmap_default_obstack); - bitmap_initialize (&generic_field_head, &bitmap_default_obstack); for (pc = &clauses, c = clauses; c ; c = *pc) { @@ -5668,6 +5694,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) switch (OMP_CLAUSE_CODE (c)) { case OMP_CLAUSE_SHARED: + field_ok = allow_fields; goto check_dup_generic; case OMP_CLAUSE_PRIVATE: field_ok = allow_fields; @@ -5691,6 +5718,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) { gcc_assert (TREE_CODE (t) == MEM_REF); t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == POINTER_PLUS_EXPR) + t = TREE_OPERAND (t, 0); if (TREE_CODE (t) == ADDR_EXPR || TREE_CODE (t) == INDIRECT_REF) t = TREE_OPERAND (t, 0); @@ -5753,7 +5782,11 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) break; } else if (!type_dependent_expression_p (t) - && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + && !INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (!declare_simd + || TREE_CODE (t) != PARM_DECL + || TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE + || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t))))) { error ("linear step expression must be integral"); remove = true; @@ -5762,12 +5795,27 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) else { t = mark_rvalue_use (t); + if (declare_simd && TREE_CODE (t) == PARM_DECL) + { + OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1; + goto check_dup_generic; + } if (!processing_template_decl && (VAR_P (OMP_CLAUSE_DECL (c)) || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)) { - if (TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL) - t = maybe_constant_value (t); + if (declare_simd) + { + t = maybe_constant_value (t); + if (TREE_CODE (t) != INTEGER_CST) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<linear%> clause step %qE is neither " + "constant nor a parameter", t); + remove = true; + break; + } + } t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); tree type = TREE_TYPE (OMP_CLAUSE_DECL (c)); if (TREE_CODE (type) == REFERENCE_TYPE) @@ -5821,7 +5869,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); if (t) { - if (!remove) + if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED) omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); } else @@ -5857,6 +5905,12 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) error ("%qD appears more than once in data clauses", t); remove = true; } + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE + && bitmap_bit_p (&map_head, DECL_UID (t))) + { + error ("%qD appears both in data and map clauses", t); + remove = true; + } else bitmap_set_bit (&generic_head, DECL_UID (t)); if (!field_ok) @@ -5866,7 +5920,9 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) && TREE_CODE (t) == FIELD_DECL && t == OMP_CLAUSE_DECL (c)) { - OMP_CLAUSE_DECL (c) = omp_privatize_field (t); + OMP_CLAUSE_DECL (c) + = omp_privatize_field (t, (OMP_CLAUSE_CODE (c) + == OMP_CLAUSE_SHARED)); if (OMP_CLAUSE_DECL (c) == error_mark_node) remove = true; } @@ -5902,6 +5958,11 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) error ("%qD appears more than once in data clauses", t); remove = true; } + else if (bitmap_bit_p (&map_head, DECL_UID (t))) + { + error ("%qD appears both in data and map clauses", t); + remove = true; + } else bitmap_set_bit (&firstprivate_head, DECL_UID (t)); goto handle_field_decl; @@ -6072,6 +6133,30 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) break; case OMP_CLAUSE_SCHEDULE: + if (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_NONMONOTONIC) + { + const char *p = NULL; + switch (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK) + { + case OMP_CLAUSE_SCHEDULE_STATIC: p = "static"; break; + case OMP_CLAUSE_SCHEDULE_DYNAMIC: break; + case OMP_CLAUSE_SCHEDULE_GUIDED: break; + case OMP_CLAUSE_SCHEDULE_AUTO: p = "auto"; break; + case OMP_CLAUSE_SCHEDULE_RUNTIME: p = "runtime"; break; + default: gcc_unreachable (); + } + if (p) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<nonmonotonic%> modifier specified for %qs " + "schedule kind", p); + OMP_CLAUSE_SCHEDULE_KIND (c) + = (enum omp_clause_schedule_kind) + (OMP_CLAUSE_SCHEDULE_KIND (c) + & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC); + } + } + t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c); if (t == NULL) ; @@ -6406,7 +6491,10 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) } if (REFERENCE_REF_P (t) && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF) - t = TREE_OPERAND (t, 0); + { + t = TREE_OPERAND (t, 0); + OMP_CLAUSE_DECL (c) = t; + } if (TREE_CODE (t) == COMPONENT_REF && allow_fields && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_) @@ -6443,15 +6531,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) break; if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) { - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP - && (OMP_CLAUSE_MAP_KIND (c) - == GOMP_MAP_FIRSTPRIVATE_POINTER)) - { - if (bitmap_bit_p (&generic_field_head, DECL_UID (t))) - break; - } - else if (bitmap_bit_p (&map_field_head, DECL_UID (t))) - break; + if (bitmap_bit_p (&map_field_head, DECL_UID (t))) + goto handle_map_references; } } if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) @@ -6459,7 +6540,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) if (processing_template_decl) break; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP - && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER) + && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER + || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)) break; if (DECL_P (t)) error ("%qD is not a variable in %qs clause", t, @@ -6511,17 +6593,13 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) error ("%qD appears more than once in data clauses", t); remove = true; } - else + else if (bitmap_bit_p (&map_head, DECL_UID (t))) { - bitmap_set_bit (&generic_head, DECL_UID (t)); - if (t != OMP_CLAUSE_DECL (c) - && (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF - || (REFERENCE_REF_P (OMP_CLAUSE_DECL (c)) - && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), - 0)) - == COMPONENT_REF)))) - bitmap_set_bit (&generic_field_head, DECL_UID (t)); + error ("%qD appears both in data and map clauses", t); + remove = true; } + else + bitmap_set_bit (&generic_head, DECL_UID (t)); } else if (bitmap_bit_p (&map_head, DECL_UID (t))) { @@ -6531,6 +6609,12 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) error ("%qD appears more than once in map clauses", t); remove = true; } + else if (bitmap_bit_p (&generic_head, DECL_UID (t)) + || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) + { + error ("%qD appears both in data and map clauses", t); + remove = true; + } else { bitmap_set_bit (&map_head, DECL_UID (t)); @@ -6538,20 +6622,75 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) && TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF) bitmap_set_bit (&map_field_head, DECL_UID (t)); } + handle_map_references: + if (!remove + && !processing_template_decl + && allow_fields + && TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) == REFERENCE_TYPE) + { + t = OMP_CLAUSE_DECL (c); + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) + { + OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t); + if (OMP_CLAUSE_SIZE (c) == NULL_TREE) + OMP_CLAUSE_SIZE (c) + = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))); + } + else if (OMP_CLAUSE_MAP_KIND (c) + != GOMP_MAP_FIRSTPRIVATE_POINTER + && (OMP_CLAUSE_MAP_KIND (c) + != GOMP_MAP_FIRSTPRIVATE_REFERENCE) + && (OMP_CLAUSE_MAP_KIND (c) + != GOMP_MAP_ALWAYS_POINTER)) + { + tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_MAP); + if (TREE_CODE (t) == COMPONENT_REF) + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER); + else + OMP_CLAUSE_SET_MAP_KIND (c2, + GOMP_MAP_FIRSTPRIVATE_REFERENCE); + OMP_CLAUSE_DECL (c2) = t; + OMP_CLAUSE_SIZE (c2) = size_zero_node; + OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c); + OMP_CLAUSE_CHAIN (c) = c2; + OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t); + if (OMP_CLAUSE_SIZE (c) == NULL_TREE) + OMP_CLAUSE_SIZE (c) + = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))); + c = c2; + } + } break; case OMP_CLAUSE_TO_DECLARE: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == FUNCTION_DECL) - break; - /* FALLTHRU */ case OMP_CLAUSE_LINK: t = OMP_CLAUSE_DECL (c); - if (!VAR_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + ; + else if (!VAR_P (t)) { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %qs", t, - omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) + { + if (TREE_CODE (t) == OVERLOAD && OVL_CHAIN (t)) + error_at (OMP_CLAUSE_LOCATION (c), + "overloaded function name %qE in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else if (TREE_CODE (t) == TEMPLATE_ID_EXPR) + error_at (OMP_CLAUSE_LOCATION (c), + "template %qE in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is neither a variable nor a function name " + "in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + } + else + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %qs", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } else if (DECL_THREAD_LOCAL_P (t)) @@ -6568,6 +6707,17 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + if (remove) + break; + if (bitmap_bit_p (&generic_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once on the same " + "%<declare target%> directive", t); + remove = true; + } + else + bitmap_set_bit (&generic_head, DECL_UID (t)); break; case OMP_CLAUSE_UNIFORM: @@ -6583,6 +6733,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) remove = true; break; } + /* map_head bitmap is used as uniform_head if declare_simd. */ + bitmap_set_bit (&map_head, DECL_UID (t)); goto check_dup_generic; case OMP_CLAUSE_GRAINSIZE: @@ -6688,7 +6840,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) goto check_dup_generic; case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_DEFAULT: case OMP_CLAUSE_UNTIED: case OMP_CLAUSE_COLLAPSE: @@ -6707,6 +6858,10 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) case OMP_CLAUSE_SEQ: break; + case OMP_CLAUSE_ORDERED: + ordered_seen = true; + break; + case OMP_CLAUSE_INBRANCH: case OMP_CLAUSE_NOTINBRANCH: if (branch_seen) @@ -6768,6 +6923,17 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) case OMP_CLAUSE_LINEAR: if (!declare_simd) need_implicitly_determined = true; + else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) + && !bitmap_bit_p (&map_head, + DECL_UID (OMP_CLAUSE_LINEAR_STEP (c)))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<linear%> clause step is a parameter %qD not " + "specified in %<uniform%> clause", + OMP_CLAUSE_LINEAR_STEP (c)); + *pc = OMP_CLAUSE_CHAIN (c); + continue; + } break; case OMP_CLAUSE_COPYPRIVATE: need_copy_assignment = true; @@ -6789,6 +6955,21 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) } pc = &OMP_CLAUSE_CHAIN (c); continue; + case OMP_CLAUSE_SCHEDULE: + if (ordered_seen + && (OMP_CLAUSE_SCHEDULE_KIND (c) + & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<nonmonotonic%> schedule modifier specified " + "together with %<ordered%> clause"); + OMP_CLAUSE_SCHEDULE_KIND (c) + = (enum omp_clause_schedule_kind) + (OMP_CLAUSE_SCHEDULE_KIND (c) + & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC); + } + pc = &OMP_CLAUSE_CHAIN (c); + continue; case OMP_CLAUSE_NOWAIT: if (copyprivate_seen) { @@ -6906,6 +7087,15 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) need_dtor)) remove = true; + if (!remove + && c_kind == OMP_CLAUSE_SHARED + && processing_template_decl) + { + t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); + if (t) + OMP_CLAUSE_DECL (c) = t; + } + if (remove) *pc = OMP_CLAUSE_CHAIN (c); else @@ -7202,9 +7392,10 @@ finish_omp_task (tree clauses, tree body) static bool handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, - tree declv, tree initv, tree condv, tree incrv, - tree *body, tree *pre_body, tree &clauses, - tree *lastp, int collapse, int ordered) + tree declv, tree orig_declv, tree initv, + tree condv, tree incrv, tree *body, + tree *pre_body, tree &clauses, tree *lastp, + int collapse, int ordered) { tree diff, iter_init, iter_incr = NULL, last; tree incr_var = NULL, orig_pre_body, orig_body, c; @@ -7261,6 +7452,10 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, TREE_OPERAND (cond, 1), iter); return true; } + if (!c_omp_check_loop_iv_exprs (locus, orig_declv, + TREE_VEC_ELT (declv, i), NULL_TREE, + cond, cp_walk_subtrees)) + return true; switch (TREE_CODE (incr)) { @@ -7516,7 +7711,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, tree finish_omp_for (location_t locus, enum tree_code code, tree declv, tree orig_declv, tree initv, tree condv, tree incrv, - tree body, tree pre_body, tree clauses) + tree body, tree pre_body, vec<tree> *orig_inits, tree clauses) { tree omp_for = NULL, orig_incr = NULL; tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE; @@ -7592,6 +7787,20 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, TREE_VEC_ELT (initv, i) = init; } + if (orig_inits) + { + bool fail = false; + tree orig_init; + FOR_EACH_VEC_ELT (*orig_inits, i, orig_init) + if (orig_init + && !c_omp_check_loop_iv_exprs (locus, declv, + TREE_VEC_ELT (declv, i), orig_init, + NULL_TREE, cp_walk_subtrees)) + fail = true; + if (fail) + return NULL; + } + if (dependent_omp_for_p (declv, initv, condv, incrv)) { tree stmt; @@ -7665,10 +7874,10 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, } if (code == CILK_FOR && i == 0) orig_decl = decl; - if (handle_omp_for_class_iterator (i, locus, code, declv, initv, - condv, incrv, &body, &pre_body, - clauses, &last, collapse, - ordered)) + if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv, + initv, condv, incrv, &body, + &pre_body, clauses, &last, + collapse, ordered)) return NULL; continue; } @@ -7727,6 +7936,10 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv, incrv, body, pre_body); + /* Check for iterators appearing in lb, b or incr expressions. */ + if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees)) + omp_for = NULL_TREE; + if (omp_for == NULL) { if (block) @@ -7734,6 +7947,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, return NULL; } + add_stmt (omp_for); + for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++) { decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0); @@ -8013,7 +8228,8 @@ finish_omp_atomic (enum tree_code code, enum tree_code opcode, tree lhs, return; } stmt = c_finish_omp_atomic (input_location, code, opcode, lhs, rhs, - v, lhs1, rhs1, swapped, seq_cst); + v, lhs1, rhs1, swapped, seq_cst, + processing_template_decl != 0); if (stmt == error_mark_node) return; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index bdd8946890d..086724c6408 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -516,12 +516,12 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, if (DECL_FUNCTION_MEMBER_P (member) && ! flag_ms_extensions) emit_diagnostic (diag_kind, input_location, 0, - "invalid use of member function " - "(did you forget the %<()%> ?)"); + "invalid use of member function %qD " + "(did you forget the %<()%> ?)", member); else emit_diagnostic (diag_kind, input_location, 0, - "invalid use of member " - "(did you forget the %<&%> ?)"); + "invalid use of member %qD " + "(did you forget the %<&%> ?)", member); } break; |