From f8aea5e37d12e09fef68b854a190f71d6b39e11f Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 15 Nov 2019 01:33:37 +0000 Subject: [PATCH] Improve checks on C2x fallthrough attribute. 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. gcc/c: * 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: * c-attribs.c (handle_fallthrough_attribute): Remove static. * c-common.h (handle_fallthrough_attribute): Declare. gcc/testsuite: * gcc.dg/c2x-attr-fallthrough-2.c, gcc.dg/c2x-attr-fallthrough-3.c: New tests. From-SVN: r278273 --- gcc/c-family/ChangeLog | 5 +++ gcc/c-family/c-attribs.c | 3 +- gcc/c-family/c-common.h | 1 + gcc/c/ChangeLog | 6 ++++ gcc/c/c-decl.c | 2 ++ gcc/c/c-parser.c | 12 +++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c | 35 +++++++++++++++++++ gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c | 18 ++++++++++ 9 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c create mode 100644 gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 571cf2bc1b7..c7420f647d8 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2019-11-15 Joseph Myers + + * c-attribs.c (handle_fallthrough_attribute): Remove static. + * c-common.h (handle_fallthrough_attribute): Declare. + 2019-11-15 Joseph Myers * c-attribs.c (handle_deprecated_attribute): Remove static. diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 18b829f47fe..4a59cdff836 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -144,7 +144,6 @@ static tree handle_simd_attribute (tree *, tree, tree, int, bool *); 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 name, tree, int, /* 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) { diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index ad40c15d92f..f3478d39beb 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1359,6 +1359,7 @@ extern void warn_for_multistatement_macros (location_t, location_t, 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); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index fdc915329c8..c2cab579838 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2019-11-15 Joseph Myers + + * c-decl.c (std_attribute_table): Add fallthrough. + * c-parser.c (c_parser_declaration_or_fndef): Diagnose fallthrough + attribute at top level. + 2019-11-15 Joseph Myers * c-decl.c (std_attribute_table): New. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index a7f7c696788..98b71ea620b 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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 } }; diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 721158a2c3e..5b290bf7567 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1927,9 +1927,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, { 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, + "% attribute at top level"); } else if (empty_ok && !(have_attrs && specs->non_std_attrs_seen_p)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 17494d02032..8c6f8914804 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-11-15 Joseph Myers + + * gcc.dg/c2x-attr-fallthrough-2.c, + gcc.dg/c2x-attr-fallthrough-3.c: New tests. + 2019-11-15 Joseph Myers * gcc.dg/c2x-attr-deprecated-1.c, gcc.dg/c2x-attr-deprecated-2.c, diff --git a/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c new file mode 100644 index 00000000000..e396a60ea0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c new file mode 100644 index 00000000000..66fe820c315 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-attr-fallthrough-3.c @@ -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; +} -- 2.30.2