diff options
author | Martin Liska <mliska@suse.cz> | 2022-10-04 12:04:54 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-10-04 12:04:54 +0200 |
commit | da0970e441345f8349522ff1abac5c223044ebb1 (patch) | |
tree | 17c2091a83c584a1eae4f8e219a460f85c5d3fd8 /gcc/c | |
parent | 54f3cfaf3a6f50958c71d79c85206a6c722e1a22 (diff) | |
parent | e886ebd17965d78f609b62479f4f48085108389c (diff) | |
download | gcc-da0970e441345f8349522ff1abac5c223044ebb1.zip gcc-da0970e441345f8349522ff1abac5c223044ebb1.tar.gz gcc-da0970e441345f8349522ff1abac5c223044ebb1.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 49 | ||||
-rw-r--r-- | gcc/c/c-lang.h | 7 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 75 |
4 files changed, 112 insertions, 24 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7b29d78..f5c9a59 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2022-09-29 Joseph Myers <joseph@codesourcery.com> + + * c-decl.cc (handle_std_noreturn_attribute): New function. + (std_attribute_table): Add _Noreturn and noreturn. + 2022-09-27 Jakub Jelinek <jakub@redhat.com> * c-lang.h (current_omp_begin_assumes): Declare. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 740982e..ffa63dc 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -153,9 +153,9 @@ static int warn_about_return_type; static bool undef_nested_function; -/* If non-zero, implicit "omp declare target" attribute is added into the - attribute lists. */ -int current_omp_declare_target_attribute; +/* Vector of implicit "omp declare target" attributes to be added into + the attribute lists. */ +vec<c_omp_declare_target_attr, va_gc> *current_omp_declare_target_attribute; /* If non-zero, we are inside of #pragma omp begin assumes ... #pragma omp end assumes region. */ @@ -4480,11 +4480,34 @@ handle_nodiscard_attribute (tree *node, tree name, tree /*args*/, } return NULL_TREE; } + +/* Handle the standard [[noreturn]] attribute. */ + +static tree +handle_std_noreturn_attribute (tree *node, tree name, tree args, + int flags, bool *no_add_attrs) +{ + /* Unlike GNU __attribute__ ((noreturn)), the standard [[noreturn]] + only applies to functions, not function pointers. */ + if (TREE_CODE (*node) == FUNCTION_DECL) + return handle_noreturn_attribute (node, name, args, flags, no_add_attrs); + else + { + pedwarn (input_location, OPT_Wattributes, + "standard %qE attribute can only be applied to functions", + name); + *no_add_attrs = true; + return NULL_TREE; + } +} + /* Table of supported standard (C2x) attributes. */ const struct attribute_spec std_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude } */ + { "_Noreturn", 0, 0, false, false, false, false, + handle_std_noreturn_attribute, NULL }, { "deprecated", 0, 1, false, false, false, false, handle_deprecated_attribute, NULL }, { "fallthrough", 0, 0, false, false, false, false, @@ -4493,6 +4516,8 @@ const struct attribute_spec std_attribute_table[] = handle_unused_attribute, NULL }, { "nodiscard", 0, 1, false, false, false, false, handle_nodiscard_attribute, NULL }, + { "noreturn", 0, 0, false, false, false, false, + handle_std_noreturn_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -5080,7 +5105,7 @@ static tree c_decl_attributes (tree *node, tree attributes, int flags) { /* Add implicit "omp declare target" attribute if requested. */ - if (current_omp_declare_target_attribute + if (vec_safe_length (current_omp_declare_target_attribute) && ((VAR_P (*node) && is_global_var (*node)) || TREE_CODE (*node) == FUNCTION_DECL)) { @@ -5094,6 +5119,22 @@ c_decl_attributes (tree *node, tree attributes, int flags) attributes = tree_cons (get_identifier ("omp declare target block"), NULL_TREE, attributes); } + if (TREE_CODE (*node) == FUNCTION_DECL) + { + int device_type + = current_omp_declare_target_attribute->last ().device_type; + device_type = MAX (device_type, 0); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0 + && !lookup_attribute ("omp declare target host", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target host"), + NULL_TREE, attributes); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0 + && !lookup_attribute ("omp declare target nohost", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target nohost"), + NULL_TREE, attributes); + } } /* Look up the current declaration with all the attributes merged diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 861abe8..49a5ec3 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -60,9 +60,14 @@ struct GTY(()) language_function { int warn_about_return_type; }; +struct GTY(()) c_omp_declare_target_attr { + int device_type; +}; + /* If non-zero, implicit "omp declare target" attribute is added into the attribute lists. */ -extern GTY(()) int current_omp_declare_target_attribute; +extern GTY(()) vec<c_omp_declare_target_attr, va_gc> + *current_omp_declare_target_attribute; /* Similarly whether we are in between #pragma omp begin assumes and #pragma omp end assumes (and how many times when nested). */ extern GTY(()) int current_omp_begin_assumes; diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index f2498dc..f6a94ba 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -1675,18 +1675,22 @@ c_parser_translation_unit (c_parser *parser) if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) error ("storage size of %q+D isn%'t known", decl); - if (current_omp_declare_target_attribute) + if (vec_safe_length (current_omp_declare_target_attribute)) { + c_omp_declare_target_attr + a = current_omp_declare_target_attribute->pop (); if (!errorcount) - error ("%<#pragma omp declare target%> without corresponding " - "%<#pragma omp end declare target%>"); - current_omp_declare_target_attribute = 0; + error ("%qs without corresponding %qs", + a.device_type >= 0 ? "#pragma omp begin declare target" + : "#pragma omp declare target", + "#pragma omp end declare target"); + vec_safe_truncate (current_omp_declare_target_attribute, 0); } if (current_omp_begin_assumes) { if (!errorcount) - error ("%<#pragma omp begin assumes%> without corresponding " - "%<#pragma omp end assumes%>"); + error ("%qs without corresponding %qs", + "#pragma omp begin assumes", "#pragma omp end assumes"); current_omp_begin_assumes = 0; } } @@ -16818,8 +16822,8 @@ c_parser_omp_clause_device_type (c_parser *parser, tree list) else goto invalid_kind; - /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, - "device_type"); */ + check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, + "device_type"); c_parser_consume_token (parser); parens.skip_until_found_close (parser); c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE); @@ -22351,7 +22355,8 @@ c_parser_omp_declare_target (c_parser *parser) else { c_parser_skip_to_pragma_eol (parser); - current_omp_declare_target_attribute++; + c_omp_declare_target_attr attr = { -1 }; + vec_safe_push (current_omp_declare_target_attribute, attr); return; } for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) @@ -22429,12 +22434,17 @@ c_parser_omp_declare_target (c_parser *parser) } } if (device_type && only_device_type) - warning_at (OMP_CLAUSE_LOCATION (clauses), 0, - "directive with only %<device_type%> clauses ignored"); + error_at (OMP_CLAUSE_LOCATION (clauses), + "directive with only %<device_type%> clause"); } /* OpenMP 5.1 - #pragma omp begin assumes clauses[optseq] new-line */ + #pragma omp begin assumes clauses[optseq] new-line + + #pragma omp begin declare target clauses[optseq] new-line */ + +#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) static void c_parser_omp_begin (c_parser *parser) @@ -22443,7 +22453,33 @@ c_parser_omp_begin (c_parser *parser) c_parser_consume_pragma (parser); if (c_parser_next_token_is (parser, CPP_NAME)) p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (strcmp (p, "assumes") == 0) + if (strcmp (p, "declare") == 0) + { + c_parser_consume_token (parser); + p = ""; + if (c_parser_next_token_is (parser, CPP_NAME)) + p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp (p, "target") == 0) + { + c_parser_consume_token (parser); + tree clauses + = c_parser_omp_all_clauses (parser, + OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK, + "#pragma omp begin declare target"); + int device_type = 0; + for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) + device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); + c_omp_declare_target_attr attr = { device_type }; + vec_safe_push (current_omp_declare_target_attribute, attr); + } + else + { + c_parser_error (parser, "expected %<target%>"); + c_parser_skip_to_pragma_eol (parser); + } + } + else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_omp_assumption_clauses (parser, false); @@ -22451,7 +22487,7 @@ c_parser_omp_begin (c_parser *parser) } else { - c_parser_error (parser, "expected %<assumes%>"); + c_parser_error (parser, "expected %<declare target%> or %<assumes%>"); c_parser_skip_to_pragma_eol (parser); } } @@ -22484,19 +22520,20 @@ c_parser_omp_end (c_parser *parser) return; } c_parser_skip_to_pragma_eol (parser); - if (!current_omp_declare_target_attribute) + if (!vec_safe_length (current_omp_declare_target_attribute)) error_at (loc, "%<#pragma omp end declare target%> without " - "corresponding %<#pragma omp declare target%>"); + "corresponding %<#pragma omp declare target%> or " + "%<#pragma omp begin declare target%>"); else - current_omp_declare_target_attribute--; + current_omp_declare_target_attribute->pop (); } else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_skip_to_pragma_eol (parser); if (!current_omp_begin_assumes) - error_at (loc, "%<#pragma omp end assumes%> without " - "corresponding %<#pragma omp begin assumes%>"); + error_at (loc, "%qs without corresponding %qs", + "#pragma omp end assumes", "#pragma omp begin assumes"); else current_omp_begin_assumes--; } |