Improve checks on C2x fallthrough attribute
diff mbox series

Message ID alpine.DEB.2.21.1911150133430.10087@digraph.polyomino.org.uk
State New
Headers show
Series
  • Improve checks on C2x fallthrough attribute
Related show

Commit Message

Joseph Myers Nov. 15, 2019, 1:34 a.m. UTC
When adding C2x attribute support, some [[fallthrough]] support
appeared as a side-effect because of code for that attribute going
through separate paths from the normal attribute handling.

However, going through those paths without the normal attribute
handlers meant that certain checks, such as for the invalid usage
[[fallthrough()]], did not operate.  This patch improves checks by
adding this attribute to the standard attribute table, so that the
parser knows it expects no arguments, along with adding an explicit
check for "[[fallthrough]];" attribute-declarations at top level.  As
with other attributes, there are still cases where warnings should be
pedwarns because C2x constraints are violated, but this patch improves
the attribute handling.

Bootstrapped with no regressions on x86_64-pc-linux-gnu.  Applied to 
mainline.

gcc/c:
2019-11-15  Joseph Myers  <joseph@codesourcery.com>

	* c-decl.c (std_attribute_table): Add fallthrough.
	* c-parser.c (c_parser_declaration_or_fndef): Diagnose fallthrough
	attribute at top level.

gcc/c-family:
2019-11-15  Joseph Myers  <joseph@codesourcery.com>

	* c-attribs.c (handle_fallthrough_attribute): Remove static.
	* c-common.h (handle_fallthrough_attribute): Declare.

gcc/testsuite:
2019-11-15  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/c2x-attr-fallthrough-2.c,
	gcc.dg/c2x-attr-fallthrough-3.c: New tests.

Patch
diff mbox series

Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 278268)
+++ gcc/c/c-decl.c	(working copy)
@@ -4343,6 +4343,8 @@  const struct attribute_spec std_attribute_table[]
        affects_type_identity, handler, exclude } */
   { "deprecated", 0, 1, false, false, false, false,
     handle_deprecated_attribute, NULL },
+  { "fallthrough", 0, 0, false, false, false, false,
+    handle_fallthrough_attribute, NULL },
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
 };
 
Index: gcc/c/c-parser.c
===================================================================
--- gcc/c/c-parser.c	(revision 278268)
+++ gcc/c/c-parser.c	(working copy)
@@ -1927,9 +1927,15 @@  c_parser_declaration_or_fndef (c_parser *parser, b
 	{
 	  if (fallthru_attr_p != NULL)
 	    *fallthru_attr_p = true;
-	  tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
-						  void_type_node, 0);
-	  add_stmt (fn);
+	  if (nested)
+	    {
+	      tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
+						      void_type_node, 0);
+	      add_stmt (fn);
+	    }
+	  else
+	    pedwarn (here, OPT_Wattributes,
+		     "%<fallthrough%> attribute at top level");
 	}
       else if (empty_ok && !(have_attrs
 			     && specs->non_std_attrs_seen_p))
Index: gcc/c-family/c-attribs.c
===================================================================
--- gcc/c-family/c-attribs.c	(revision 278268)
+++ gcc/c-family/c-attribs.c	(working copy)
@@ -144,7 +144,6 @@  static tree handle_simd_attribute (tree *, tree, t
 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
 						 bool *);
 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
-static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
 						       int, bool *);
 static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
@@ -4114,7 +4113,7 @@  handle_designated_init_attribute (tree *node, tree
 /* Handle a "fallthrough" attribute; arguments as in struct
    attribute_spec.handler.  */
 
-static tree
+tree
 handle_fallthrough_attribute (tree *, tree name, tree, int,
 			      bool *no_add_attrs)
 {
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 278268)
+++ gcc/c-family/c-common.h	(working copy)
@@ -1359,6 +1359,7 @@  extern void warn_for_multistatement_macros (locati
 extern bool attribute_takes_identifier_p (const_tree);
 extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+extern tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
 extern int parse_tm_stmt_attr (tree, int);
 extern int tm_attr_to_mask (tree);
 extern tree tm_mask_to_attr (int);
Index: gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c
===================================================================
--- gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c	(working copy)
@@ -0,0 +1,35 @@ 
+/* Test C2x attribute syntax.  Invalid use of fallthrough attribute.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wextra" } */
+
+[[fallthrough]]; /* { dg-error "'fallthrough' attribute at top level" } */
+
+int [[fallthrough]] x; /* { dg-warning "ignored" } */
+/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+
+int g () [[fallthrough]]; /* { dg-warning "ignored" } */
+/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+
+int
+f (int a)
+{
+  [[fallthrough]] int b = 2; /* { dg-warning "not followed by|ignored" } */
+  switch (a)
+    {
+    case 1:
+      b = 1; /* { dg-warning "may fall through" } */
+    case 2:
+      b = 2; /* { dg-warning "may fall through" } */
+      [[fallthrough()]]; /* { dg-error "does not take any arguments" } */
+    case 3:
+      b += 7;
+      break;
+    case 4:
+      b = 4; /* { dg-warning "may fall through" } */
+      [[fallthrough(1)]]; /* { dg-error "does not take any arguments|expected" } */
+    case 5:
+      b += 5;
+      break;
+    }
+  [[fallthrough]] return b; /* { dg-warning "ignored" } */
+}
Index: gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c
===================================================================
--- gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* Test C2x attribute syntax.  Invalid use of fallthrough attribute
+   outside switch or in bad context inside switch.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wextra" } */
+
+int
+f (int a)
+{
+  [[fallthrough]]; /* { dg-error "invalid use of attribute 'fallthrough'" } */
+  switch (a)
+    {
+    case 1:
+      a++;
+      [[fallthrough]]; /* { dg-warning "attribute 'fallthrough' not preceding a case label or default label" } */
+      a++;
+    }
+  return a;
+}