aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-10-04 12:04:54 +0200
committerMartin Liska <mliska@suse.cz>2022-10-04 12:04:54 +0200
commitda0970e441345f8349522ff1abac5c223044ebb1 (patch)
tree17c2091a83c584a1eae4f8e219a460f85c5d3fd8 /gcc/c
parent54f3cfaf3a6f50958c71d79c85206a6c722e1a22 (diff)
parente886ebd17965d78f609b62479f4f48085108389c (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/c/c-decl.cc49
-rw-r--r--gcc/c/c-lang.h7
-rw-r--r--gcc/c/c-parser.cc75
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--;
}