From 757ba6653c2699761c2243e0194749a6695112d8 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 23 Oct 2020 12:37:38 -0600 Subject: PR middle-end/97552 - missing waning passing null to a VLA argument declared [static] gcc/ChangeLog: PR middle-end/97552 * attribs.c (init_attr_rdwr_indices): Handle static VLA parameters. gcc/c/ChangeLog: PR middle-end/97552 * c-decl.c (get_parm_array_spec): Handle static VLA parameters. gcc/testsuite/ChangeLog: PR middle-end/97552 * gcc.dg/Wvla-parameter-2.c: Adjust text of expected warning. * gcc.dg/Wnonnull-5.c: New test. --- gcc/c/c-decl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 81b9adb..1673b95 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5784,6 +5784,9 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) continue; } + if (pd->u.array.static_p) + spec += 's'; + if (TREE_CODE (nelts) == INTEGER_CST) { /* Skip all constant bounds except the most significant one. @@ -5796,9 +5799,8 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) return attrs; char buf[40]; - const char *code = pd->u.array.static_p ? "s" : ""; unsigned HOST_WIDE_INT n = tree_to_uhwi (nelts); - sprintf (buf, "%s%llu", code, (unsigned long long)n); + sprintf (buf, "%llu", (unsigned long long)n); spec += buf; break; } -- cgit v1.1 From 83f83ddfe0fe41c9b553850d4ababd5089df8332 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 11 Sep 2020 16:19:08 -0400 Subject: c, c++: Implement -Wsizeof-array-div [PR91741] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements a new warning, -Wsizeof-array-div. It warns about code like int arr[10]; sizeof (arr) / sizeof (short); where we have a division of two sizeof expressions, where the first argument is an array, and the second sizeof does not equal the size of the array element. See e.g. . Clang makes it possible to suppress the warning by parenthesizing the second sizeof like this: sizeof (arr) / (sizeof (short)); so I followed suit. In the C++ FE this was rather easy, because finish_parenthesized_expr already set TREE_NO_WARNING. In the C FE I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the non-() and () versions. This warning is enabled by -Wall. An example of the output: x.c:5:23: warning: expression does not compute the number of elements in this array; element type is ‘int’, not ‘short int’ [-Wsizeof-array-div] 5 | return sizeof (arr) / sizeof (short); | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence this warning 5 | return sizeof (arr) / sizeof (short); | ^~~~~~~~~~~~~~ | ( ) x.c:4:7: note: array ‘arr’ declared here 4 | int arr[10]; | ^~~ gcc/c-family/ChangeLog: PR c++/91741 * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR. (c_common_init_ts): Likewise. * c-common.def (PAREN_SIZEOF_EXPR): New tree code. * c-common.h (maybe_warn_sizeof_array_div): Declare. * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs. (maybe_warn_sizeof_array_div): New function. * c.opt (Wsizeof-array-div): New option. gcc/c/ChangeLog: PR c++/91741 * c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div. (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR. (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR. * c-tree.h (char_type_p): Declare. * c-typeck.c (char_type_p): No longer static. gcc/cp/ChangeLog: PR c++/91741 * typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div. gcc/ChangeLog: PR c++/91741 * doc/invoke.texi: Document -Wsizeof-array-div. gcc/testsuite/ChangeLog: PR c++/91741 * c-c++-common/Wsizeof-pointer-div.c: Add dg-warning. * c-c++-common/Wsizeof-array-div1.c: New test. * g++.dg/warn/Wsizeof-array-div1.C: New test. * g++.dg/warn/Wsizeof-array-div2.C: New test. --- gcc/c/c-parser.c | 48 ++++++++++++++++++++++++++++++------------------ gcc/c/c-tree.h | 1 + gcc/c/c-typeck.c | 2 +- 3 files changed, 32 insertions(+), 19 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7d58356..b6a7ef4 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7876,7 +7876,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, enum tree_code op; /* The source location of this operation. */ location_t loc; - /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */ + /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */ tree sizeof_arg; } stack[NUM_PRECS]; int sp; @@ -7894,9 +7894,11 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ == truthvalue_true_node); \ break; \ - case TRUNC_DIV_EXPR: \ - if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \ - && stack[sp].expr.original_code == SIZEOF_EXPR) \ + case TRUNC_DIV_EXPR: \ + if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \ + || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \ + && (stack[sp].expr.original_code == SIZEOF_EXPR \ + || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \ { \ tree type0 = stack[sp - 1].sizeof_arg; \ tree type1 = stack[sp].sizeof_arg; \ @@ -7910,18 +7912,23 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, && !(TREE_CODE (first_arg) == PARM_DECL \ && C_ARRAY_PARAMETER (first_arg) \ && warn_sizeof_array_argument)) \ - { \ - auto_diagnostic_group d; \ - if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ - "division % " \ - "does not compute the number of array " \ - "elements", \ - type0, type1)) \ - if (DECL_P (first_arg)) \ - inform (DECL_SOURCE_LOCATION (first_arg), \ - "first % operand was declared here"); \ - } \ - } \ + { \ + auto_diagnostic_group d; \ + if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ + "division % " \ + "does not compute the number of array " \ + "elements", \ + type0, type1)) \ + if (DECL_P (first_arg)) \ + inform (DECL_SOURCE_LOCATION (first_arg), \ + "first % operand was declared here"); \ + } \ + else if (TREE_CODE (type0) == ARRAY_TYPE \ + && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \ + && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \ + maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \ + stack[sp].sizeof_arg, type1); \ + } \ break; \ default: \ break; \ @@ -9177,6 +9184,9 @@ c_parser_postfix_expression (c_parser *parser) if (expr.original_code != C_MAYBE_CONST_EXPR && expr.original_code != SIZEOF_EXPR) expr.original_code = ERROR_MARK; + /* Remember that we saw ( ) around the sizeof. */ + if (expr.original_code == SIZEOF_EXPR) + expr.original_code = PAREN_SIZEOF_EXPR; /* Don't change EXPR.ORIGINAL_TYPE. */ location_t loc_close_paren = c_parser_peek_token (parser)->location; set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); @@ -10792,7 +10802,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, if (locations) locations->safe_push (expr.get_location ()); if (sizeof_arg != NULL - && expr.original_code == SIZEOF_EXPR) + && (expr.original_code == SIZEOF_EXPR + || expr.original_code == PAREN_SIZEOF_EXPR)) { sizeof_arg[0] = c_last_sizeof_arg; sizeof_arg_loc[0] = c_last_sizeof_loc; @@ -10815,7 +10826,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, locations->safe_push (expr.get_location ()); if (++idx < 3 && sizeof_arg != NULL - && expr.original_code == SIZEOF_EXPR) + && (expr.original_code == SIZEOF_EXPR + || expr.original_code == PAREN_SIZEOF_EXPR)) { sizeof_arg[idx] = c_last_sizeof_arg; sizeof_arg_loc[idx] = c_last_sizeof_loc; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 287b1df..1f783db 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -675,6 +675,7 @@ extern location_t c_last_sizeof_loc; extern struct c_switch *c_switch_stack; +extern bool char_type_p (tree); extern tree c_objc_common_truthvalue_conversion (location_t, tree); extern tree require_complete_type (location_t, tree); extern bool same_translation_unit_p (const_tree, const_tree); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index dd3e309..459090e 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3719,7 +3719,7 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg) /* Returns true if TYPE is a character type, *not* including wchar_t. */ -static bool +bool char_type_p (tree type) { return (type == char_type_node -- cgit v1.1 From efe71fcc4cb0e9989b2655e034c57cc73ae679a9 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 24 Oct 2020 00:16:29 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 839bfa1..8c6893b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,17 @@ +2020-10-23 Marek Polacek + + PR c++/91741 + * c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div. + (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR. + (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR. + * c-tree.h (char_type_p): Declare. + * c-typeck.c (char_type_p): No longer static. + +2020-10-23 Martin Sebor + + PR middle-end/97552 + * c-decl.c (get_parm_array_spec): Handle static VLA parameters. + 2020-09-19 Martin Sebor PR c/50584 -- cgit v1.1 From 75ce04fba49eb30b6a8fe23bc3605cf0ef9a8e28 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 27 Oct 2020 22:15:46 +0000 Subject: c: Allow duplicate C2x standard attributes N2557, accepted into C2x at the October WG14 meeting, removes the requirement that duplicates of standard attributes cannot appear within an attribute list (so allowing e.g. [[deprecated, deprecated]], where previously that was disallowed but [[deprecated]] [[deprecated]] was OK). Remove the code checking for this (standard attributes aren't in any released version of the C standard) and update tests accordingly. Bootstrapped with no regressions on x86_64-pc-linux-gnu. gcc/c/ 2020-10-27 Joseph Myers * c-parser.c (c_parser_std_attribute_specifier): Allow duplicate standard attributes. gcc/testsuite/ 2020-10-27 Joseph Myers * gcc.dg/c2x-attr-deprecated-4.c, gcc.dg/c2x-attr-fallthrough-4.c, gcc.dg/c2x-attr-maybe_unused-4.c: Allow duplicate attributes. --- gcc/c/c-parser.c | 54 ++---------------------------------------------------- 1 file changed, 2 insertions(+), 52 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index b6a7ef4..d49e508 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -4977,9 +4977,6 @@ c_parser_std_attribute (c_parser *parser, bool for_tm) static tree c_parser_std_attribute_specifier (c_parser *parser, bool for_tm) { - bool seen_deprecated = false; - bool seen_fallthrough = false; - bool seen_maybe_unused = false; location_t loc = c_parser_peek_token (parser)->location; if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) return NULL_TREE; @@ -5005,55 +5002,8 @@ c_parser_std_attribute_specifier (c_parser *parser, bool for_tm) tree attribute = c_parser_std_attribute (parser, for_tm); if (attribute != error_mark_node) { - bool duplicate = false; - tree name = get_attribute_name (attribute); - tree ns = get_attribute_namespace (attribute); - if (ns == NULL_TREE) - { - /* Some standard attributes may appear at most once in - each attribute list. Diagnose duplicates and remove - them from the list to avoid subsequent diagnostics - such as the more general one for multiple - "fallthrough" attributes in the same place (including - in separate attribute lists in the same attribute - specifier sequence, which is not a constraint - violation). */ - if (is_attribute_p ("deprecated", name)) - { - if (seen_deprecated) - { - error ("attribute % can appear at most " - "once in an attribute-list"); - duplicate = true; - } - seen_deprecated = true; - } - else if (is_attribute_p ("fallthrough", name)) - { - if (seen_fallthrough) - { - error ("attribute % can appear at most " - "once in an attribute-list"); - duplicate = true; - } - seen_fallthrough = true; - } - else if (is_attribute_p ("maybe_unused", name)) - { - if (seen_maybe_unused) - { - error ("attribute % can appear at most " - "once in an attribute-list"); - duplicate = true; - } - seen_maybe_unused = true; - } - } - if (!duplicate) - { - TREE_CHAIN (attribute) = attributes; - attributes = attribute; - } + TREE_CHAIN (attribute) = attributes; + attributes = attribute; } if (c_parser_next_token_is_not (parser, CPP_COMMA)) break; -- cgit v1.1 From 89bb01e7cbd82cdf318202d8185d765dcc338915 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 28 Oct 2020 00:16:38 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 8c6893b..727762b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2020-10-27 Joseph Myers + + * c-parser.c (c_parser_std_attribute_specifier): Allow duplicate + standard attributes. + 2020-10-23 Marek Polacek PR c++/91741 -- cgit v1.1 From 3a8b20947f2b1559a7d5dcb62918f91344908c62 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 28 Oct 2020 10:38:01 +0100 Subject: openmp: Parsing and some semantic analysis of OpenMP allocate clause This patch adds parsing of OpenMP allocate clause, but still ignores it during OpenMP lowering where we should for privatized variables with allocate clause use the corresponding allocators rather than allocating them on the stack. 2020-10-28 Jakub Jelinek gcc/ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_ALLOCATE. * tree.h (OMP_CLAUSE_ALLOCATE_ALLOCATOR, OMP_CLAUSE_ALLOCATE_COMBINED): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add allocate clause. (walk_tree_1): Handle OMP_CLAUSE_ALLOCATE. * tree-pretty-print.c (dump_omp_clause): Likewise. * gimplify.c (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses, gimplify_omp_for): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Likewise. * omp-low.c (scan_sharing_clauses): Likewise. gcc/c-family/ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * c-omp.c: Include bitmap.h. (c_omp_split_clauses): Handle OMP_CLAUSE_ALLOCATE. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Handle allocate. (c_parser_omp_clause_allocate): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ALLOCATE. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK, OMP_TASKGROUP_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK, OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK, OMP_TASKLOOP_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. gcc/cp/ * parser.c (cp_parser_omp_clause_name): Handle allocate. (cp_parser_omp_clause_allocate): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ALLOCATE. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK, OMP_TASKGROUP_CLAUSE_MASK, OMP_DISTRIBUTE_CLAUSE_MASK, OMP_TEAMS_CLAUSE_MASK, OMP_TARGET_CLAUSE_MASK, OMP_TASKLOOP_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ALLOCATE. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. * pt.c (tsubst_omp_clauses): Likewise. gcc/testsuite/ * c-c++-common/gomp/allocate-1.c: New test. * c-c++-common/gomp/allocate-2.c: New test. * c-c++-common/gomp/clauses-1.c (omp_allocator_handle_t): New typedef. (foo, bar, baz): Add allocate clauses where allowed. --- gcc/c/c-parser.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- gcc/c/c-typeck.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 2 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index d49e508..b921c4e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -12603,6 +12603,8 @@ c_parser_omp_clause_name (c_parser *parser) case 'a': if (!strcmp ("aligned", p)) result = PRAGMA_OMP_CLAUSE_ALIGNED; + else if (!strcmp ("allocate", p)) + result = PRAGMA_OMP_CLAUSE_ALLOCATE; else if (!strcmp ("async", p)) result = PRAGMA_OACC_CLAUSE_ASYNC; else if (!strcmp ("attach", p)) @@ -15112,6 +15114,62 @@ c_parser_omp_clause_aligned (c_parser *parser, tree list) return nl; } +/* OpenMP 5.0: + allocate ( variable-list ) + allocate ( expression : variable-list ) */ + +static tree +c_parser_omp_clause_allocate (c_parser *parser, tree list) +{ + location_t clause_loc = c_parser_peek_token (parser)->location; + tree nl, c; + tree allocator = NULL_TREE; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if ((c_parser_next_token_is_not (parser, CPP_NAME) + && c_parser_next_token_is_not (parser, CPP_KEYWORD)) + || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA + && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN)) + { + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + allocator = expr.value; + allocator = c_fully_fold (allocator, false, NULL); + tree orig_type + = expr.original_type ? expr.original_type : TREE_TYPE (allocator); + orig_type = TYPE_MAIN_VARIANT (orig_type); + if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator)) + || TREE_CODE (orig_type) != ENUMERAL_TYPE + || TYPE_NAME (orig_type) != get_identifier ("omp_allocator_handle_t")) + { + error_at (clause_loc, "% clause allocator expression " + "has type %qT rather than " + "%", + TREE_TYPE (allocator)); + allocator = NULL_TREE; + } + if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) + { + parens.skip_until_found_close (parser); + return list; + } + } + + nl = c_parser_omp_variable_list (parser, clause_loc, + OMP_CLAUSE_ALLOCATE, list); + + if (allocator) + for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator; + + parens.skip_until_found_close (parser); + return nl; +} + /* OpenMP 4.0: linear ( variable-list ) linear ( variable-list : expression ) @@ -16354,6 +16412,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, clauses = c_parser_omp_clause_aligned (parser, clauses); c_name = "aligned"; break; + case PRAGMA_OMP_CLAUSE_ALLOCATE: + clauses = c_parser_omp_clause_allocate (parser, clauses); + c_name = "allocate"; + break; case PRAGMA_OMP_CLAUSE_LINEAR: clauses = c_parser_omp_clause_linear (parser, clauses); c_name = "linear"; @@ -18534,6 +18596,7 @@ c_parser_omp_simd (location_t loc, c_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) static tree @@ -18825,6 +18888,7 @@ c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser) | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree @@ -18879,6 +18943,7 @@ c_parser_omp_sections (location_t loc, c_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND)) static tree @@ -19020,6 +19085,7 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree @@ -19054,6 +19120,7 @@ c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p) | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) static tree @@ -19124,7 +19191,8 @@ c_parser_omp_taskyield (c_parser *parser) */ #define OMP_TASKGROUP_CLAUSE_MASK \ - ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) static tree c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p) @@ -19225,6 +19293,7 @@ c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context) | (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_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) static tree @@ -19314,6 +19383,7 @@ c_parser_omp_distribute (location_t loc, c_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)) static tree @@ -19701,6 +19771,7 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)) @@ -21331,6 +21402,7 @@ c_finish_taskloop_clauses (tree clauses) | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 459090e..cc9a262 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13795,6 +13795,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* 1 if normal/task reduction has been seen, -1 if inscan reduction has been seen, -2 if mixed inscan/normal reduction diagnosed. */ int reduction_seen = 0; + bool allocate_seen = false; bitmap_obstack_initialize (NULL); bitmap_initialize (&generic_head, &bitmap_default_obstack); @@ -14344,6 +14345,29 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) bitmap_set_bit (&oacc_reduction_head, DECL_UID (t)); break; + case OMP_CLAUSE_ALLOCATE: + t = OMP_CLAUSE_DECL (c); + if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in % clause", t); + remove = true; + } + else if (bitmap_bit_p (&aligned_head, DECL_UID (t))) + { + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%qE appears more than once in % clauses", + t); + remove = true; + } + else + { + bitmap_set_bit (&aligned_head, DECL_UID (t)); + if (!OMP_CLAUSE_ALLOCATE_COMBINED (c)) + allocate_seen = true; + } + break; + case OMP_CLAUSE_DEPEND: t = OMP_CLAUSE_DECL (c); if (t == NULL_TREE) @@ -15041,10 +15065,27 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) reduction_seen = -2; } - if (linear_variable_step_check || reduction_seen == -2) + if (linear_variable_step_check || reduction_seen == -2 || allocate_seen) for (pc = &clauses, c = clauses; c ; c = *pc) { bool remove = false; + if (allocate_seen) + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_PRIVATE: + case OMP_CLAUSE_FIRSTPRIVATE: + case OMP_CLAUSE_LASTPRIVATE: + case OMP_CLAUSE_LINEAR: + case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + if (DECL_P (OMP_CLAUSE_DECL (c))) + bitmap_clear_bit (&aligned_head, + DECL_UID (OMP_CLAUSE_DECL (c))); + break; + default: + break; + } if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) && !bitmap_bit_p (&map_head, @@ -15065,6 +15106,25 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) pc = &OMP_CLAUSE_CHAIN (c); } + if (allocate_seen) + for (pc = &clauses, c = clauses; c ; c = *pc) + { + bool remove = false; + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE + && !OMP_CLAUSE_ALLOCATE_COMBINED (c) + && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c)))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qD specified in % clause but not in " + "an explicit privatization clause", OMP_CLAUSE_DECL (c)); + remove = true; + } + if (remove) + *pc = OMP_CLAUSE_CHAIN (c); + else + pc = &OMP_CLAUSE_CHAIN (c); + } + if (nogroup_seen && reduction_seen) { error_at (OMP_CLAUSE_LOCATION (*nogroup_seen), -- cgit v1.1 From a4223abb3deb24e8104bbfec6f0f21579c1889e3 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 28 Oct 2020 18:57:02 +0000 Subject: c: Allow omitted parameter names for C2x C2x allows parameter names to be omitted in function definitions, as in C++; add support for this feature. As with other features that only result in previously rejected code being accepted, this feature is now accepted as an extension for previous standard versions, with a pedwarn-if-pedantic that is disabled by -Wno-c11-c2x-compat. The logic for avoiding unused-parameter warnings for unnamed parameters is in code shared between C and C++, so no changes are needed there. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ 2020-10-28 Joseph Myers * c-decl.c (store_parm_decls_newstyle): Use pedwarn_c11 not error_at for omitted parameter name. gcc/testsuite/ 2020-10-28 Joseph Myers * gcc.dg/c11-parm-omit-1.c, gcc.dg/c11-parm-omit-2.c, gcc.dg/c11-parm-omit-3.c, gcc.dg/c11-parm-omit-4.c, gcc.dg/c2x-parm-omit-1.c, gcc.dg/c2x-parm-omit-2.c, gcc.dg/c2x-parm-omit-3.c, gcc.dg/c2x-parm-omit-4.c: New tests. * gcc.dg/noncompile/pr79758.c: Do not expect error for omitted parameter name. --- gcc/c/c-decl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 1673b95..a5d0b15 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -9630,7 +9630,9 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) warn_if_shadowing (decl); } else - error_at (DECL_SOURCE_LOCATION (decl), "parameter name omitted"); + pedwarn_c11 (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic, + "ISO C does not support omitting parameter names in " + "function definitions before C2X"); } /* Record the parameter list in the function declaration. */ -- cgit v1.1 From e93aae4a497c38b46df818a629c78149fe6af24b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 29 Oct 2020 00:16:50 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 727762b..89913b7 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,21 @@ +2020-10-28 Joseph Myers + + * c-decl.c (store_parm_decls_newstyle): Use pedwarn_c11 not + error_at for omitted parameter name. + +2020-10-28 Jakub Jelinek + + * c-parser.c (c_parser_omp_clause_name): Handle allocate. + (c_parser_omp_clause_allocate): New function. + (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ALLOCATE. + (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, + OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, + OMP_TASK_CLAUSE_MASK, OMP_TASKGROUP_CLAUSE_MASK, + OMP_DISTRIBUTE_CLAUSE_MASK, OMP_TEAMS_CLAUSE_MASK, + OMP_TARGET_CLAUSE_MASK, OMP_TASKLOOP_CLAUSE_MASK): Add + PRAGMA_OMP_CLAUSE_ALLOCATE. + * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_ALLOCATE. + 2020-10-27 Joseph Myers * c-parser.c (c_parser_std_attribute_specifier): Allow duplicate -- cgit v1.1 From 52215bb3ec6e1bbf44729574ab34ea478f3066b1 Mon Sep 17 00:00:00 2001 From: Asher Gordon Date: Thu, 29 Oct 2020 21:01:07 +0000 Subject: Replace free with XDELETE. gcc/c/ChangeLog: * c-typeck.c (free_all_tagged_tu_seen_up_to): Replace free with XDELETE. (finish_init): Likewise. (pop_init_level): Likewise. --- gcc/c/c-typeck.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index cc9a262..981cbe8 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -1407,7 +1407,7 @@ free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *tu_til) const struct tagged_tu_seen_cache *const tu1 = (const struct tagged_tu_seen_cache *) tu; tu = tu1->next; - free (CONST_CAST (struct tagged_tu_seen_cache *, tu1)); + XDELETE (CONST_CAST (struct tagged_tu_seen_cache *, tu1)); } tagged_tu_seen_base = tu_til; } @@ -8314,13 +8314,13 @@ finish_init (void) { struct constructor_stack *q = constructor_stack; constructor_stack = q->next; - free (q); + XDELETE (q); } gcc_assert (!constructor_range_stack); /* Pop back to the data of the outer initializer (if any). */ - free (spelling_base); + XDELETE (spelling_base); constructor_decl = p->decl; require_constant_value = p->require_constant_value; @@ -8333,7 +8333,7 @@ finish_init (void) spelling_size = p->spelling_size; constructor_top_level = p->top_level; initializer_stack = p->next; - free (p); + XDELETE (p); } /* Call here when we see the initializer is surrounded by braces. @@ -8864,7 +8864,7 @@ pop_init_level (location_t loc, int implicit, RESTORE_SPELLING_DEPTH (constructor_depth); constructor_stack = p->next; - free (p); + XDELETE (p); if (ret.value == NULL_TREE && constructor_stack == 0) ret.value = error_mark_node; -- cgit v1.1 From 4f0606fe4bbf1346f83dd4d0c9060c6b46672a7d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 30 Oct 2020 00:16:29 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 89913b7..ca844ca 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2020-10-29 Asher Gordon + + * c-typeck.c (free_all_tagged_tu_seen_up_to): Replace free + with XDELETE. + (finish_init): Likewise. + (pop_init_level): Likewise. + 2020-10-28 Joseph Myers * c-decl.c (store_parm_decls_newstyle): Use pedwarn_c11 not -- cgit v1.1 From c19e44ac8dbc9af07e5e671edfa03ab5b08649c5 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 4 Nov 2020 06:48:46 +0000 Subject: c: Implement C2x nodiscard attribute C2x adds the nodiscard standard attribute, with an optional string argument, as in C++; implement it for C. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ 2020-11-04 Joseph Myers * c-decl.c (handle_nodiscard_attribute): New. (std_attribute_table): Add nodiscard. * c-parser.c (c_parser_std_attribute): Expect argument to nodiscard attribute to be a string. Do not special-case ignoring nodiscard. * c-typeck.c (maybe_warn_nodiscard): New. (build_compound_expr, emit_side_effect_warnings): Call maybe_warn_nodiscard. (c_process_expr_stmt, c_finish_stmt_expr): Also call emit_side_effect_warnings if warn_unused_result. gcc/testsuite/ 2020-11-04 Joseph Myers * gcc.dg/c2x-attr-nodiscard-1.c, gcc.dg/c2x-attr-nodiscard-2.c, gcc.dg/c2x-attr-nodiscard-3.c, gcc.dg/c2x-attr-nodiscard-4.c: New tests. * gcc.dg/c2x-attr-syntax-5.c: Remove nodiscard test. --- gcc/c/c-decl.c | 27 ++++++++++++++++++ gcc/c/c-parser.c | 10 +++---- gcc/c/c-typeck.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index a5d0b15..d4179aa 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -4400,6 +4400,31 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) } +/* Handle the standard [[nodiscard]] attribute. */ + +static tree +handle_nodiscard_attribute (tree *node, tree name, tree /*args*/, + int /*flags*/, bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))) + warning_at (DECL_SOURCE_LOCATION (*node), + OPT_Wattributes, "%qE attribute applied to %qD with void " + "return type", name, *node); + } + else if (RECORD_OR_UNION_TYPE_P (*node) + || TREE_CODE (*node) == ENUMERAL_TYPE) + /* OK */; + else + { + pedwarn (input_location, + OPT_Wattributes, "%qE attribute can only be applied to " + "functions or to structure, union or enumeration types", name); + *no_add_attrs = true; + } + return NULL_TREE; +} /* Table of supported standard (C2x) attributes. */ const struct attribute_spec std_attribute_table[] = { @@ -4411,6 +4436,8 @@ const struct attribute_spec std_attribute_table[] = handle_fallthrough_attribute, NULL }, { "maybe_unused", 0, 0, false, false, false, false, handle_unused_attribute, NULL }, + { "nodiscard", 0, 1, false, false, false, false, + handle_nodiscard_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index b921c4e..fc97aa3 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -4950,7 +4950,8 @@ c_parser_std_attribute (c_parser *parser, bool for_tm) && attribute_takes_identifier_p (name)); bool require_string = (ns == NULL_TREE - && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0); + && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0 + || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0)); TREE_VALUE (attribute) = c_parser_attribute_arguments (parser, takes_identifier, require_string, false); @@ -4960,13 +4961,12 @@ c_parser_std_attribute (c_parser *parser, bool for_tm) parens.require_close (parser); } out: - if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name)) + if (ns == NULL_TREE && !for_tm && !as) { /* An attribute with standard syntax and no namespace specified is a constraint violation if it is not one of the known - standard attributes (of which nodiscard is the only one - without a handler in GCC). Diagnose it here with a pedwarn - and then discard it to prevent a duplicate warning later. */ + standard attributes. Diagnose it here with a pedwarn and + then discard it to prevent a duplicate warning later. */ pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", name); return error_mark_node; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 981cbe8..0d75ed4 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -5490,6 +5490,82 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, return ret; } +/* EXPR is an expression, location LOC, whose result is discarded. + Warn if it is a call to a nodiscard function (or a COMPOUND_EXPR + whose right-hand operand is such a call, possibly recursively). */ + +static void +maybe_warn_nodiscard (location_t loc, tree expr) +{ + if (VOID_TYPE_P (TREE_TYPE (expr))) + return; + while (TREE_CODE (expr) == COMPOUND_EXPR) + { + expr = TREE_OPERAND (expr, 1); + if (EXPR_HAS_LOCATION (expr)) + loc = EXPR_LOCATION (expr); + } + if (TREE_CODE (expr) != CALL_EXPR) + return; + tree fn = CALL_EXPR_FN (expr); + if (!fn) + return; + tree attr; + if (TREE_CODE (fn) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL + && (attr = lookup_attribute ("nodiscard", + DECL_ATTRIBUTES (TREE_OPERAND (fn, 0))))) + { + fn = TREE_OPERAND (fn, 0); + tree args = TREE_VALUE (attr); + if (args) + args = TREE_VALUE (args); + auto_diagnostic_group d; + int warned; + if (args) + warned = warning_at (loc, OPT_Wunused_result, + "ignoring return value of %qD, declared with " + "attribute %: %E", fn, args); + else + warned = warning_at (loc, OPT_Wunused_result, + "ignoring return value of %qD, declared with " + "attribute %", fn); + if (warned) + inform (DECL_SOURCE_LOCATION (fn), "declared here"); + } + else + { + tree rettype = TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))); + attr = lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype)); + if (!attr) + return; + tree args = TREE_VALUE (attr); + if (args) + args = TREE_VALUE (args); + auto_diagnostic_group d; + int warned; + if (args) + warned = warning_at (loc, OPT_Wunused_result, + "ignoring return value of type %qT, declared " + "with attribute %: %E", + rettype, args); + else + warned = warning_at (loc, OPT_Wunused_result, + "ignoring return value of type %qT, declared " + "with attribute %", rettype); + if (warned) + { + if (TREE_CODE (fn) == ADDR_EXPR) + { + fn = TREE_OPERAND (fn, 0); + if (TREE_CODE (fn) == FUNCTION_DECL) + inform (DECL_SOURCE_LOCATION (fn), + "in call to %qD, declared here", fn); + } + } + } +} + /* Return a compound expression that performs two expressions and returns the value of the second of them. @@ -5561,6 +5637,8 @@ build_compound_expr (location_t loc, tree expr1, tree expr2) else if (warn_unused_value) warn_if_unused_value (expr1, loc); + maybe_warn_nodiscard (loc, expr1); + if (expr2 == error_mark_node) return error_mark_node; @@ -11072,6 +11150,9 @@ c_finish_bc_stmt (location_t loc, tree label, bool is_break) static void emit_side_effect_warnings (location_t loc, tree expr) { + maybe_warn_nodiscard (loc, expr); + if (!warn_unused_value) + return; if (expr == error_mark_node) ; else if (!TREE_SIDE_EFFECTS (expr)) @@ -11127,7 +11208,7 @@ c_process_expr_stmt (location_t loc, tree expr) Warnings for statement expressions will be emitted later, once we figure out which is the result. */ if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list) - && warn_unused_value) + && (warn_unused_value || warn_unused_result)) emit_side_effect_warnings (EXPR_LOC_OR_LOC (expr, loc), expr); exprv = expr; @@ -11221,7 +11302,7 @@ c_finish_stmt_expr (location_t loc, tree body) /* If we're supposed to generate side effects warnings, process all of the statements except the last. */ - if (warn_unused_value) + if (warn_unused_value || warn_unused_result) { for (tree_stmt_iterator i = tsi_start (last); tsi_stmt (i) != tsi_stmt (l); tsi_next (&i)) -- cgit v1.1 From 9649031577028310e853025672c71dfb500494f0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 4 Nov 2020 09:37:22 +0100 Subject: openmp: allocate clause vs. *reduction array sections [PR97670] This patch finds the base expression of reduction array sections and uses it in checks whether allocate clause lists only variables that have been privatized. Also fixes a pasto that caused an ICE. 2020-11-04 Jakub Jelinek PR c++/97670 gcc/c-family/ * c-omp.c (c_omp_split_clauses): Look through array reductions to find underlying decl to clear in the allocate_head bitmap. gcc/c/ * c-typeck.c (c_finish_omp_clauses): Look through array reductions to find underlying decl to clear in the aligned_head bitmap. gcc/cp/ * semantics.c (finish_omp_clauses): Look through array reductions to find underlying decl to clear in the aligned_head bitmap. Use DECL_UID (t) instead of DECL_UID (OMP_CLAUSE_DECL (c)) when clearing in the bitmap. Only diagnose errors about allocate vars not being privatized on the same construct on allocate clause if it has a DECL_P OMP_CLAUSE_DECL. gcc/testsuite/ * c-c++-common/gomp/allocate-4.c: New test. * g++.dg/gomp/allocate-2.C: New test. * g++.dg/gomp/allocate-3.C: New test. --- gcc/c/c-typeck.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 0d75ed4..2bf46f4 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -15153,13 +15153,26 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (allocate_seen) switch (OMP_CLAUSE_CODE (c)) { + case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF) + { + t = TREE_OPERAND (OMP_CLAUSE_DECL (c), 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); + if (DECL_P (t)) + bitmap_clear_bit (&aligned_head, DECL_UID (t)); + break; + } + /* FALLTHRU */ case OMP_CLAUSE_PRIVATE: case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_LASTPRIVATE: case OMP_CLAUSE_LINEAR: - case OMP_CLAUSE_REDUCTION: - case OMP_CLAUSE_IN_REDUCTION: - case OMP_CLAUSE_TASK_REDUCTION: if (DECL_P (OMP_CLAUSE_DECL (c))) bitmap_clear_bit (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c))); -- cgit v1.1 From 35c125cb6ac47fa97aa5ee22f987a38e63adad08 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 5 Nov 2020 00:16:36 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index ca844ca..43a9c58 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,22 @@ +2020-11-04 Jakub Jelinek + + PR c++/97670 + * c-typeck.c (c_finish_omp_clauses): Look through array reductions to + find underlying decl to clear in the aligned_head bitmap. + +2020-11-04 Joseph Myers + + * c-decl.c (handle_nodiscard_attribute): New. + (std_attribute_table): Add nodiscard. + * c-parser.c (c_parser_std_attribute): Expect argument to + nodiscard attribute to be a string. Do not special-case ignoring + nodiscard. + * c-typeck.c (maybe_warn_nodiscard): New. + (build_compound_expr, emit_side_effect_warnings): Call + maybe_warn_nodiscard. + (c_process_expr_stmt, c_finish_stmt_expr): Also call + emit_side_effect_warnings if warn_unused_result. + 2020-10-29 Asher Gordon * c-typeck.c (free_all_tagged_tu_seen_up_to): Replace free -- cgit v1.1 From a2c11935b010ee55f7ccd14d27f62c6fbed3745e Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Fri, 6 Nov 2020 11:13:47 +0100 Subject: OpenACC (C/C++): Fix 'acc atomic' parsing gcc/c/ChangeLog: * c-parser.c (c_parser_omp_atomic): Add openacc parameter and update OpenACC matching. (c_parser_omp_construct): Update call. gcc/cp/ChangeLog: * parser.c (cp_parser_omp_atomic): Add openacc parameter and update OpenACC matching. (cp_parser_omp_construct): Update call. gcc/testsuite/ChangeLog: * c-c++-common/goacc-gomp/atomic.c: New test. * c-c++-common/goacc/atomic.c: New test. --- gcc/c/c-parser.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index fc97aa3..dedfb84 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -17304,7 +17304,7 @@ c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) LOC is the location of the #pragma token. */ static void -c_parser_omp_atomic (location_t loc, c_parser *parser) +c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc) { tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE; tree lhs1 = NULL_TREE, rhs1 = NULL_TREE; @@ -17343,6 +17343,12 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) new_code = OMP_ATOMIC; else if (!strcmp (p, "capture")) new_code = OMP_ATOMIC_CAPTURE_NEW; + else if (openacc) + { + p = NULL; + error_at (cloc, "expected %, %, %, " + "or % clause"); + } else if (!strcmp (p, "seq_cst")) new_memory_order = OMP_MEMORY_ORDER_SEQ_CST; else if (!strcmp (p, "acq_rel")) @@ -17370,7 +17376,12 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) { if (new_code != ERROR_MARK) { - if (code != ERROR_MARK) + /* OpenACC permits 'update capture'. */ + if (openacc + && code == OMP_ATOMIC + && new_code == OMP_ATOMIC_CAPTURE_NEW) + code = new_code; + else if (code != ERROR_MARK) error_at (cloc, "too many atomic clauses"); else code = new_code; @@ -17392,7 +17403,9 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) if (code == ERROR_MARK) code = OMP_ATOMIC; - if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED) + if (openacc) + memory_order = OMP_MEMORY_ORDER_RELAXED; + else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED) { omp_requires_mask = (enum omp_requires) (omp_requires_mask @@ -17448,6 +17461,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser) } break; case OMP_ATOMIC: + /* case OMP_ATOMIC_CAPTURE_NEW: - or update to OpenMP 5.1 */ if (memory_order == OMP_MEMORY_ORDER_ACQ_REL || memory_order == OMP_MEMORY_ORDER_ACQUIRE) { @@ -21489,7 +21503,7 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) switch (p_kind) { case PRAGMA_OACC_ATOMIC: - c_parser_omp_atomic (loc, parser); + c_parser_omp_atomic (loc, parser, true); return; case PRAGMA_OACC_CACHE: strcpy (p_name, "#pragma acc"); @@ -21516,7 +21530,7 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) stmt = c_parser_oacc_wait (loc, parser, p_name); break; case PRAGMA_OMP_ATOMIC: - c_parser_omp_atomic (loc, parser); + c_parser_omp_atomic (loc, parser, false); return; case PRAGMA_OMP_CRITICAL: stmt = c_parser_omp_critical (loc, parser, if_p); -- cgit v1.1 From ba6498124c35e60360f9492d7b5651d0f486d110 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 6 Nov 2020 09:59:21 -0800 Subject: core: Rename DECL_IS_BUILTIN -> DECL_IS_UNDECLARED_BUILTIN In cleaning up C++'s handling of hidden decls, I renamed its DECL_BUILTIN_P, which checks for loc == BUILTINS_LOCATION to DECL_UNDECLARED_BUILTIN_P, because the location gets updated, if user source declares the builtin, and the predicate no longer holds. The original name was confusing me. (The builtin may still retain builtin properties in the redeclaration, and other predicates can still detect that.) I discovered that tree.h had its own variant 'DECL_IS_BUILTIN', which behaves in (almost) the same manner. And therefore has the same mutating behaviour. This patch deletes the C++ one, and renames tree.h's to DECL_IS_UNDECLARED_BUILTIN, to emphasize its non-constantness. I guess _IS_ wins over _P gcc/ * tree.h (DECL_IS_BUILTIN): Rename to ... (DECL_IS_UNDECLARED_BUILTIN): ... here. No need to use SOURCE_LOCUS. * calls.c (maybe_warn_alloc_args_overflow): Adjust for rename. * cfgexpand.c (pass_expand::execute): Likewise. * dwarf2out.c (base_type_die, is_naming_typedef_decl): Likewise. * godump.c (go_decl, go_type_decl): Likewise. * print-tree.c (print_decl_identifier): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Likewise. * xcoffout.c (xcoff_assign_fundamental_type_number): Likewise. gcc/c-family/ * c-ada-spec.c (collect_ada_nodes): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. (collect_ada_node): Likewise. (dump_forward_type): Likewise. * c-common.c (set_underlying_type): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. (user_facing_original_type, c_common_finalize_early_debug): Likewise. gcc/c/ * c-decl.c (diagnose_mismatched_decls): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. (warn_if_shadowing, implicitly_declare, names_builtin_p) (collect_source_refs): Likewise. * c-typeck.c (inform_declaration, inform_for_arg) (convert_for_assignment): Likewise. gcc/cp/ * cp-tree.h (DECL_UNDECLARED_BUILTIN_P): Delete. * cp-objcp-common.c (names_bultin_p): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. * decl.c (decls_match): Likewise. Replace DECL_UNDECLARED_BUILTIN_P with DECL_IS_UNDECLARED_BUILTIN. (duplicate_decls): Likewise. * decl2.c (collect_source_refs): Likewise. * name-lookup.c (anticipated_builtin_p, print_binding_level) (do_nonmember_using_decl): Likewise. * pt.c (builtin_pack_fn_p): Likewise. * typeck.c (error_args_num): Likewise. gcc/lto/ * lto-symtab.c (lto_symtab_merge_decls_1): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. gcc/go/ * go-gcc.cc (Gcc_backend::call_expression): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. libcc1/ * libcc1plugin.cc (address_rewriter): Rename DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. * libcp1plugin.cc (supplement_binding): Likewise. --- gcc/c/c-decl.c | 14 +++++++------- gcc/c/c-typeck.c | 10 ++++++---- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index d4179aa..f19c82c 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2051,7 +2051,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } } else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_IS_BUILTIN (olddecl)) + && DECL_IS_UNDECLARED_BUILTIN (olddecl)) { /* A conflicting function declaration for a predeclared function that isn't actually built in. Objective C uses @@ -2265,7 +2265,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, built in, newdecl silently overrides olddecl. The latter occur only in Objective C; see also above. (FIXME: Make Objective C use normal builtins.) */ - if (!DECL_IS_BUILTIN (olddecl) + if (!DECL_IS_UNDECLARED_BUILTIN (olddecl) && !DECL_EXTERN_INLINE (olddecl)) { auto_diagnostic_group d; @@ -2978,7 +2978,7 @@ warn_if_shadowing (tree new_decl) || warn_shadow_local || warn_shadow_compatible_local) /* No shadow warnings for internally generated vars. */ - || DECL_IS_BUILTIN (new_decl)) + || DECL_IS_UNDECLARED_BUILTIN (new_decl)) return; /* Is anything being shadowed? Invisible decls do not count. */ @@ -3631,7 +3631,7 @@ implicitly_declare (location_t loc, tree functionid) in the external scope because they're pushed before the file scope gets created. Catch this here and rebind them into the file scope. */ - if (!fndecl_built_in_p (decl) && DECL_IS_BUILTIN (decl)) + if (!fndecl_built_in_p (decl) && DECL_IS_UNDECLARED_BUILTIN (decl)) { bind (functionid, decl, file_scope, /*invisible=*/false, /*nested=*/true, @@ -10500,7 +10500,7 @@ names_builtin_p (const char *name) { tree id = get_identifier (name); if (tree decl = identifier_global_value (id)) - return TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_BUILTIN (decl); + return TREE_CODE (decl) == FUNCTION_DECL && DECL_IS_UNDECLARED_BUILTIN (decl); /* Also detect common reserved C words that aren't strictly built-in functions. */ @@ -12134,12 +12134,12 @@ collect_source_refs (void) { decls = DECL_INITIAL (t); for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl)) - if (!DECL_IS_BUILTIN (decl)) + if (!DECL_IS_UNDECLARED_BUILTIN (decl)) collect_source_ref (DECL_SOURCE_FILE (decl)); } for (decl = BLOCK_VARS (ext_block); decl; decl = TREE_CHAIN (decl)) - if (!DECL_IS_BUILTIN (decl)) + if (!DECL_IS_UNDECLARED_BUILTIN (decl)) collect_source_ref (DECL_SOURCE_FILE (decl)); } diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 2bf46f4..9684037 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3014,7 +3014,8 @@ build_function_call (location_t loc, tree function, tree params) static void inform_declaration (tree decl) { - if (decl && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_IS_BUILTIN (decl))) + if (decl && (TREE_CODE (decl) != FUNCTION_DECL + || !DECL_IS_UNDECLARED_BUILTIN (decl))) inform (DECL_SOURCE_LOCATION (decl), "declared here"); } @@ -6578,7 +6579,7 @@ inform_for_arg (tree fundecl, location_t ploc, int parmnum, tree expected_type, tree actual_type) { location_t loc; - if (fundecl && !DECL_IS_BUILTIN (fundecl)) + if (fundecl && !DECL_IS_UNDECLARED_BUILTIN (fundecl)) loc = get_fndecl_argument_location (fundecl, parmnum - 1); else loc = ploc; @@ -6828,7 +6829,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, if (pedwarn (expr_loc, OPT_Wc___compat, "enum conversion when " "passing argument %d of %qE is invalid in C++", parmnum, rname)) - inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) + inform ((fundecl && !DECL_IS_UNDECLARED_BUILTIN (fundecl)) ? DECL_SOURCE_LOCATION (fundecl) : expr_loc, "expected %qT but argument is of type %qT", type, rhstype); @@ -7239,7 +7240,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, case ic_argpass: /* Do not warn for built-in functions, for example memcpy, since we control how they behave and they can be useful in this area. */ - if (TREE_CODE (rname) != FUNCTION_DECL || !DECL_IS_BUILTIN (rname)) + if (TREE_CODE (rname) != FUNCTION_DECL + || !DECL_IS_UNDECLARED_BUILTIN (rname)) warning_at (location, OPT_Wscalar_storage_order, "passing argument %d of %qE from incompatible " "scalar storage order", parmnum, rname); -- cgit v1.1 From 9a34a5cce6b50fc3527e7c7ab356808ed435883c Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 31 Oct 2020 20:53:34 +0000 Subject: Objective-C/C++ (parsers) : Update @property attribute parsing. At present, we are missing parsing and checking for around half of the property attributes in use. The existing ad hoc scheme for the parser's communication with the Objective C validation is not suitable for extending to cover all the missing cases. Additionally: 1/ We were declaring errors in two cases that the reference implementation warns (or is silent). I've elected to warn for both those cases, (Wattributes) it could be that we should implement Wobjc-xxx-property warning masks (TODO). 2/ We were emitting spurious complaints about missing property attributes when these were not being parsed because we gave up on the first syntax error. 3/ The quality of the diagnostic locations was poor (that's true for much of Objective-C, we will have to improve it as we modernise areas). We continue to attempt to keep the code, warning and error output similar (preferably identical output) between the C and C++ front ends. The interface to the Objective-C-specific parts of the parsing is simplified to a vector of parsed (but not fully-checked) property attributes, this will simplify the addition of new attributes. gcc/c-family/ChangeLog: * c-objc.h (enum objc_property_attribute_group): New (enum objc_property_attribute_kind): New. (OBJC_PROPATTR_GROUP_MASK): New. (struct property_attribute_info): Small class encapsulating parser output from property attributes. (objc_prop_attr_kind_for_rid): New (objc_add_property_declaration): Simplify interface. * stub-objc.c (enum rid): Dummy type. (objc_add_property_declaration): Simplify interface. (objc_prop_attr_kind_for_rid): New. gcc/c/ChangeLog: * c-parser.c (c_parser_objc_at_property_declaration): Improve parsing fidelity. Associate better location info with @property attributes. Clean up the interface to objc_add_property_declaration (). gcc/cp/ChangeLog: * parser.c (cp_parser_objc_at_property_declaration): Improve parsing fidelity. Associate better location info with @property attributes. Clean up the interface to objc_add_property_declaration (). gcc/objc/ChangeLog: * objc-act.c (objc_prop_attr_kind_for_rid): New. (objc_add_property_declaration): Adjust to consume the parser output using a vector of parsed attributes. gcc/testsuite/ChangeLog: * obj-c++.dg/property/at-property-1.mm: Adjust expected diagnostics. * obj-c++.dg/property/at-property-29.mm: Likewise. * obj-c++.dg/property/at-property-4.mm: Likewise. * obj-c++.dg/property/property-neg-2.mm: Likewise. * objc.dg/property/at-property-1.m: Likewise. * objc.dg/property/at-property-29.m: Likewise. * objc.dg/property/at-property-4.m: Likewise. * objc.dg/property/at-property-5.m: Likewise. * objc.dg/property/property-neg-2.m: Likewise. --- gcc/c/c-parser.c | 280 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 159 insertions(+), 121 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index dedfb84..da8278a8 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11958,158 +11958,196 @@ c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, static void c_parser_objc_at_property_declaration (c_parser *parser) { - /* The following variables hold the attributes of the properties as - parsed. They are 'false' or 'NULL_TREE' if the attribute was not - seen. When we see an attribute, we set them to 'true' (if they - are boolean properties) or to the identifier (if they have an - argument, ie, for getter and setter). Note that here we only - parse the list of attributes, check the syntax and accumulate the - attributes that we find. objc_add_property_declaration() will - then process the information. */ - bool property_assign = false; - bool property_copy = false; - tree property_getter_ident = NULL_TREE; - bool property_nonatomic = false; - bool property_readonly = false; - bool property_readwrite = false; - bool property_retain = false; - tree property_setter_ident = NULL_TREE; - - /* 'properties' is the list of properties that we read. Usually a - single one, but maybe more (eg, in "@property int a, b, c;" there - are three). */ - tree properties; - location_t loc; - - loc = c_parser_peek_token (parser)->location; gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY)); - + location_t loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); /* Eat '@property'. */ - /* Parse the optional attribute list... */ + /* Parse the optional attribute list. + + A list of parsed, but not verified, attributes. */ + vec prop_attr_list = vNULL; + + bool syntax_error = false; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { matching_parens parens; + location_t attr_start = c_parser_peek_token (parser)->location; /* Eat the '(' */ parens.consume_open (parser); /* Property attribute keywords are valid now. */ parser->objc_property_attr_context = true; - while (true) + /* Allow @property (), with a warning. */ + location_t attr_end = c_parser_peek_token (parser)->location; + + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { - bool syntax_error = false; - c_token *token = c_parser_peek_token (parser); - enum rid keyword; + location_t attr_comb = make_location (attr_end, attr_start, attr_end); + warning_at (attr_comb, OPT_Wattributes, + "empty property attribute list"); + } + else + while (true) + { + c_token *token = c_parser_peek_token (parser); + attr_start = token->location; + attr_end = get_finish (token->location); + location_t attr_comb = make_location (attr_start, attr_start, + attr_end); - if (token->type != CPP_KEYWORD) - { - if (token->type == CPP_CLOSE_PAREN) - c_parser_error (parser, "expected identifier"); - else - { - c_parser_consume_token (parser); - c_parser_error (parser, "unknown property attribute"); - } - break; - } - keyword = token->keyword; - c_parser_consume_token (parser); - switch (keyword) - { - case RID_ASSIGN: property_assign = true; break; - case RID_COPY: property_copy = true; break; - case RID_NONATOMIC: property_nonatomic = true; break; - case RID_READONLY: property_readonly = true; break; - case RID_READWRITE: property_readwrite = true; break; - case RID_RETAIN: property_retain = true; break; - - case RID_GETTER: - case RID_SETTER: - if (c_parser_next_token_is_not (parser, CPP_EQ)) - { - if (keyword == RID_GETTER) - c_parser_error (parser, - "missing %<=%> (after % attribute)"); - else - c_parser_error (parser, - "missing %<=%> (after % attribute)"); - syntax_error = true; - break; - } - c_parser_consume_token (parser); /* eat the = */ - if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - syntax_error = true; + if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA) + { + warning_at (attr_comb, OPT_Wattributes, + "missing property attribute"); + if (token->type == CPP_CLOSE_PAREN) break; - } - if (keyword == RID_SETTER) - { - if (property_setter_ident != NULL_TREE) - c_parser_error (parser, "the % attribute may only be specified once"); - else - property_setter_ident = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - if (c_parser_next_token_is_not (parser, CPP_COLON)) - c_parser_error (parser, "setter name must terminate with %<:%>"); - else - c_parser_consume_token (parser); - } - else - { - if (property_getter_ident != NULL_TREE) - c_parser_error (parser, "the % attribute may only be specified once"); - else - property_getter_ident = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - } - break; - default: - c_parser_error (parser, "unknown property attribute"); - syntax_error = true; - break; + c_parser_consume_token (parser); + continue; + } + + tree attr_name = NULL_TREE; + enum rid keyword = RID_MAX; /* Not a valid property attribute. */ + bool add_at = false; + if (token->type == CPP_KEYWORD) + { + keyword = token->keyword; + if (OBJC_IS_AT_KEYWORD (keyword)) + { + /* For '@' keywords the token value has the keyword, + prepend the '@' for diagnostics. */ + attr_name = token->value; + add_at = true; + } + else + attr_name = ridpointers[(int)keyword]; + } + else if (token->type == CPP_NAME) + attr_name = token->value; + c_parser_consume_token (parser); + + enum objc_property_attribute_kind prop_kind + = objc_prop_attr_kind_for_rid (keyword); + property_attribute_info *prop + = new property_attribute_info (attr_name, attr_comb, prop_kind); + prop_attr_list.safe_push (prop); + + tree meth_name; + switch (prop->prop_kind) + { + default: break; + case OBJC_PROPERTY_ATTR_UNKNOWN: + if (attr_name) + error_at (attr_comb, "unknown property attribute %<%s%s%>", + add_at ? "@" : "", IDENTIFIER_POINTER (attr_name)); + else + error_at (attr_comb, "unknown property attribute"); + prop->parse_error = syntax_error = true; + break; + + case OBJC_PROPERTY_ATTR_GETTER: + case OBJC_PROPERTY_ATTR_SETTER: + if (c_parser_next_token_is_not (parser, CPP_EQ)) + { + attr_comb = make_location (attr_end, attr_start, attr_end); + error_at (attr_comb, "expected %<=%> after Objective-C %qE", + attr_name); + prop->parse_error = syntax_error = true; + break; + } + token = c_parser_peek_token (parser); + attr_end = token->location; + c_parser_consume_token (parser); /* eat the = */ + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + attr_comb = make_location (attr_end, attr_start, attr_end); + error_at (attr_comb, "expected %qE selector name", + attr_name); + prop->parse_error = syntax_error = true; + break; + } + /* Get the end of the method name, and consume the name. */ + token = c_parser_peek_token (parser); + attr_end = get_finish (token->location); + meth_name = token->value; + c_parser_consume_token (parser); + if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER) + { + if (c_parser_next_token_is_not (parser, CPP_COLON)) + { + attr_comb = make_location (attr_end, attr_start, + attr_end); + error_at (attr_comb, "setter method names must" + " terminate with %<:%>"); + prop->parse_error = syntax_error = true; + } + else + { + attr_end = get_finish (c_parser_peek_token + (parser)->location); + c_parser_consume_token (parser); + } + attr_comb = make_location (attr_start, attr_start, + attr_end); + } + else + attr_comb = make_location (attr_start, attr_start, + attr_end); + prop->ident = meth_name; + /* Updated location including all that was successfully + parsed. */ + prop->prop_loc = attr_comb; + break; } - if (syntax_error) - break; - + /* If we see a comma here, then keep going - even if we already + saw a syntax error. For simple mistakes e.g. (asign, getter=x) + this makes a more useful output and avoid spurious warnings about + missing attributes that are, in fact, specified after the one with + the syntax error. */ if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); else break; } parser->objc_property_attr_context = false; - parens.skip_until_found_close (parser); - } - /* ... and the property declaration(s). */ - properties = c_parser_struct_declaration (parser); - if (properties == error_mark_node) - { - c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); - parser->error = false; - return; + if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) + /* We don't really want to chew the whole of the file looking for a + matching closing parenthesis, so we will try to read the decl and + let the error handling for that close out the statement. */ + ; + else + syntax_error = false, parens.skip_until_found_close (parser); } - if (properties == NULL_TREE) - c_parser_error (parser, "expected identifier"); + /* 'properties' is the list of properties that we read. Usually a + single one, but maybe more (eg, in "@property int a, b, c;" there + are three). */ + tree properties = c_parser_struct_declaration (parser); + + if (properties == error_mark_node) + c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); else { - /* Comma-separated properties are chained together in - reverse order; add them one by one. */ - properties = nreverse (properties); - - for (; properties; properties = TREE_CHAIN (properties)) - objc_add_property_declaration (loc, copy_node (properties), - property_readonly, property_readwrite, - property_assign, property_retain, - property_copy, property_nonatomic, - property_getter_ident, property_setter_ident); + if (properties == NULL_TREE) + c_parser_error (parser, "expected identifier"); + else + { + /* Comma-separated properties are chained together in reverse order; + add them one by one. */ + properties = nreverse (properties); + for (; properties; properties = TREE_CHAIN (properties)) + objc_add_property_declaration (loc, copy_node (properties), + prop_attr_list); + } + c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } - c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); + while (!prop_attr_list.is_empty()) + delete prop_attr_list.pop (); + prop_attr_list.release (); parser->error = false; } -- cgit v1.1 From 44cab2d8fd777450953ee1c1dfeba6f67db13869 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 7 Nov 2020 00:16:39 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 43a9c58..933b343 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,25 @@ +2020-11-06 Iain Sandoe + + * c-parser.c (c_parser_objc_at_property_declaration): + Improve parsing fidelity. Associate better location info + with @property attributes. Clean up the interface to + objc_add_property_declaration (). + +2020-11-06 Nathan Sidwell + + * c-decl.c (diagnose_mismatched_decls): Rename + DECL_IS_BUILTIN->DECL_IS_UNDECLARED_BUILTIN. + (warn_if_shadowing, implicitly_declare, names_builtin_p) + (collect_source_refs): Likewise. + * c-typeck.c (inform_declaration, inform_for_arg) + (convert_for_assignment): Likewise. + +2020-11-06 Tobias Burnus + + * c-parser.c (c_parser_omp_atomic): Add openacc parameter and update + OpenACC matching. + (c_parser_omp_construct): Update call. + 2020-11-04 Jakub Jelinek PR c++/97670 -- cgit v1.1 From 8b7a9a249a63e066cff6e95db05a3158b4cc56cc Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Sat, 7 Nov 2020 00:48:33 +0100 Subject: C Parser: Implement mixing of labels and code. Implement mixing of labels and code as adopted for C2X and process some std-attributes on labels. 2020-11-06 Martin Uecker gcc/ * doc/extend.texi: Document mixing labels and code. * doc/invoke.texi: Likewise. gcc/c/ * c-parser.c (c_parser_label): Implement mixing of labels and code. (c_parser_all_labels): Likewise. gcc/testsuite/ * c-c++-common/attr-fallthrough-2.c: Update compiler flags. * c-c++-common/Wimplicit-fallthrough-20.c: Adapt test. * gcc.dg/20031223-1.c: Update compiler flags and adapt test. * gcc.dg/c11-labels-1.c: New test. * gcc.dg/c11-labels-2.c: New test. * gcc.dg/c11-labels-3.c: New test. * gcc.dg/c2x-attr-syntax-3.c: Adapt test. * gcc.dg/c2x-labels-1.c: New test. * gcc.dg/c2x-labels-2.c: New test. * gcc.dg/c2x-labels-3.c: New test. * gcc.dg/decl-9.c: Update compiler flags and add error. * gcc.dg/gomp/barrier-2.c: Update compiler flags and add warning. * gcc.dg/gomp/declare-simd-5.c: Update compiler flags and adapt test. * gcc.dg/gomp/declare-variant-2.c: Update compiler flags and add error. * gcc.dg/label-compound-stmt-1.c: Update compiler flags. * gcc.dg/parse-decl-after-label.c: Update compiler flags. --- gcc/c/c-parser.c | 105 ++++++++++++++++++++----------------------------------- 1 file changed, 37 insertions(+), 68 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index da8278a8..ecc3d21 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1521,7 +1521,7 @@ static void c_parser_initval (c_parser *, struct c_expr *, struct obstack *); static tree c_parser_compound_statement (c_parser *, location_t * = NULL); static location_t c_parser_compound_statement_nostart (c_parser *); -static void c_parser_label (c_parser *); +static void c_parser_label (c_parser *, tree); static void c_parser_statement (c_parser *, bool *, location_t * = NULL); static void c_parser_statement_after_labels (c_parser *, bool *, vec * = NULL); @@ -5523,7 +5523,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after, } /* Parse a compound statement (possibly a function body) (C90 6.6.2, - C99 6.8.2, C11 6.8.2). + C99 6.8.2, C11 6.8.2, C2X 6.8.2). compound-statement: { block-item-list[opt] } @@ -5534,6 +5534,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after, block-item-list block-item block-item: + label nested-declaration statement @@ -5674,7 +5675,7 @@ c_parser_compound_statement_nostart (c_parser *parser) { location_t loc = c_parser_peek_token (parser)->location; loc = expansion_point_location_if_in_system_header (loc); - /* Standard attributes may start a statement or a declaration. */ + /* Standard attributes may start a label, statement or declaration. */ bool have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1); tree std_attrs = NULL_TREE; @@ -5685,7 +5686,6 @@ c_parser_compound_statement_nostart (c_parser *parser) || (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) { - c_warn_unused_attributes (std_attrs); if (c_parser_next_token_is_keyword (parser, RID_CASE)) label_loc = c_parser_peek_2nd_token (parser)->location; else @@ -5693,27 +5693,31 @@ c_parser_compound_statement_nostart (c_parser *parser) last_label = true; last_stmt = false; mark_valid_location_for_stdc_pragma (false); - c_parser_label (parser); + c_parser_label (parser, std_attrs); } - else if (!last_label - && (c_parser_next_tokens_start_declaration (parser) - || (have_std_attrs - && c_parser_next_token_is (parser, CPP_SEMICOLON)))) + else if (c_parser_next_tokens_start_declaration (parser) + || (have_std_attrs + && c_parser_next_token_is (parser, CPP_SEMICOLON))) { - last_label = false; + if (last_label) + pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic, + "a label can only be part of a statement and " + "a declaration is not a statement"); + mark_valid_location_for_stdc_pragma (false); bool fallthru_attr_p = false; c_parser_declaration_or_fndef (parser, true, !have_std_attrs, true, true, true, NULL, vNULL, have_std_attrs, std_attrs, NULL, &fallthru_attr_p); + if (last_stmt && !fallthru_attr_p) pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, "ISO C90 forbids mixed declarations and code"); last_stmt = fallthru_attr_p; + last_label = false; } - else if (!last_label - && c_parser_next_token_is_keyword (parser, RID_EXTENSION)) + else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) { /* __extension__ can start a declaration, but is also an unary operator that can start an expression. Consume all @@ -5796,7 +5800,7 @@ c_parser_compound_statement_nostart (c_parser *parser) parser->error = false; } if (last_label) - error_at (label_loc, "label at end of compound statement"); + pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement"); location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); /* Restore the value we started with. */ @@ -5812,19 +5816,29 @@ c_parser_compound_statement_nostart (c_parser *parser) static void c_parser_all_labels (c_parser *parser) { + tree std_attrs = NULL; if (c_parser_nth_token_starts_std_attributes (parser, 1)) { - tree std_attrs = c_parser_std_attribute_specifier_sequence (parser); + std_attrs = c_parser_std_attribute_specifier_sequence (parser); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) c_parser_error (parser, "expected statement"); - else - c_warn_unused_attributes (std_attrs); } while (c_parser_next_token_is_keyword (parser, RID_CASE) || c_parser_next_token_is_keyword (parser, RID_DEFAULT) || (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) - c_parser_label (parser); + { + c_parser_label (parser, std_attrs); + std_attrs = NULL; + if (c_parser_nth_token_starts_std_attributes (parser, 1)) + { + std_attrs = c_parser_std_attribute_specifier_sequence (parser); + if (c_parser_next_token_is (parser, CPP_SEMICOLON)) + c_parser_error (parser, "expected statement"); + } + } + if (std_attrs) + c_warn_unused_attributes (std_attrs); } /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1). @@ -5846,9 +5860,8 @@ c_parser_all_labels (c_parser *parser) in the caller, to distinguish statements from declarations. Any attribute-specifier-sequence after the label is parsed in this function. */ - static void -c_parser_label (c_parser *parser) +c_parser_label (c_parser *parser, tree std_attrs) { location_t loc1 = c_parser_peek_token (parser)->location; tree label = NULL_TREE; @@ -5898,8 +5911,13 @@ c_parser_label (c_parser *parser) if (tlab) { decl_attributes (&tlab, attrs, 0); + decl_attributes (&tlab, std_attrs, 0); label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); } + if (attrs + && c_parser_next_tokens_start_declaration (parser)) + warning_at (loc2, OPT_Wattributes, "GNU-style attribute between" + " label and declaration appertains to the label"); } if (label) { @@ -5907,55 +5925,6 @@ c_parser_label (c_parser *parser) FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p; else FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p; - - /* Standard attributes are only allowed here if they start a - statement, not a declaration (including the case of an - attribute-declaration with only attributes). */ - bool have_std_attrs - = c_parser_nth_token_starts_std_attributes (parser, 1); - tree std_attrs = NULL_TREE; - if (have_std_attrs) - std_attrs = c_parser_std_attribute_specifier_sequence (parser); - - /* Allow '__attribute__((fallthrough));'. */ - if (!have_std_attrs - && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) - { - location_t loc = c_parser_peek_token (parser)->location; - tree attrs = c_parser_gnu_attributes (parser); - if (attribute_fallthrough_p (attrs)) - { - if (c_parser_next_token_is (parser, CPP_SEMICOLON)) - { - tree fn = build_call_expr_internal_loc (loc, - IFN_FALLTHROUGH, - void_type_node, 0); - add_stmt (fn); - } - else - warning_at (loc, OPT_Wattributes, "% attribute " - "not followed by %<;%>"); - } - else if (attrs != NULL_TREE) - warning_at (loc, OPT_Wattributes, "only attribute %" - " can be applied to a null statement"); - } - if (c_parser_next_tokens_start_declaration (parser) - || (have_std_attrs - && c_parser_next_token_is (parser, CPP_SEMICOLON))) - { - error_at (c_parser_peek_token (parser)->location, - "a label can only be part of a statement and " - "a declaration is not a statement"); - c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, - /*static_assert_ok*/ true, - /*empty_ok*/ true, /*nested*/ true, - /*start_attr_ok*/ true, NULL, - vNULL, have_std_attrs, std_attrs); - } - else if (std_attrs) - /* Nonempty attributes on the following statement are ignored. */ - c_warn_unused_attributes (std_attrs); } } -- cgit v1.1 From 2da7ee050cf01c8c38cb20828a432921e6b9f5b7 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 8 Nov 2020 00:16:31 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 933b343..5b0d42c 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2020-11-07 Martin Uecker + + * c-parser.c (c_parser_label): Implement mixing of labels and code. + (c_parser_all_labels): Likewise. + 2020-11-06 Iain Sandoe * c-parser.c (c_parser_objc_at_property_declaration): -- cgit v1.1 From 9e6280242225587be256fdb80c41327736238e77 Mon Sep 17 00:00:00 2001 From: Chung-Lin Tang Date: Tue, 10 Nov 2020 03:36:58 -0800 Subject: openmp: Implement OpenMP 5.0 base-pointer attachement and clause ordering This patch implements some parts of the target variable mapping changes specified in OpenMP 5.0, including base-pointer attachment/detachment behavior for array section list-items in map clauses, and ordering of map clauses according to map kind. 2020-11-10 Chung-Lin Tang gcc/c-family/ChangeLog: * c-common.h (c_omp_adjust_map_clauses): New declaration. * c-omp.c (struct map_clause): Helper type for c_omp_adjust_map_clauses. (c_omp_adjust_map_clauses): New function. gcc/c/ChangeLog: * c-parser.c (c_parser_omp_target_data): Add use of new c_omp_adjust_map_clauses function. Add GOMP_MAP_ATTACH_DETACH as handled map clause kind. (c_parser_omp_target_enter_data): Likewise. (c_parser_omp_target_exit_data): Likewise. (c_parser_omp_target): Likewise. * c-typeck.c (handle_omp_array_sections): Adjust COMPONENT_REF case to use GOMP_MAP_ATTACH_DETACH map kind for C_ORT_OMP region type. (c_finish_omp_clauses): Adjust bitmap checks to allow struct decl and same struct field access to co-exist on OpenMP construct. gcc/cp/ChangeLog: * parser.c (cp_parser_omp_target_data): Add use of new c_omp_adjust_map_clauses function. Add GOMP_MAP_ATTACH_DETACH as handled map clause kind. (cp_parser_omp_target_enter_data): Likewise. (cp_parser_omp_target_exit_data): Likewise. (cp_parser_omp_target): Likewise. * semantics.c (handle_omp_array_sections): Adjust COMPONENT_REF case to use GOMP_MAP_ATTACH_DETACH map kind for C_ORT_OMP region type. Fix interaction between reference case and attach/detach. (finish_omp_clauses): Adjust bitmap checks to allow struct decl and same struct field access to co-exist on OpenMP construct. gcc/ChangeLog: * gimplify.c (is_or_contains_p): New static helper function. (omp_target_reorder_clauses): New function. (gimplify_scan_omp_clauses): Add use of omp_target_reorder_clauses to reorder clause list according to OpenMP 5.0 rules. Add handling of GOMP_MAP_ATTACH_DETACH for OpenMP cases. * omp-low.c (is_omp_target): New static helper function. (scan_sharing_clauses): Add scan phase handling of GOMP_MAP_ATTACH/DETACH for OpenMP cases. (lower_omp_target): Add lowering handling of GOMP_MAP_ATTACH/DETACH for OpenMP cases. gcc/testsuite/ChangeLog: * c-c++-common/gomp/clauses-2.c: Remove dg-error cases now valid. * gfortran.dg/gomp/map-2.f90: Likewise. * c-c++-common/gomp/map-5.c: New testcase. libgomp/ChangeLog: * libgomp.h (enum gomp_map_vars_kind): Adjust enum values to be bit-flag usable. * oacc-mem.c (acc_map_data): Adjust gomp_map_vars argument flags to 'GOMP_MAP_VARS_OPENACC | GOMP_MAP_VARS_ENTER_DATA'. (goacc_enter_datum): Likewise for call to gomp_map_vars_async. (goacc_enter_data_internal): Likewise. * target.c (gomp_map_vars_internal): Change checks of GOMP_MAP_VARS_ENTER_DATA to use bit-and (&). Adjust use of gomp_attach_pointer for OpenMP cases. (gomp_exit_data): Add handling of GOMP_MAP_DETACH. (GOMP_target_enter_exit_data): Add handling of GOMP_MAP_ATTACH. * testsuite/libgomp.c-c++-common/ptr-attach-1.c: New testcase. --- gcc/c/c-parser.c | 10 +++++++++- gcc/c/c-typeck.c | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index ecc3d21..377914c 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -19511,6 +19511,7 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p) tree clauses = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK, "#pragma omp target data"); + c_omp_adjust_map_clauses (clauses, false); int map_seen = 0; for (tree *pc = &clauses; *pc;) { @@ -19528,6 +19529,7 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p) break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: + case GOMP_MAP_ATTACH_DETACH: break; default: map_seen |= 1; @@ -19651,6 +19653,7 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser, tree clauses = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK, "#pragma omp target enter data"); + c_omp_adjust_map_clauses (clauses, false); int map_seen = 0; for (tree *pc = &clauses; *pc;) { @@ -19664,6 +19667,7 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser, break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: + case GOMP_MAP_ATTACH_DETACH: break; default: map_seen |= 1; @@ -19735,7 +19739,7 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser, tree clauses = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK, "#pragma omp target exit data"); - + c_omp_adjust_map_clauses (clauses, false); int map_seen = 0; for (tree *pc = &clauses; *pc;) { @@ -19750,6 +19754,7 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser, break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: + case GOMP_MAP_ATTACH_DETACH: break; default: map_seen |= 1; @@ -19960,6 +19965,8 @@ c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p) OMP_TARGET_CLAUSES (stmt) = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK, "#pragma omp target"); + c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true); + pc = &OMP_TARGET_CLAUSES (stmt); keep_next_level (); block = c_begin_compound_stmt (true); @@ -19984,6 +19991,7 @@ check_clauses: case GOMP_MAP_ALLOC: case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: + case GOMP_MAP_ATTACH_DETACH: break; default: error_at (OMP_CLAUSE_LOCATION (*pc), diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 9684037..df1dad4 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13584,11 +13584,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) if (ort != C_ORT_OMP && ort != C_ORT_ACC) OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER); else if (TREE_CODE (t) == COMPONENT_REF) - { - gomp_map_kind k = (ort == C_ORT_ACC) ? GOMP_MAP_ATTACH_DETACH - : GOMP_MAP_ALWAYS_POINTER; - OMP_CLAUSE_SET_MAP_KIND (c2, k); - } + OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH); else OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER @@ -14711,7 +14707,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) { - if (bitmap_bit_p (&map_field_head, DECL_UID (t))) + if (bitmap_bit_p (&map_field_head, DECL_UID (t)) + || (ort == C_ORT_OMP + && bitmap_bit_p (&map_head, DECL_UID (t)))) break; } } @@ -14780,7 +14778,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) else bitmap_set_bit (&generic_head, DECL_UID (t)); } - else if (bitmap_bit_p (&map_head, DECL_UID (t))) + else if (bitmap_bit_p (&map_head, DECL_UID (t)) + && (ort != C_ORT_OMP + || !bitmap_bit_p (&map_field_head, DECL_UID (t)))) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) error_at (OMP_CLAUSE_LOCATION (c), @@ -14794,7 +14794,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) + && ort == C_ORT_ACC) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qD appears more than once in data clauses", t); + remove = true; + } + else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))) { if (ort == C_ORT_ACC) error_at (OMP_CLAUSE_LOCATION (c), -- cgit v1.1