diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index e4f1d3542f37..8bb80e251dc2 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 71fe7305369b..1eb842e1c7ba 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 e7b0fd1309d3..64fe14b66fe8 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 0b6f94e18a82..417ba3e38baf 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 0fe2ff55040d..95f4ead54a06 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 ee891ee33c24..e4d58e318f88 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 44f2cc9bd138..7c01317d8fa2 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 9d6995938cd6..b65bcbef7098 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 477f30dbd44d..7090a3f30e17 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 45c4d50dee0a..0ed2ebe92ffe 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 d6c4c6de509c..6a379e9db4f5 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