* [committed] c: C2x attributes fixes and updates
@ 2022-08-31 22:25 Joseph Myers
0 siblings, 0 replies; only message in thread
From: Joseph Myers @ 2022-08-31 22:25 UTC (permalink / raw)
To: gcc-patches
Implement some changes to the currently supported C2x standard
attributes that have been made to the specification since they were
first implemented in GCC, and some consequent changes:
* maybe_unused is now supported on labels. In fact that was already
accidentally supported in GCC as a result of sharing the
implementation with __attribute__ ((unused)), but needed to be
covered in the tests.
* As part of the support for maybe_unused on labels, its
__has_c_attribute value changed.
* The issue of maybe_unused accidentally being already supported on
labels showed up the lack of tests for other standard attributes
being incorrectly applied to labels; add such tests.
* Use of fallthrough or nodiscard attributes on labels already
properly resulted in a pedwarn. For the deprecated attribute,
however, there was only a warning, and the wording "'deprecated'
attribute ignored for 'void'" included an unhelpful "for 'void'".
Arrange for the case of the deprecated attribute on a label to be
checked for separately and result in a pedwarn. As with
inappropriate uses of fallthrough (see commit
6c80b1b56dec2691436f3e2676e3d1b105b01b89), it seems reasonable for
this pedwarn to apply regardless of whether [[]] or __attribute__
was used and regardless of whether C or C++ is being compiled.
* Attributes on case or default labels (the standard syntax supports
attributes on all kinds of labels) were quietly ignored, whether or
not appropriate for use in such a context, because they weren't
passed to decl_attributes at all. (Note where I'm changing the
do_case prototype that such a function is actually only defined in
the C front end, not for C++, despite the declaration being in
c-common.h.)
* A recent change as part of the editorial review in preparation for
the C2x CD ballot has changed the __has_c_attribute value for
fallthrough to 201910 to reflect when that attribute was actually
voted into the working draft.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/c-family/
* c-attribs.cc (handle_deprecated_attribute): Check and pedwarn
for LABEL_DECL.
* c-common.cc (c_add_case_label): Add argument ATTRS. Call
decl_attributes.
* c-common.h (do_case, c_add_case_label): Update declarations.
* c-lex.cc (c_common_has_attribute): For C, produce a result of
201910 for fallthrough and 202106 for maybe_unused.
gcc/c/
* c-parser.cc (c_parser_label): Pass attributes to do_case.
* c-typeck.cc (do_case): Add argument ATTRS. Pass it to
c_add_case_label.
gcc/testsuite/
* gcc.dg/c2x-attr-deprecated-2.c, gcc.dg/c2x-attr-fallthrough-2.c,
gcc.dg/c2x-attr-maybe_unused-1.c, gcc.dg/c2x-attr-nodiscard-2.c:
Add tests of attributes on labels.
* gcc.dg/c2x-has-c-attribute-2.c: Update expected results for
maybe_unused and fallthrough.
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index e4f1d3542f3..8bb80e251dc 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -4163,6 +4163,13 @@ handle_deprecated_attribute (tree *node, tree name,
|| TREE_CODE (decl) == CONST_DECL
|| objc_method_decl (TREE_CODE (decl)))
TREE_DEPRECATED (decl) = 1;
+ else if (TREE_CODE (decl) == LABEL_DECL)
+ {
+ pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
+ name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
else
warn = 1;
}
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 71fe7305369..1eb842e1c7b 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -5068,11 +5068,12 @@ case_compare (splay_tree_key k1, splay_tree_key k2)
CASES is a tree containing all the case ranges processed so far;
COND is the condition for the switch-statement itself.
Returns the CASE_LABEL_EXPR created, or ERROR_MARK_NODE if no
- CASE_LABEL_EXPR is created. */
+ CASE_LABEL_EXPR is created. ATTRS are the attributes to be applied
+ to the label. */
tree
c_add_case_label (location_t loc, splay_tree cases, tree cond,
- tree low_value, tree high_value)
+ tree low_value, tree high_value, tree attrs)
{
tree type;
tree label;
@@ -5081,6 +5082,7 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond,
/* Create the LABEL_DECL itself. */
label = create_artificial_label (loc);
+ decl_attributes (&label, attrs, 0);
/* If there was an error processing the switch condition, bail now
before we get more confused. */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index e7b0fd1309d..64fe14b66fe 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1018,7 +1018,7 @@ extern void c_parse_final_cleanups (void);
/* True iff TYPE is cv decltype(nullptr). */
#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)
-extern tree do_case (location_t, tree, tree);
+extern tree do_case (location_t, tree, tree, tree);
extern tree build_stmt (location_t, enum tree_code, ...);
extern tree build_real_imag_expr (location_t, enum tree_code, tree);
@@ -1046,7 +1046,8 @@ extern tree boolean_increment (enum tree_code, tree);
extern int case_compare (splay_tree_key, splay_tree_key);
-extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree);
+extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree,
+ tree = NULL_TREE);
extern bool c_switch_covers_all_cases_p (splay_tree, tree);
extern bool c_block_may_fallthru (const_tree);
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index 0b6f94e18a8..417ba3e38ba 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -381,12 +381,14 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax)
}
else
{
- if (is_attribute_p ("deprecated", attr_name)
- || is_attribute_p ("maybe_unused", attr_name)
- || is_attribute_p ("fallthrough", attr_name))
+ if (is_attribute_p ("deprecated", attr_name))
result = 201904;
+ else if (is_attribute_p ("fallthrough", attr_name))
+ result = 201910;
else if (is_attribute_p ("nodiscard", attr_name))
result = 202003;
+ else if (is_attribute_p ("maybe_unused", attr_name))
+ result = 202106;
}
if (result)
attr_name = NULL_TREE;
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0fe2ff55040..95f4ead54a0 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -5912,14 +5912,14 @@ c_parser_label (c_parser *parser, tree std_attrs)
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
- label = do_case (loc1, exp1, NULL_TREE);
+ label = do_case (loc1, exp1, NULL_TREE, std_attrs);
}
else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
c_parser_consume_token (parser);
exp2 = c_parser_expr_no_commas (parser, NULL).value;
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (loc1, exp1, exp2);
+ label = do_case (loc1, exp1, exp2, std_attrs);
}
else
c_parser_error (parser, "expected %<:%> or %<...%>");
@@ -5928,7 +5928,7 @@ c_parser_label (c_parser *parser, tree std_attrs)
{
c_parser_consume_token (parser);
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (loc1, NULL_TREE, NULL_TREE);
+ label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
}
else
{
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ee891ee33c2..e4d58e318f8 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -11172,10 +11172,10 @@ c_start_switch (location_t switch_loc,
return add_stmt (cs->switch_stmt);
}
-/* Process a case label at location LOC. */
+/* Process a case label at location LOC, with attributes ATTRS. */
tree
-do_case (location_t loc, tree low_value, tree high_value)
+do_case (location_t loc, tree low_value, tree high_value, tree attrs)
{
tree label = NULL_TREE;
@@ -11211,7 +11211,7 @@ do_case (location_t loc, tree low_value, tree high_value)
label = c_add_case_label (loc, c_switch_stack->cases,
SWITCH_STMT_COND (c_switch_stack->switch_stmt),
- low_value, high_value);
+ low_value, high_value, attrs);
if (label == error_mark_node)
label = NULL_TREE;
return label;
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-deprecated-2.c b/gcc/testsuite/gcc.dg/c2x-attr-deprecated-2.c
index 44f2cc9bd13..7c01317d8fa 100644
--- a/gcc/testsuite/gcc.dg/c2x-attr-deprecated-2.c
+++ b/gcc/testsuite/gcc.dg/c2x-attr-deprecated-2.c
@@ -3,7 +3,8 @@
/* { dg-options "-std=c2x -pedantic-errors" } */
/* This attribute is not valid in most cases on types other than their
- definitions, or on statements, or as an attribute-declaration. */
+ definitions, or on labels, or on statements, or as an
+ attribute-declaration. */
[[deprecated]]; /* { dg-error "ignored" } */
@@ -21,4 +22,10 @@ f (void)
int a;
[[deprecated]]; /* { dg-error "ignored" } */
[[deprecated]] a = 1; /* { dg-error "ignored" } */
+ [[deprecated]] label: ; /* { dg-error "ignored" } */
+ switch (var)
+ {
+ [[deprecated]] case 1: ; /* { dg-error "ignored" } */
+ [[deprecated]] default: ; /* { dg-error "ignored" } */
+ }
}
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c
index 9d6995938cd..b65bcbef709 100644
--- a/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c
+++ b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c
@@ -33,6 +33,10 @@ f (int a)
case 5:
b += 5;
break;
+ [[fallthrough]] case 6: break; /* { dg-error "ignored" } */
+ [[fallthrough]] default: break; /* { dg-error "ignored" } */
}
[[fallthrough]] return b; /* { dg-error "ignored" } */
+ [[fallthrough]] label: ; /* { dg-error "ignored" } */
+ goto label;
}
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c
index 477f30dbd44..7090a3f30e1 100644
--- a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c
+++ b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c
@@ -14,7 +14,9 @@ g ([[maybe_unused]] int x, int y)
[[maybe_unused]] int a;
int b [[__maybe_unused__]];
int c [[maybe_unused]];
+ [[__maybe_unused__]] label1:
c = y;
+ [[maybe_unused]] label2:
return y;
}
@@ -29,3 +31,14 @@ union [[maybe_unused]] u { int x; };
enum [[maybe_unused]] eu { E2 };
union u2 { [[maybe_unused]] int a; int b [[maybe_unused]]; } y;
+
+void
+g2 (int x)
+{
+ switch (x)
+ {
+ [[maybe_unused]] case 1: ;
+ [[__maybe_unused__]] case 2: ;
+ [[maybe_unused]] default: ;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-attr-nodiscard-2.c b/gcc/testsuite/gcc.dg/c2x-attr-nodiscard-2.c
index 45c4d50dee0..0ed2ebe92ff 100644
--- a/gcc/testsuite/gcc.dg/c2x-attr-nodiscard-2.c
+++ b/gcc/testsuite/gcc.dg/c2x-attr-nodiscard-2.c
@@ -39,4 +39,10 @@ f (void)
[[nodiscard ("reason")]] int b = 1; /* { dg-error "can only be applied" } */
[[nodiscard]]; /* { dg-error "ignored" } */
[[nodiscard]] a = 1; /* { dg-error "ignored" } */
+ [[nodiscard]] label: ; /* { dg-error "can only be applied" } */
+ switch (var)
+ {
+ [[nodiscard]] case 1: ; /* { dg-error "can only be applied" } */
+ [[nodiscard]] default: ; /* { dg-error "can only be applied" } */
+ }
}
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
index d6c4c6de509..6a379e9db4f 100644
--- a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
@@ -10,11 +10,11 @@
#error "bad result for __nodiscard__"
#endif
-#if __has_c_attribute(maybe_unused) != 201904L
+#if __has_c_attribute(maybe_unused) != 202106L
#error "bad result for maybe_unused"
#endif
-#if __has_c_attribute(__maybe_unused__) != 201904L
+#if __has_c_attribute(__maybe_unused__) != 202106L
#error "bad result for __maybe_unused__"
#endif
@@ -26,11 +26,11 @@
#error "bad result for __deprecated__"
#endif
-#if __has_c_attribute (fallthrough) != 201904L
+#if __has_c_attribute (fallthrough) != 201910L
#error "bad result for fallthrough"
#endif
-#if __has_c_attribute (__fallthrough__) != 201904L
+#if __has_c_attribute (__fallthrough__) != 201910L
#error "bad result for __fallthrough__"
#endif
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-08-31 22:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-31 22:25 [committed] c: C2x attributes fixes and updates Joseph Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).