Fix warnings when using -Wimplicit-fallthrough compiler flag.
Annotate explicitly "fall through" switch cases with a new
_Py_FALLTHROUGH macro which uses __attribute__((fallthrough)) if
available. Replace "fall through" comments with _Py_FALLTHROUGH.
Add _Py__has_attribute() macro. No longer define __has_attribute()
macro if it's not defined. Move also _Py__has_builtin() at the top
of pyport.h.
Co-Authored-By: Nikita Sobolev <mail@sobolevn.me>
* we may still need to support gcc >= 4, as some Ubuntu LTS and Centos versions
* have 4 < gcc < 5.
*/
- #ifndef __has_attribute
- #define __has_attribute(x) 0 // Compatibility with non-clang compilers.
- #endif
#if (defined(__GNUC__) && (__GNUC__ >= 4)) ||\
- (defined(__clang__) && __has_attribute(visibility))
+ (defined(__clang__) && _Py__has_attribute(visibility))
#define Py_IMPORTED_SYMBOL __attribute__ ((visibility ("default")))
#define Py_EXPORTED_SYMBOL __attribute__ ((visibility ("default")))
#define Py_LOCAL_SYMBOL __attribute__ ((visibility ("hidden")))
#endif
+// Preprocessor check for a builtin preprocessor function. Always return 0
+// if __has_builtin() macro is not defined.
+//
+// __has_builtin() is available on clang and GCC 10.
+#ifdef __has_builtin
+# define _Py__has_builtin(x) __has_builtin(x)
+#else
+# define _Py__has_builtin(x) 0
+#endif
+
+// Preprocessor check for a compiler __attribute__. Always return 0
+// if __has_attribute() macro is not defined.
+#ifdef __has_attribute
+# define _Py__has_attribute(x) __has_attribute(x)
+#else
+# define _Py__has_attribute(x) 0
+#endif
+
// Macro to use C++ static_cast<> in the Python C API.
#ifdef __cplusplus
# define _Py_STATIC_CAST(type, expr) static_cast<type>(expr)
#endif
-// Preprocessor check for a builtin preprocessor function. Always return 0
-// if __has_builtin() macro is not defined.
-//
-// __has_builtin() is available on clang and GCC 10.
-#ifdef __has_builtin
-# define _Py__has_builtin(x) __has_builtin(x)
-#else
-# define _Py__has_builtin(x) 0
-#endif
-
// _Py_TYPEOF(expr) gets the type of an expression.
//
// Example: _Py_TYPEOF(x) x_copy = (x);
# define _SGI_MP_SOURCE
#endif
+// Explicit fallthrough in switch case to avoid warnings
+// with compiler flag -Wimplicit-fallthrough.
+//
+// Usage example:
+//
+// switch (value) {
+// case 1: _Py_FALLTHROUGH;
+// case 2: code; break;
+// }
+//
+// __attribute__((fallthrough)) was introduced in GCC 7.
+#if _Py__has_attribute(fallthrough)
+# define _Py_FALLTHROUGH __attribute__((fallthrough))
+#else
+# define _Py_FALLTHROUGH do { } while (0)
+#endif
+
#endif /* Py_PYPORT_H */
}
/* normal character - handle as START_FIELD */
self->state = START_FIELD;
- /* fallthru */
+ _Py_FALLTHROUGH;
case START_FIELD:
/* expecting field */
self->unquoted_field = true;
case AFTER_ESCAPED_CRNL:
if (c == EOL)
break;
- /*fallthru*/
+ _Py_FALLTHROUGH;
case IN_FIELD:
/* in unquoted field */
case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
*pinoutmask |= (1 << i); /* mark as inout arg */
(*pnumretvals)++;
- /* fall through */
+ _Py_FALLTHROUGH;
case 0:
case PARAMFLAG_FIN:
/* 'in' parameter. Copy it from inargs. */
case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32:
if (info->getfunc != _ctypes_get_fielddesc("c")->getfunc
- && info->getfunc != _ctypes_get_fielddesc("u")->getfunc
- )
+ && info->getfunc != _ctypes_get_fielddesc("u")->getfunc)
+ {
break;
- /* else fall through */
+ }
+ _Py_FALLTHROUGH; /* else fall through */
default:
PyErr_Format(PyExc_TypeError,
"bit fields not allowed for type %s",
module_state *state;
switch (err) {
- case ERR_QUEUE_ALLOC: // fall through
+ case ERR_QUEUE_ALLOC: _Py_FALLTHROUGH;
case ERR_QUEUES_ALLOC:
PyErr_NoMemory();
break;
}
switch(self->protocol) {
- case PY_SSL_VERSION_TLS_CLIENT: /* fall through */
- case PY_SSL_VERSION_TLS_SERVER: /* fall through */
+ case PY_SSL_VERSION_TLS_CLIENT: _Py_FALLTHROUGH;
+ case PY_SSL_VERSION_TLS_SERVER: _Py_FALLTHROUGH;
case PY_SSL_VERSION_TLS:
break;
default:
}
default:
--*pfmt; /* Back out of pointer increment */
- /* Fall through */
+ _Py_FALLTHROUGH;
case '@':
return native_table;
}
return -1;
switch (c) {
- case 's': /* fall through */
+ case 's': _Py_FALLTHROUGH;
case 'p': len++; ncodes++; break;
case 'x': break;
default: len += num; if (num) ncodes++; break;
case 3:
traceback = PyTuple_GetItem(args, 2);
Py_INCREF(traceback);
- /* fall through */
+ _Py_FALLTHROUGH;
case 2:
value = PyTuple_GetItem(args, 1);
Py_INCREF(value);
- /* fall through */
+ _Py_FALLTHROUGH;
case 1:
type = PyTuple_GetItem(args, 0);
Py_INCREF(type);
jisx0213_pair_encmap, JISX0213_ENCPAIRS);
if (coded != DBCINV)
return coded;
- /* fall through */
+ _Py_FALLTHROUGH;
case -1: /* flush unterminated */
*length = 1;
{
break;
}
- /* fall through */
+ _Py_FALLTHROUGH;
default:
return SetFromWindowsErr(err);
}
#ifdef AF_RDS
case AF_RDS:
- /* RDS sockets use sockaddr_in: fall-through */
+ /* RDS sockets use sockaddr_in */
+ _Py_FALLTHROUGH;
#endif /* AF_RDS */
#ifdef AF_DIVERT
case AF_DIVERT:
- /* FreeBSD divert(4) sockets use sockaddr_in: fall-through */
+ /* FreeBSD divert(4) sockets use sockaddr_in */
+ _Py_FALLTHROUGH;
#endif /* AF_DIVERT */
case AF_INET:
switch (s->sock_proto) {
#ifdef CAN_RAW
case CAN_RAW:
- /* fall-through */
+ _Py_FALLTHROUGH;
#endif
#ifdef CAN_BCM
case CAN_BCM:
#ifdef AF_RDS
case AF_RDS:
- /* RDS sockets use sockaddr_in: fall-through */
+ /* RDS sockets use sockaddr_in */
+ _Py_FALLTHROUGH;
#endif /* AF_RDS */
case AF_INET:
Py_END_ALLOW_THREADS
switch (err) {
- case Z_OK: /* fall through */
- case Z_BUF_ERROR: /* fall through */
+ case Z_OK: _Py_FALLTHROUGH;
+ case Z_BUF_ERROR: _Py_FALLTHROUGH;
case Z_STREAM_END:
break;
case Z_MEM_ERROR:
Py_END_ALLOW_THREADS
switch (err) {
- case Z_OK: /* fall through */
- case Z_BUF_ERROR: /* fall through */
+ case Z_OK: _Py_FALLTHROUGH;
+ case Z_BUF_ERROR: _Py_FALLTHROUGH;
case Z_STREAM_END:
break;
default:
Py_END_ALLOW_THREADS
switch (err) {
- case Z_OK: /* fall through */
- case Z_BUF_ERROR: /* fall through */
+ case Z_OK: _Py_FALLTHROUGH;
+ case Z_BUF_ERROR: _Py_FALLTHROUGH;
case Z_STREAM_END:
break;
default:
err = inflate(&self->zst, Z_SYNC_FLUSH);
Py_END_ALLOW_THREADS
switch (err) {
- case Z_OK: /* fall through */
- case Z_BUF_ERROR: /* fall through */
+ case Z_OK: _Py_FALLTHROUGH;
+ case Z_BUF_ERROR: _Py_FALLTHROUGH;
case Z_STREAM_END:
break;
default:
switch (num_args) {
case 3:
step = args[2];
- /* fallthrough */
+ _Py_FALLTHROUGH;
case 2:
/* Convert borrowed refs to owned refs */
start = PyNumber_Index(args[0]);
case _Py_ERROR_REPLACE:
memset(p, '?', endpos - startpos);
p += (endpos - startpos);
- /* fall through */
+ _Py_FALLTHROUGH;
case _Py_ERROR_IGNORE:
i += (endpos - startpos - 1);
break;
}
startpos = k;
assert(startpos < endpos);
- /* fall through */
+ _Py_FALLTHROUGH;
default:
rep = unicode_encode_call_errorhandler(
errors, &error_handler_obj, "utf-8", "surrogates not allowed",
/* Truncated surrogate code in range D800-DFFF */
goto End;
}
- /* fall through */
+ _Py_FALLTHROUGH;
case 3:
case 4:
errmsg = "invalid continuation byte";
case _Py_ERROR_REPLACE:
memset(str, '?', collend - collstart);
str += (collend - collstart);
- /* fall through */
+ _Py_FALLTHROUGH;
case _Py_ERROR_IGNORE:
pos = collend;
break;
break;
collstart = pos;
assert(collstart != collend);
- /* fall through */
+ _Py_FALLTHROUGH;
default:
rep = unicode_encode_call_errorhandler(errors, &error_handler_obj,
return -1;
}
}
- /* fall through */
+ _Py_FALLTHROUGH;
case _Py_ERROR_IGNORE:
*inpos = collendpos;
break;
#endif
break;
case SSTATE_NOT_INTERNED:
- /* fall through */
+ _Py_FALLTHROUGH;
default:
Py_UNREACHABLE();
}
codestr->op.code = EXTENDED_ARG;
codestr->op.arg = (oparg >> 24) & 0xFF;
codestr++;
- /* fall through */
+ _Py_FALLTHROUGH;
case 3:
codestr->op.code = EXTENDED_ARG;
codestr->op.arg = (oparg >> 16) & 0xFF;
codestr++;
- /* fall through */
+ _Py_FALLTHROUGH;
case 2:
codestr->op.code = EXTENDED_ARG;
codestr->op.arg = (oparg >> 8) & 0xFF;
codestr++;
- /* fall through */
+ _Py_FALLTHROUGH;
case 1:
codestr->op.code = opcode;
codestr->op.arg = oparg & 0xFF;
switch (oparg) {
case 2:
cause = PyStackRef_AsPyObjectSteal(args[1]);
- /* fall through */
+ _Py_FALLTHROUGH;
case 1:
exc = PyStackRef_AsPyObjectSteal(args[0]);
- /* fall through */
+ _Py_FALLTHROUGH;
case 0:
if (do_raise(tstate, exc, cause)) {
assert(oparg == 0);
{
return SUCCESS;
}
- /* fall through */
+ _Py_FALLTHROUGH;
case Set_kind:
case SetComp_kind:
case GeneratorExp_kind:
if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
return SUCCESS;
}
- /* fall through */
+ _Py_FALLTHROUGH;
case Tuple_kind:
case List_kind:
case ListComp_kind:
{
assert(!PyErr_Occurred());
switch (code) {
- case _PyXI_ERR_NO_ERROR: // fall through
+ case _PyXI_ERR_NO_ERROR: _Py_FALLTHROUGH;
case _PyXI_ERR_UNCAUGHT_EXCEPTION:
// There is nothing to apply.
#ifdef Py_DEBUG
switch (c) {
case '-':
sign = 1;
- /* fall through */
+ _Py_FALLTHROUGH;
case '+':
c = *++s;
}
switch (c) {
case '-':
esign = 1;
- /* fall through */
+ _Py_FALLTHROUGH;
case '+':
c = *++s;
}
break;
case 2:
leftright = 0;
- /* fall through */
+ _Py_FALLTHROUGH;
case 4:
if (ndigits <= 0)
ndigits = 1;
break;
case 3:
leftright = 0;
- /* fall through */
+ _Py_FALLTHROUGH;
case 5:
i = ndigits + k + 1;
ilim = i;
format->thousands_separators = LT_UNDER_FOUR_LOCALE;
break;
}
- /* fall through */
+ _Py_FALLTHROUGH;
default:
invalid_thousands_separator_type(format->thousands_separators, format->type);
return 0;
switch (oparg) {
case 2:
cause = PyStackRef_AsPyObjectSteal(args[1]);
- /* fall through */
+ _Py_FALLTHROUGH;
case 1:
exc = PyStackRef_AsPyObjectSteal(args[0]);
- /* fall through */
+ _Py_FALLTHROUGH;
case 0:
if (do_raise(tstate, exc, cause)) {
assert(oparg == 0);
goto err;
format++;
}
- /* fall through */
+ _Py_FALLTHROUGH;
case 's': /* string */
case 'z': /* string or None */
{
#ifndef NDEBUG
switch (kind) {
- case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
+ case _Py_ext_module_loader_result_EXCEPTION: _Py_FALLTHROUGH;
case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC:
assert(PyErr_Occurred());
break;
- case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
- case _Py_ext_module_loader_result_ERR_UNINITIALIZED: /* fall through */
- case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
- case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
+ case _Py_ext_module_loader_result_ERR_MISSING: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_UNINITIALIZED: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NOT_MODULE: _Py_FALLTHROUGH;
case _Py_ext_module_loader_result_ERR_MISSING_DEF:
assert(!PyErr_Occurred());
break;
res->kind = _Py_ext_module_kind_INVALID;
break;
/* None of the rest affect the result kind. */
- case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
- case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
- case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC: /* fall through */
- case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
- case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
+ case _Py_ext_module_loader_result_EXCEPTION: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_MISSING: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NOT_MODULE: _Py_FALLTHROUGH;
case _Py_ext_module_loader_result_ERR_MISSING_DEF:
break;
default:
#ifndef NDEBUG
switch (err.kind) {
- case _Py_ext_module_loader_result_EXCEPTION: /* fall through */
+ case _Py_ext_module_loader_result_EXCEPTION: _Py_FALLTHROUGH;
case _Py_ext_module_loader_result_ERR_UNREPORTED_EXC:
assert(err.exc != NULL);
break;
- case _Py_ext_module_loader_result_ERR_MISSING: /* fall through */
- case _Py_ext_module_loader_result_ERR_UNINITIALIZED: /* fall through */
- case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: /* fall through */
- case _Py_ext_module_loader_result_ERR_NOT_MODULE: /* fall through */
+ case _Py_ext_module_loader_result_ERR_MISSING: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_UNINITIALIZED: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE: _Py_FALLTHROUGH;
+ case _Py_ext_module_loader_result_ERR_NOT_MODULE: _Py_FALLTHROUGH;
case _Py_ext_module_loader_result_ERR_MISSING_DEF:
assert(err.exc == NULL);
break;
case TYPE_ASCII_INTERNED:
is_interned = 1;
- /* fall through */
+ _Py_FALLTHROUGH;
case TYPE_ASCII:
n = r_long(p);
if (n < 0 || n > SIZE32_MAX) {
case TYPE_SHORT_ASCII_INTERNED:
is_interned = 1;
- /* fall through */
+ _Py_FALLTHROUGH;
case TYPE_SHORT_ASCII:
n = r_byte(p);
if (n == EOF) {
case TYPE_INTERNED:
is_interned = 1;
- /* fall through */
+ _Py_FALLTHROUGH;
case TYPE_UNICODE:
{
const char *buffer;
return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t));
#endif
/* Fall through from 'n' to 'l' if Py_ssize_t is long */
+ _Py_FALLTHROUGH;
case 'l':
return PyLong_FromLong(va_arg(*p_va, long));
switch(len) {
/* ((hash << 5) + hash) + *p == hash * 33 + *p */
- case 7: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
- case 6: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
- case 5: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
- case 4: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
- case 3: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
- case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
+ case 7: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
+ case 6: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
+ case 5: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
+ case 4: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
+ case 3: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
+ case 2: hash = ((hash << 5) + hash) + *p++; _Py_FALLTHROUGH;
case 1: hash = ((hash << 5) + hash) + *p++; break;
default:
Py_UNREACHABLE();
t = 0;
pt = (uint8_t *)&t;
switch (src_sz) {
- case 7: pt[6] = in[6]; /* fall through */
- case 6: pt[5] = in[5]; /* fall through */
- case 5: pt[4] = in[4]; /* fall through */
+ case 7: pt[6] = in[6]; _Py_FALLTHROUGH;
+ case 6: pt[5] = in[5]; _Py_FALLTHROUGH;
+ case 5: pt[4] = in[4]; _Py_FALLTHROUGH;
case 4: memcpy(pt, in, sizeof(uint32_t)); break;
- case 3: pt[2] = in[2]; /* fall through */
- case 2: pt[1] = in[1]; /* fall through */
- case 1: pt[0] = in[0]; /* fall through */
+ case 3: pt[2] = in[2]; _Py_FALLTHROUGH;
+ case 2: pt[1] = in[1]; _Py_FALLTHROUGH;
+ case 1: pt[0] = in[0]; break;
}
b |= _le64toh(t);
t = 0;
pt = (uint8_t *)&t;
switch (src_sz) {
- case 7: pt[6] = in[6]; /* fall through */
- case 6: pt[5] = in[5]; /* fall through */
- case 5: pt[4] = in[4]; /* fall through */
+ case 7: pt[6] = in[6]; _Py_FALLTHROUGH;
+ case 6: pt[5] = in[5]; _Py_FALLTHROUGH;
+ case 5: pt[4] = in[4]; _Py_FALLTHROUGH;
case 4: memcpy(pt, in, sizeof(uint32_t)); break;
- case 3: pt[2] = in[2]; /* fall through */
- case 2: pt[1] = in[1]; /* fall through */
- case 1: pt[0] = in[0]; /* fall through */
+ case 3: pt[2] = in[2]; _Py_FALLTHROUGH;
+ case 2: pt[1] = in[1]; _Py_FALLTHROUGH;
+ case 1: pt[0] = in[0]; break;
}
b |= _le64toh(t);
case 'E':
float_strings = uc_float_strings;
format_code = 'e';
- /* Fall through. */
+ _Py_FALLTHROUGH;
case 'e':
mode = 2;
precision++;
case 'F':
float_strings = uc_float_strings;
format_code = 'f';
- /* Fall through. */
+ _Py_FALLTHROUGH;
case 'f':
mode = 3;
break;
case 'G':
float_strings = uc_float_strings;
format_code = 'g';
- /* Fall through. */
+ _Py_FALLTHROUGH;
case 'g':
mode = 2;
/* precision 0 makes no sense for 'g' format; interpret as 1 */