Skip to content

Commit bb2eb56

Browse files
committed
pythongh-121040: Use __attribute__((fallthrough))
Annotate explicitly "fall through" switch cases with a new _Py_FALLTHROUGH macro which uses __attribute__((fallthrough)) if available. Fix warnings when using -Wimplicit-fallthrough compiler flag.
1 parent 9e4a81f commit bb2eb56

27 files changed

+108
-88
lines changed

Include/pyport.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,4 +607,19 @@ extern "C" {
607607
# define _SGI_MP_SOURCE
608608
#endif
609609

610+
// Explicit fallthrough in switch case.
611+
// Example:
612+
//
613+
// switch(value)
614+
// case 1: _Py_FALLTHROUGH;
615+
// case 2: code; break;
616+
// }
617+
//
618+
// __attribute__((fallthrough)) was introduced in GCC 7.
619+
#if defined(__has_attribute) && __has_attribute(fallthrough)
620+
# define _Py_FALLTHROUGH __attribute__((fallthrough))
621+
#else
622+
# define _Py_FALLTHROUGH do { } while (0)
623+
#endif
624+
610625
#endif /* Py_PYPORT_H */

Modules/_csv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
731731
}
732732
/* normal character - handle as START_FIELD */
733733
self->state = START_FIELD;
734-
/* fallthru */
734+
_Py_FALLTHROUGH;
735735
case START_FIELD:
736736
/* expecting field */
737737
self->unquoted_field = true;
@@ -785,7 +785,7 @@ parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
785785
case AFTER_ESCAPED_CRNL:
786786
if (c == EOL)
787787
break;
788-
/*fallthru*/
788+
_Py_FALLTHROUGH;
789789

790790
case IN_FIELD:
791791
/* in unquoted field */

Modules/_ctypes/_ctypes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4074,7 +4074,7 @@ _build_callargs(ctypes_state *st, PyCFuncPtrObject *self, PyObject *argtypes,
40744074
case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
40754075
*pinoutmask |= (1 << i); /* mark as inout arg */
40764076
(*pnumretvals)++;
4077-
/* fall through */
4077+
_Py_FALLTHROUGH;
40784078
case 0:
40794079
case PARAMFLAG_FIN:
40804080
/* 'in' parameter. Copy it from inargs. */

Modules/_ctypes/stgdict.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,10 +485,11 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
485485
case FFI_TYPE_SINT16:
486486
case FFI_TYPE_SINT32:
487487
if (info->getfunc != _ctypes_get_fielddesc("c")->getfunc
488-
&& info->getfunc != _ctypes_get_fielddesc("u")->getfunc
489-
)
488+
&& info->getfunc != _ctypes_get_fielddesc("u")->getfunc)
489+
{
490490
break;
491-
/* else fall through */
491+
}
492+
_Py_FALLTHROUGH; /* else fall through */
492493
default:
493494
PyErr_Format(PyExc_TypeError,
494495
"bit fields not allowed for type %s",

Modules/_interpqueuesmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ handle_queue_error(int err, PyObject *mod, int64_t qid)
363363

364364
module_state *state;
365365
switch (err) {
366-
case ERR_QUEUE_ALLOC: // fall through
366+
case ERR_QUEUE_ALLOC: _Py_FALLTHROUGH;
367367
case ERR_QUEUES_ALLOC:
368368
PyErr_NoMemory();
369369
break;

Modules/_ssl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3472,8 +3472,8 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what)
34723472
}
34733473

34743474
switch(self->protocol) {
3475-
case PY_SSL_VERSION_TLS_CLIENT: /* fall through */
3476-
case PY_SSL_VERSION_TLS_SERVER: /* fall through */
3475+
case PY_SSL_VERSION_TLS_CLIENT: _Py_FALLTHROUGH;
3476+
case PY_SSL_VERSION_TLS_SERVER: _Py_FALLTHROUGH;
34773477
case PY_SSL_VERSION_TLS:
34783478
break;
34793479
default:

Modules/_struct.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,7 @@ whichtable(const char **pfmt)
13731373
}
13741374
default:
13751375
--*pfmt; /* Back out of pointer increment */
1376-
/* Fall through */
1376+
_Py_FALLTHROUGH;
13771377
case '@':
13781378
return native_table;
13791379
}
@@ -1475,7 +1475,7 @@ prepare_s(PyStructObject *self)
14751475
return -1;
14761476

