public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).