Skip to content

Commit fa1427a

Browse files
amomchilovkddnewton
authored andcommitted
[ruby/prism] Enable implicit fall-through errors
ruby/prism@03797b84d3
1 parent b0e64fc commit fa1427a

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

prism/defines.h

+12
Original file line numberDiff line numberDiff line change
@@ -243,4 +243,16 @@
243243
#define PRISM_UNLIKELY(x) (x)
244244
#endif
245245

246+
/**
247+
* We use -Wimplicit-fallthrough to guard potentially unintended fall-through between cases of a switch.
248+
* Use PRISM_FALLTHROUGH to explicitly annotate cases where the fallthrough is intentional.
249+
*/
250+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L // C23 or later
251+
#define PRISM_FALLTHROUGH [[fallthrough]];
252+
#elif defined(__GNUC__) || defined(__clang__)
253+
#define PRISM_FALLTHROUGH __attribute__((fallthrough));
254+
#elif defined(_MSC_VER)
255+
#define PRISM_FALLTHROUGH __fallthrough;
256+
#endif
257+
246258
#endif

prism/prism.c

+27-26
Original file line numberDiff line numberDiff line change
@@ -9120,7 +9120,7 @@ lex_global_variable(pm_parser_t *parser) {
91209120
case '-':
91219121
parser->current.end++;
91229122
allow_multiple = false;
9123-
/* fallthrough */
9123+
PRISM_FALLTHROUGH
91249124
default: {
91259125
size_t width;
91269126

@@ -10049,8 +10049,8 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expre
1004910049
escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags));
1005010050
return;
1005110051
}
10052+
PRISM_FALLTHROUGH
1005210053
}
10053-
/* fallthrough */
1005410054
default: {
1005510055
if ((flags & (PM_ESCAPE_FLAG_CONTROL | PM_ESCAPE_FLAG_META)) && !char_is_ascii_printable(peeked)) {
1005610056
size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
@@ -10759,7 +10759,7 @@ parser_lex(pm_parser_t *parser) {
1075910759

1076010760
lexed_comment = true;
1076110761
}
10762-
/* fallthrough */
10762+
PRISM_FALLTHROUGH
1076310763
case '\r':
1076410764
case '\n': {
1076510765
parser->semantic_token_seen = semantic_token_seen & 0x1;
@@ -10801,7 +10801,7 @@ parser_lex(pm_parser_t *parser) {
1080110801
parser->current.type = PM_TOKEN_NEWLINE;
1080210802
return;
1080310803
}
10804-
/* fallthrough */
10804+
PRISM_FALLTHROUGH
1080510805
case PM_IGNORED_NEWLINE_ALL:
1080610806
if (!lexed_comment) parser_lex_ignored_newline(parser);
1080710807
lexed_comment = false;
@@ -11816,7 +11816,7 @@ parser_lex(pm_parser_t *parser) {
1181611816
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped carriage return");
1181711817
break;
1181811818
}
11819-
/* fallthrough */
11819+
PRISM_FALLTHROUGH
1182011820
default:
1182111821
PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "backslash");
1182211822
break;
@@ -12013,7 +12013,7 @@ parser_lex(pm_parser_t *parser) {
1201312013
pm_token_buffer_push_byte(&token_buffer, '\r');
1201412014
break;
1201512015
}
12016-
/* fallthrough */
12016+
PRISM_FALLTHROUGH
1201712017
case '\n':
1201812018
pm_token_buffer_push_byte(&token_buffer, '\n');
1201912019

@@ -12200,7 +12200,7 @@ parser_lex(pm_parser_t *parser) {
1220012200
pm_regexp_token_buffer_escape(parser, &token_buffer);
1220112201
token_buffer.base.cursor = breakpoint;
1220212202

12203-
/* fallthrough */
12203+
PRISM_FALLTHROUGH
1220412204
case '\n':
1220512205
// If we've hit a newline, then we need to track that in
1220612206
// the list of newlines.
@@ -12242,7 +12242,7 @@ parser_lex(pm_parser_t *parser) {
1224212242
pm_token_buffer_push_byte(&token_buffer.base, '\r');
1224312243
break;
1224412244
}
12245-
/* fallthrough */
12245+
PRISM_FALLTHROUGH
1224612246
case '\n':
1224712247
if (parser->heredoc_end) {
1224812248
// ... if we are on the same line as a heredoc,
@@ -12450,7 +12450,7 @@ parser_lex(pm_parser_t *parser) {
1245012450
pm_token_buffer_escape(parser, &token_buffer);
1245112451
token_buffer.cursor = breakpoint;
1245212452

12453-
/* fallthrough */
12453+
PRISM_FALLTHROUGH
1245412454
case '\n':
1245512455
// When we hit a newline, we need to flush any potential
1245612456
// heredocs. Note that this has to happen after we check
@@ -12495,7 +12495,7 @@ parser_lex(pm_parser_t *parser) {
1249512495
pm_token_buffer_push_byte(&token_buffer, '\r');
1249612496
break;
1249712497
}
12498-
/* fallthrough */
12498+
PRISM_FALLTHROUGH
1249912499
case '\n':
1250012500
if (!lex_mode->as.string.interpolation) {
1250112501
pm_token_buffer_push_byte(&token_buffer, '\\');
@@ -12703,7 +12703,7 @@ parser_lex(pm_parser_t *parser) {
1270312703
pm_token_buffer_escape(parser, &token_buffer);
1270412704
token_buffer.cursor = breakpoint;
1270512705

12706-
/* fallthrough */
12706+
PRISM_FALLTHROUGH
1270712707
case '\n': {
1270812708
if (parser->heredoc_end != NULL && (parser->heredoc_end > breakpoint)) {
1270912709
parser_flush_heredoc_end(parser);
@@ -12803,7 +12803,7 @@ parser_lex(pm_parser_t *parser) {
1280312803
pm_token_buffer_push_byte(&token_buffer, '\r');
1280412804
break;
1280512805
}
12806-
/* fallthrough */
12806+
PRISM_FALLTHROUGH
1280712807
case '\n':
1280812808
pm_token_buffer_push_byte(&token_buffer, '\\');
1280912809
pm_token_buffer_push_byte(&token_buffer, '\n');
@@ -12823,7 +12823,7 @@ parser_lex(pm_parser_t *parser) {
1282312823
pm_token_buffer_push_byte(&token_buffer, '\r');
1282412824
break;
1282512825
}
12826-
/* fallthrough */
12826+
PRISM_FALLTHROUGH
1282712827
case '\n':
1282812828
// If we are in a tilde here, we should
1282912829
// break out of the loop and return the
@@ -13545,7 +13545,7 @@ parse_target(pm_parser_t *parser, pm_node_t *target, bool multiple, bool splat_p
1354513545
return (pm_node_t *) pm_index_target_node_create(parser, call);
1354613546
}
1354713547
}
13548-
/* fallthrough */
13548+
PRISM_FALLTHROUGH
1354913549
default:
1355013550
// In this case we have a node that we don't know how to convert
1355113551
// into a target. We need to treat it as an error. For now, we'll
@@ -13627,7 +13627,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1362713627
case PM_BACK_REFERENCE_READ_NODE:
1362813628
case PM_NUMBERED_REFERENCE_READ_NODE:
1362913629
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, target, PM_ERR_WRITE_TARGET_READONLY);
13630-
/* fallthrough */
13630+
PRISM_FALLTHROUGH
1363113631
case PM_GLOBAL_VARIABLE_READ_NODE: {
1363213632
pm_global_variable_write_node_t *node = pm_global_variable_write_node_create(parser, target, operator, value);
1363313633
pm_node_destroy(parser, target);
@@ -13769,7 +13769,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1376913769
// is no way for us to attach it to the tree at this point.
1377013770
pm_node_destroy(parser, value);
1377113771
}
13772-
/* fallthrough */
13772+
PRISM_FALLTHROUGH
1377313773
default:
1377413774
// In this case we have a node that we don't know how to convert into a
1377513775
// target. We need to treat it as an error. For now, we'll mark it as an
@@ -14289,7 +14289,7 @@ parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_for
1428914289
}
1429014290
}
1429114291
}
14292-
/* fallthrough */
14292+
PRISM_FALLTHROUGH
1429314293
default: {
1429414294
if (argument == NULL) {
1429514295
argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, true, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1));
@@ -16177,7 +16177,7 @@ parse_operator_symbol_name(const pm_token_t *name) {
1617716177
case PM_TOKEN_TILDE:
1617816178
case PM_TOKEN_BANG:
1617916179
if (name->end[-1] == '@') return name->end - 1;
16180-
/* fallthrough */
16180+
PRISM_FALLTHROUGH
1618116181
default:
1618216182
return name->end;
1618316183
}
@@ -17149,7 +17149,7 @@ parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node
1714917149
break;
1715017150
}
1715117151
}
17152-
/* fallthrough */
17152+
PRISM_FALLTHROUGH
1715317153
default: {
1715417154
// If we get anything else, then this is an error. For this we'll
1715517155
// create a missing node for the value and create an assoc node for
@@ -17645,7 +17645,7 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
1764517645
break;
1764617646
}
1764717647
}
17648-
/* fallthrough */
17648+
PRISM_FALLTHROUGH
1764917649
default:
1765017650
node = parse_pattern_primitives(parser, captures, NULL, diag_id, (uint16_t) (depth + 1));
1765117651
break;
@@ -18775,7 +18775,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1877518775
pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT);
1877618776
}
1877718777
}
18778-
/* fallthrough */
18778+
PRISM_FALLTHROUGH
1877918779
default:
1878018780
return (pm_node_t *) pm_alias_method_node_create(parser, &keyword, new_name, old_name);
1878118781
}
@@ -19303,7 +19303,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1930319303
case PM_TOKEN_CLASS_VARIABLE:
1930419304
case PM_TOKEN_GLOBAL_VARIABLE:
1930519305
valid_name = false;
19306-
/* fallthrough */
19306+
PRISM_FALLTHROUGH
1930719307
case PM_TOKEN_CONSTANT:
1930819308
case PM_TOKEN_KEYWORD_NIL:
1930919309
case PM_TOKEN_KEYWORD_SELF:
@@ -21114,7 +21114,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2111421114
pm_parser_local_add_location(parser, call_node->message_loc.start, call_node->message_loc.end, 0);
2111521115
}
2111621116
}
21117-
/* fallthrough */
21117+
PRISM_FALLTHROUGH
2111821118
case PM_CASE_WRITABLE: {
2111921119
parser_lex(parser);
2112021120
pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) ? PM_BINDING_POWER_MULTI_ASSIGNMENT + 1 : binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, (uint16_t) (depth + 1));
@@ -21160,7 +21160,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2116021160
case PM_BACK_REFERENCE_READ_NODE:
2116121161
case PM_NUMBERED_REFERENCE_READ_NODE:
2116221162
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY);
21163-
/* fallthrough */
21163+
PRISM_FALLTHROUGH
2116421164
case PM_GLOBAL_VARIABLE_READ_NODE: {
2116521165
parser_lex(parser);
2116621166

@@ -21278,7 +21278,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2127821278
case PM_BACK_REFERENCE_READ_NODE:
2127921279
case PM_NUMBERED_REFERENCE_READ_NODE:
2128021280
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY);
21281-
/* fallthrough */
21281+
PRISM_FALLTHROUGH
2128221282
case PM_GLOBAL_VARIABLE_READ_NODE: {
2128321283
parser_lex(parser);
2128421284

@@ -21406,7 +21406,7 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
2140621406
case PM_BACK_REFERENCE_READ_NODE:
2140721407
case PM_NUMBERED_REFERENCE_READ_NODE:
2140821408
PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY);
21409-
/* fallthrough */
21409+
PRISM_FALLTHROUGH
2141021410
case PM_GLOBAL_VARIABLE_READ_NODE: {
2141121411
parser_lex(parser);
2141221412

@@ -22043,6 +22043,7 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2204322043
if (pm_symbol_node_label_p(node)) {
2204422044
return node;
2204522045
}
22046+
break;
2204622047
default:
2204722048
break;
2204822049
}

prism/regexp.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,7 @@ pm_regexp_parse_group(pm_regexp_parser_t *parser, uint16_t depth) {
599599
// If we hit a -, then we're done parsing options.
600600
if (*parser->cursor != '-') break;
601601

602-
// Otherwise, fallthrough to the - case.
603-
/* fallthrough */
602+
PRISM_FALLTHROUGH
604603
case '-':
605604
parser->cursor++;
606605
while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ':' && *parser->cursor != ')') {
@@ -712,7 +711,7 @@ pm_regexp_parse_item(pm_regexp_parser_t *parser, uint16_t depth) {
712711
if (!pm_regexp_char_find(parser, '\n')) parser->cursor = parser->end;
713712
return true;
714713
}
715-
/* fallthrough */
714+
PRISM_FALLTHROUGH
716715
default: {
717716
size_t width;
718717
if (!parser->encoding_changed) {

0 commit comments

Comments
 (0)