14771477
switch (c) {
1478-
case 's': /* fall through */
1478+
case 's': _Py_FALLTHROUGH;
14791479
case 'p': len++; ncodes++; break;
14801480
case 'x': break;
14811481
default: len += num; if (num) ncodes++; break;

Modules/_testcapi/exceptions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ err_restore(PyObject *self, PyObject *args) {
3434
case 3:
3535
traceback = PyTuple_GetItem(args, 2);
3636
Py_INCREF(traceback);
37-
/* fall through */
37+
_Py_FALLTHROUGH;
3838
case 2:
3939
value = PyTuple_GetItem(args, 1);
4040
Py_INCREF(value);
41-
/* fall through */
41+
_Py_FALLTHROUGH;
4242
case 1:
4343
type = PyTuple_GetItem(args, 0);
4444
Py_INCREF(type);

Modules/cjkcodecs/_codecs_iso2022.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ jisx0213_encoder(const MultibyteCodec *codec, const Py_UCS4 *data,
806806
jisx0213_pair_encmap, JISX0213_ENCPAIRS);
807807
if (coded != DBCINV)
808808
return coded;
809-
/* fall through */
809+
_Py_FALLTHROUGH;
810810

811811
case -1: /* flush unterminated */
812812
*length = 1;

Modules/overlapped.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
923923
{
924924
break;
925925
}
926-
/* fall through */
926+
_Py_FALLTHROUGH;
927927
default:
928928
return SetFromWindowsErr(err);
929929
}

Modules/socketmodule.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,12 +1887,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
18871887

18881888
#ifdef AF_RDS
18891889
case AF_RDS:
1890-
/* RDS sockets use sockaddr_in: fall-through */
1890+
/* RDS sockets use sockaddr_in */
1891+
_Py_FALLTHROUGH;
18911892
#endif /* AF_RDS */
18921893

18931894
#ifdef AF_DIVERT
18941895
case AF_DIVERT:
1895-
/* FreeBSD divert(4) sockets use sockaddr_in: fall-through */
1896+
/* FreeBSD divert(4) sockets use sockaddr_in */
1897+
_Py_FALLTHROUGH;
18961898
#endif /* AF_DIVERT */
18971899

18981900
case AF_INET:
@@ -2214,7 +2216,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
22142216
switch (s->sock_proto) {
22152217
#ifdef CAN_RAW
22162218
case CAN_RAW:
2217-
/* fall-through */
2219+
_Py_FALLTHROUGH;
22182220
#endif
22192221
#ifdef CAN_BCM
22202222
case CAN_BCM:
@@ -2590,7 +2592,8 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
25902592

25912593
#ifdef AF_RDS
25922594
case AF_RDS:
2593-
/* RDS sockets use sockaddr_in: fall-through */
2595+
/* RDS sockets use sockaddr_in */
2596+
_Py_FALLTHROUGH;
25942597
#endif /* AF_RDS */
25952598

25962599
case AF_INET:

Modules/zlibmodule.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,8 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits,
489489
Py_END_ALLOW_THREADS
490490

491491
switch (err) {
492-
case Z_OK: /* fall through */
493-
case Z_BUF_ERROR: /* fall through */
492+
case Z_OK: _Py_FALLTHROUGH;
493+
case Z_BUF_ERROR: _Py_FALLTHROUGH;
494494
case Z_STREAM_END:
495495
break;
496496
case Z_MEM_ERROR:
@@ -915,8 +915,8 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls,
915915
Py_END_ALLOW_THREADS
916916

917917
switch (err) {
918-
case Z_OK: /* fall through */
919-
case Z_BUF_ERROR: /* fall through */
918+
case Z_OK: _Py_FALLTHROUGH;
919+
case Z_BUF_ERROR: _Py_FALLTHROUGH;
920920
case Z_STREAM_END:
921921
break;
922922
default:
@@ -1293,8 +1293,8 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls,
12931293
Py_END_ALLOW_THREADS
12941294

12951295
switch (err) {
1296-
case Z_OK: /* fall through */
1297-
case Z_BUF_ERROR: /* fall through */
1296+
case Z_OK: _Py_FALLTHROUGH;
1297+
case Z_BUF_ERROR: _Py_FALLTHROUGH;
12981298
case Z_STREAM_END:
12991299
break;
13001300
default:
@@ -1495,8 +1495,8 @@ decompress_buf(ZlibDecompressor *self, Py_ssize_t max_length)
14951495
err = inflate(&self->zst, Z_SYNC_FLUSH);
14961496
Py_END_ALLOW_THREADS
14971497
switch (err) {
1498-
case Z_OK: /* fall through */
1499-
case Z_BUF_ERROR: /* fall through */
1498+
case Z_OK: _Py_FALLTHROUGH;
1499+
case Z_BUF_ERROR: _Py_FALLTHROUGH;
15001500
case Z_STREAM_END:
15011501
break;
15021502
default:

Objects/rangeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args)
8383
switch (num_args) {
8484
case 3:
8585
step = args[2];
86-
/* fallthrough */
86+
_Py_FALLTHROUGH;
8787
case 2:
8888
/* Convert borrowed refs to owned refs */
8989
start = PyNumber_Index(args[0]);

Objects/stringlib/codecs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
331331
case _Py_ERROR_REPLACE:
332332
memset(p, '?', endpos - startpos);
333333
p += (endpos - startpos);
334-
/* fall through */
334+
_Py_FALLTHROUGH;
335335
case _Py_ERROR_IGNORE:
336336
i += (endpos - startpos - 1);
337337
break;
@@ -379,7 +379,7 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
379379
}
380380
startpos = k;
381381
assert(startpos < endpos);
382-
/* fall through */
382+
_Py_FALLTHROUGH;
383383
default:
384384
rep = unicode_encode_call_errorhandler(
385385
errors, &error_handler_obj, "utf-8", "surrogates not allowed",

Objects/unicodeobject.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5073,7 +5073,7 @@ unicode_decode_utf8_impl(_PyUnicodeWriter *writer,
50735073
/* Truncated surrogate code in range D800-DFFF */
50745074
goto End;
50755075
}
5076-
/* fall through */
5076+
_Py_FALLTHROUGH;
50775077
case 3:
50785078
case 4:
50795079
errmsg = "invalid continuation byte";
@@ -7108,7 +7108,7 @@ unicode_encode_ucs1(PyObject *unicode,
71087108
case _Py_ERROR_REPLACE:
71097109
memset(str, '?', collend - collstart);
71107110
str += (collend - collstart);
7111-
/* fall through */
7111+
_Py_FALLTHROUGH;
71127112
case _Py_ERROR_IGNORE:
71137113
pos = collend;
71147114
break;
@@ -7147,7 +7147,7 @@ unicode_encode_ucs1(PyObject *unicode,
71477147
break;
71487148
collstart = pos;
71497149
assert(collstart != collend);
7150-
/* fall through */
7150+
_Py_FALLTHROUGH;
71517151

71527152
default:
71537153
rep = unicode_encode_call_errorhandler(errors, &error_handler_obj,
@@ -8699,7 +8699,7 @@ charmap_encoding_error(
86998699
return -1;
87008700
}
87018701
}
8702-
/* fall through */
8702+
_Py_FALLTHROUGH;
87038703
case _Py_ERROR_IGNORE:
87048704
*inpos = collendpos;
87058705
break;
@@ -15673,7 +15673,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1567315673
#endif
1567415674
break;
1567515675
case SSTATE_NOT_INTERNED:
15676-
/* fall through */
15676+
_Py_FALLTHROUGH;
1567715677
default:
1567815678
Py_UNREACHABLE();
1567915679
}

Python/assemble.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,17 +369,17 @@ write_instr(_Py_CODEUNIT *codestr, instruction *instr, int ilen)
369369
codestr->op.code = EXTENDED_ARG;
370370
codestr->op.arg = (oparg >> 24) & 0xFF;
371371
codestr++;
372-
/* fall through */
372+
_Py_FALLTHROUGH;
373373
case 3:
374374
codestr->op.code = EXTENDED_ARG;
375375
codestr->op.arg = (oparg >> 16) & 0xFF;
376376
codestr++;
377-
/* fall through */
377+
_Py_FALLTHROUGH;
378378
case 2:
379379
codestr->op.code = EXTENDED_ARG;
380380
codestr->op.arg = (oparg >> 8) & 0xFF;
381381
codestr++;
382-
/* fall through */
382+
_Py_FALLTHROUGH;
383383
case 1:
384384
codestr->op.code = opcode;
385385
codestr->op.arg = oparg & 0xFF;

Python/bytecodes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,10 +794,10 @@ dummy_func(
794794
switch (oparg) {
795795
case 2:
796796
cause = args[1];
797-
/* fall through */
797+
_Py_FALLTHROUGH;
798798
case 1:
799799
exc = args[0];
800-
/* fall through */
800+
_Py_FALLTHROUGH;
801801
case 0:
802802
if (do_raise(tstate, exc, cause)) {
803803
assert(oparg == 0);

Python/compile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4681,7 +4681,7 @@ check_subscripter(struct compiler *c, expr_ty e)
46814681
{
46824682
return SUCCESS;
46834683
}
4684-
/* fall through */
4684+
_Py_FALLTHROUGH;
46854685
case Set_kind:
46864686
case SetComp_kind:
46874687
case GeneratorExp_kind:
@@ -4714,7 +4714,7 @@ check_index(struct compiler *c, expr_ty e, expr_ty s)
47144714
if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
47154715
return SUCCESS;
47164716
}
4717-
/* fall through */
4717+
_Py_FALLTHROUGH;
47184718
case Tuple_kind:
47194719
case List_kind:
47204720
case ListComp_kind:

Python/crossinterp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ _PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp)
969969
{
970970
assert(!PyErr_Occurred());
971971
switch (code) {
972-
case _PyXI_ERR_NO_ERROR: // fall through
972+
case _PyXI_ERR_NO_ERROR: _Py_FALLTHROUGH;
973973
case _PyXI_ERR_UNCAUGHT_EXCEPTION:
974974
// There is nothing to apply.
975975
#ifdef Py_DEBUG

Python/dtoa.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,7 @@ _Py_dg_strtod(const char *s00, char **se)
14051405
switch (c) {
14061406
case '-':
14071407
sign = 1;
1408-
/* fall through */
1408+
_Py_FALLTHROUGH;
14091409
case '+':
14101410
c = *++s;
14111411
}
@@ -1474,7 +1474,7 @@ _Py_dg_strtod(const char *s00, char **se)
14741474
switch (c) {
14751475
case '-':
14761476
esign = 1;
1477-
/* fall through */
1477+
_Py_FALLTHROUGH;
14781478
case '+':
14791479
c = *++s;
14801480
}
@@ -2362,15 +2362,15 @@ _Py_dg_dtoa(double dd, int mode, int ndigits,
23622362
break;
23632363
case 2:
23642364
leftright = 0;
2365-
/* fall through */
2365+
_Py_FALLTHROUGH;
23662366
case 4:
23672367
if (ndigits <= 0)
23682368
ndigits = 1;
23692369
ilim = ilim1 = i = ndigits;
23702370
break;
23712371
case 3:
23722372
leftright = 0;
2373-
/* fall through */
2373+
_Py_FALLTHROUGH;
23742374
case 5:
23752375
i = ndigits + k + 1;
23762376
ilim = i;

Python/formatter_unicode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ parse_internal_render_format_spec(PyObject *obj,
320320
format->thousands_separators = LT_UNDER_FOUR_LOCALE;
321321
break;
322322
}
323-
/* fall through */
323+
_Py_FALLTHROUGH;
324324
default:
325325
invalid_thousands_separator_type(format->thousands_separators, format->type);
326326
return 0;

Python/getargs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2676,7 +2676,7 @@ skipitem(const char **p_format, va_list *p_va, int flags)
26762676
goto err;
26772677
format++;
26782678
}
2679-
/* fall through */
2679+
_Py_FALLTHROUGH;
26802680

26812681
case 's': /* string */
26822682
case 'z': /* string or None */

0 commit comments

Comments
 (0)