diff --git a/regression/ansi-c/gcc_attributes13/main.c b/regression/ansi-c/gcc_attributes13/main.c index 64230094d9d..74cff9de533 100644 --- a/regression/ansi-c/gcc_attributes13/main.c +++ b/regression/ansi-c/gcc_attributes13/main.c @@ -7,13 +7,20 @@ int main() int x; switch(x) { - case 1: - x = 2; + case 1: + x = 2; #ifdef __GNUC__ - __attribute__((fallthrough)); + __attribute__((fallthrough)); #endif - case 2: - x = 3; + case 2: + { + x = 3; +#ifdef __GNUC__ + __attribute__((__fallthrough__)); +#endif + } + case 3: + break; } return 0; diff --git a/src/ansi-c/parser.y b/src/ansi-c/parser.y index b719b1a488f..6665ca6279f 100644 --- a/src/ansi-c/parser.y +++ b/src/ansi-c/parser.y @@ -1655,6 +1655,11 @@ gcc_attribute: { init($$); } + | TOK_GCC_ATTRIBUTE_FALLTHROUGH + { + // attribute ignored + init($$); + } | gcc_type_attribute ; @@ -2320,19 +2325,7 @@ declaration_statement: ; labeled_statement: - identifier_or_typedef_name ':' gcc_attribute_specifier ';' - { - /* Only semicolons permitted after the attribute: - https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html */ - $$=$2; - statement($$, ID_label); - irep_idt identifier=PARSER.lookup_label(parser_stack($1).get(ID_C_base_name)); - parser_stack($$).set(ID_label, identifier); - // attribute ignored - statement($3, ID_skip); - mto($$, $3); - } - | identifier_or_typedef_name ':' statement + identifier_or_typedef_name ':' statement { $$=$2; statement($$, ID_label); @@ -2367,10 +2360,14 @@ labeled_statement: ; statement_attribute: - TOK_GCC_ATTRIBUTE '(' '(' TOK_GCC_ATTRIBUTE_FALLTHROUGH ')' ')' ';' labeled_statement + gcc_attribute_specifier ';' { - // attribute ignored - $$=$8; + // Really should only be TOK_GCC_ATTRIBUTE_FALLTHROUGH or a label + // attribute. Only semicolons permitted after the attribute: + // https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html + // We ignore all such attributes. + $$=$1; + statement($$, ID_skip); } ; diff --git a/src/ansi-c/scanner.l b/src/ansi-c/scanner.l index f7d23af3f1f..79b87f1a833 100644 --- a/src/ansi-c/scanner.l +++ b/src/ansi-c/scanner.l @@ -1704,7 +1704,8 @@ __decltype { if(PARSER.cpp98 && "destructor" | "__destructor__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_DESTRUCTOR; } -"fallthrough" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_FALLTHROUGH; } +"fallthrough" | +"__fallthrough__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_FALLTHROUGH; } "used" | "__used__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_USED; }