[Chore](build) enable fallthrough check annd fix some fallthrough bug (#16748)

* enable fallthrough check annd fix some fallthrough bug

* fix

* fix
This commit is contained in:
Pxl
2023-02-15 15:58:43 +08:00
committed by GitHub
parent 585b74b175
commit f50edff59d
18 changed files with 77 additions and 194 deletions

View File

@ -474,7 +474,6 @@ add_compile_options(-g
-fno-omit-frame-pointer)
add_compile_options(-Wno-unused-parameter
-Wno-implicit-fallthrough
-Wno-sign-compare
-Wno-array-bounds)

View File

@ -66,7 +66,7 @@ if (GLIBC_COMPATIBILITY)
if (COMPILER_CLANG)
target_compile_options(glibc-compatibility PRIVATE -Wno-unused-command-line-argument -Wno-unused-but-set-variable)
elseif (COMPILER_GCC)
target_compile_options(glibc-compatibility PRIVATE -Wno-unused-but-set-variable -Wno-unused-but-set-variable)
target_compile_options(glibc-compatibility PRIVATE -Wno-unused-but-set-variable -Wno-unused-but-set-variable -Wno-implicit-fallthrough)
endif ()
target_include_directories(glibc-compatibility PRIVATE ${musl_arch_include_dir})

View File

@ -57,7 +57,7 @@ endif()
add_library(Gutil STATIC ${SOURCE_FILES})
set_target_properties(Gutil PROPERTIES COMPILE_FLAGS "-funsigned-char -Wno-deprecated")
target_compile_options(Gutil PRIVATE -Wno-char-subscripts)
target_compile_options(Gutil PRIVATE -Wno-char-subscripts -Wno-implicit-fallthrough)
# target_link_libraries(Gutil glog protobuf rt)
#set(GUTIL_LIBS

View File

@ -14,101 +14,6 @@
#include "butil/macros.h"
#include "gutil/port.h"
// The swigged version of an abstract class must be concrete if any methods
// return objects of the abstract type. We keep it abstract in C++ and
// concrete for swig.
#ifndef SWIG
#define ABSTRACT = 0
#endif
// The COMPILE_ASSERT macro can be used to verify that a compile time
// expression is true. For example, you could use it to verify the
// size of a static array:
//
// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
// content_type_names_incorrect_size);
//
// or to make sure a struct is smaller than a certain size:
//
// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
//
// The second argument to the macro is the name of the variable. If
// the expression is false, most compilers will issue a warning/error
// containing the name of the variable.
template <bool>
struct CompileAssert {};
#ifndef COMPILE_ASSERT
#define COMPILE_ASSERT(expr, msg) \
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED
// Implementation details of COMPILE_ASSERT:
//
// - COMPILE_ASSERT works by defining an array type that has -1
// elements (and thus is invalid) when the expression is false.
//
// - The simpler definition
//
// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
//
// does not work, as gcc supports variable-length arrays whose sizes
// are determined at run-time (this is gcc's extension and not part
// of the C++ standard). As a result, gcc fails to reject the
// following code with the simple definition:
//
// int foo;
// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
// // not a compile-time constant.
//
// - By using the type CompileAssert<(bool(expr))>, we ensures that
// expr is a compile-time constant. (Template arguments must be
// determined at compile-time.)
//
// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
//
// CompileAssert<bool(expr)>
//
// instead, these compilers will refuse to compile
//
// COMPILE_ASSERT(5 > 0, some_message);
//
// (They seem to think the ">" in "5 > 0" marks the end of the
// template argument list.)
//
// - The array size is (bool(expr) ? 1 : -1), instead of simply
//
// ((expr) ? 1 : -1).
//
// This is to avoid running into a bug in MS VC 7.1, which
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
#endif // COMPILE_ASSERT
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
//
// For disallowing only assign or copy, write the code directly, but declare
// the intend in a comment, for example:
// void operator=(const TypeName&); // DISALLOW_ASSIGN
// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
// semantically, one should either use disallow both or neither. Try to
// avoid these in new code.
#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
#endif
// An older, politically incorrect name for the above.
// Prefer DISALLOW_COPY_AND_ASSIGN for new code.
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
// A macro to turn a symbol into a string
#define AS_STRING(x) AS_STRING_INTERNAL(x)
#define AS_STRING_INTERNAL(x) #x
// Macro that allows definition of a variable appended with the current line
// number in the source file. Typically for use by other macros to allow the
// user to declare multiple variables with the same "base" name inside the same
@ -117,86 +22,9 @@ struct CompileAssert {};
#define VARNAME_LINENUM_INTERNAL(v, line) VARNAME_LINENUM_INTERNAL2(v, line)
#define VARNAME_LINENUM_INTERNAL2(v, line) v##line
// The following enum should be used only as a constructor argument to indicate
// that the variable has static storage class, and that the constructor should
// do nothing to its state. It indicates to the reader that it is legal to
// declare a static instance of the class, provided the constructor is given
// the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a
// static variable that has a constructor or a destructor because invocation
// order is undefined. However, IF the type can be initialized by filling with
// zeroes (which the loader does for static variables), AND the type's
// destructor does nothing to the storage, then a constructor for static
// initialization can be declared as
// explicit MyClass(base::LinkerInitialized x) {}
// and invoked as
// static MyClass my_variable_name(base::LINKER_INITIALIZED);
namespace base {
enum LinkerInitialized { LINKER_INITIALIZED };
}
// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
// between switch labels:
// switch (x) {
// case 40:
// case 41:
// if (truth_is_out_there) {
// ++x;
// FALLTHROUGH_INTENDED; // Use instead of/along with annotations in
// // comments.
// } else {
// return x;
// }
// case 42:
// ...
//
// As shown in the example above, the FALLTHROUGH_INTENDED macro should be
// followed by a semicolon. It is designed to mimic control-flow statements
// like 'break;', so it can be placed in most places where 'break;' can, but
// only if there are no statements on the execution path between it and the
// next switch label.
//
// When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is
// expanded to [[clang::fallthrough]] attribute, which is analysed when
// performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
// See clang documentation on language extensions for details:
// http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
//
// When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
// effect on diagnostics.
//
// In either case this macro has no effect on runtime behavior and performance
// of code.
#if defined(__clang__) && defined(LANG_CXX11) && defined(__has_warning)
#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
#define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT
#endif
#endif
#ifndef FALLTHROUGH_INTENDED
#define FALLTHROUGH_INTENDED \
do { \
} while (0)
#endif
// Retry on EINTR for functions like read() that return -1 on error.
#define RETRY_ON_EINTR(err, expr) \
do { \
static_assert(std::is_signed<decltype(err)>::value, #err " must be a signed integer"); \
(err) = (expr); \
} while ((err) == -1 && errno == EINTR)
// Same as above but for stream API calls like fread() and fwrite().
#define STREAM_RETRY_ON_EINTR(nread, stream, expr) \
do { \
static_assert(std::is_unsigned<decltype(nread)>::value == true, \
#nread " must be an unsigned integer"); \
(nread) = (expr); \
} while ((nread) == 0 && ferror(stream) == EINTR)
// Same as above but for functions that return pointer types (like
// fopen() and freopen()).
#define POINTER_RETRY_ON_EINTR(ptr, expr) \
do { \
static_assert(std::is_pointer<decltype(ptr)>::value == true, #ptr " must be a pointer"); \
(ptr) = (expr); \
} while ((ptr) == nullptr && errno == EINTR)

View File

@ -230,6 +230,7 @@ Status KafkaDataConsumer::group_consume(BlockingQueue<RdKafka::Message*>* queue,
std::this_thread::sleep_for(std::chrono::milliseconds(200));
break;
}
[[fallthrough]];
default:
LOG(WARNING) << "kafka consume failed: " << _id << ", msg: " << msg->errstr();
done = true;

View File

@ -245,6 +245,7 @@ TypeDescriptor::TypeDescriptor(const google::protobuf::RepeatedPtrField<PTypeNod
children.push_back(TypeDescriptor(types, idx));
++(*idx);
children.push_back(TypeDescriptor(types, idx));
break;
}
case TTypeNodeType::STRUCT: {
type = TYPE_STRUCT;
@ -258,6 +259,7 @@ TypeDescriptor::TypeDescriptor(const google::protobuf::RepeatedPtrField<PTypeNod
++(*idx);
children.push_back(TypeDescriptor(types, idx));
}
break;
}
case TTypeNodeType::VARIANT: {
type = TYPE_VARIANT;

View File

@ -321,9 +321,10 @@ const uint8_t* BitPacking::UnpackUpTo31Values(const uint8_t* __restrict__ in, in
}
#pragma push_macro("UNPACK_VALUES_CASE")
#define UNPACK_VALUES_CASE(ignore1, i, ignore2) \
case 31 - i: \
out[30 - i] = static_cast<OutType>(UnpackValue<BIT_WIDTH, 30 - i, false>(in_buffer));
#define UNPACK_VALUES_CASE(ignore1, i, ignore2) \
case 31 - i: \
out[30 - i] = static_cast<OutType>(UnpackValue<BIT_WIDTH, 30 - i, false>(in_buffer)); \
[[fallthrough]];
// Use switch with fall-through cases to minimise branching.
switch (num_values) {

View File

@ -1512,6 +1512,7 @@ public:
case BITMAP:
return cardinality() + 1 - 2 * (_bitmap.contains(rhs._sv));
}
break;
case BITMAP:
switch (_type) {
case EMPTY:
@ -1538,6 +1539,7 @@ public:
case BITMAP:
return cardinality() - _bitmap.contains(rhs._sv);
}
break;
case BITMAP:
switch (_type) {
case EMPTY:

View File

@ -169,16 +169,22 @@ public:
switch (len & 7) {
case 7:
h ^= uint64_t(data2[6]) << 48;
[[fallthrough]];
case 6:
h ^= uint64_t(data2[5]) << 40;
[[fallthrough]];
case 5:
h ^= uint64_t(data2[4]) << 32;
[[fallthrough]];
case 4:
h ^= uint64_t(data2[3]) << 24;
[[fallthrough]];
case 3:
h ^= uint64_t(data2[2]) << 16;
[[fallthrough]];
case 2:
h ^= uint64_t(data2[1]) << 8;
[[fallthrough]];
case 1:
h ^= uint64_t(data2[0]);
h *= MURMUR_PRIME;
@ -261,16 +267,22 @@ public:
switch (len & 7) {
case 7:
h ^= (uint64_t)data[6] << 48;
[[fallthrough]];
case 6:
h ^= (uint64_t)data[5] << 40;
[[fallthrough]];
case 5:
h ^= (uint64_t)data[4] << 32;
[[fallthrough]];
case 4:
h ^= (uint64_t)data[3] << 24;
[[fallthrough]];
case 3:
h ^= (uint64_t)data[2] << 16;
[[fallthrough]];
case 2:
h ^= (uint64_t)data[1] << 8;
[[fallthrough]];
case 1:
h ^= (uint64_t)data[0];
h *= m;

View File

@ -121,8 +121,10 @@ void murmur_hash3_x86_32(const void* key, int len, uint32_t seed, void* out) {
switch (len & 3) {
case 3:
k1 ^= tail[2] << 16;
[[fallthrough]];
case 2:
k1 ^= tail[1] << 8;
[[fallthrough]];
case 1:
k1 ^= tail[0];
k1 *= c1;
@ -218,47 +220,58 @@ void murmur_hash3_x86_128(const void* key, const int len, uint32_t seed, void* o
switch (len & 15) {
case 15:
k4 ^= tail[14] << 16;
[[fallthrough]];
case 14:
k4 ^= tail[13] << 8;
[[fallthrough]];
case 13:
k4 ^= tail[12] << 0;
k4 *= c4;
k4 = ROTL32(k4, 18);
k4 *= c1;
h4 ^= k4;
[[fallthrough]];
case 12:
k3 ^= tail[11] << 24;
[[fallthrough]];
case 11:
k3 ^= tail[10] << 16;
[[fallthrough]];
case 10:
k3 ^= tail[9] << 8;
[[fallthrough]];
case 9:
k3 ^= tail[8] << 0;
k3 *= c3;
k3 = ROTL32(k3, 17);
k3 *= c4;
h3 ^= k3;
[[fallthrough]];
case 8:
k2 ^= tail[7] << 24;
[[fallthrough]];
case 7:
k2 ^= tail[6] << 16;
[[fallthrough]];
case 6:
k2 ^= tail[5] << 8;
[[fallthrough]];
case 5:
k2 ^= tail[4] << 0;
k2 *= c2;
k2 = ROTL32(k2, 16);
k2 *= c3;
h2 ^= k2;
[[fallthrough]];
case 4:
k1 ^= tail[3] << 24;
[[fallthrough]];
case 3:
k1 ^= tail[2] << 16;
[[fallthrough]];
case 2:
k1 ^= tail[1] << 8;
[[fallthrough]];
case 1:
k1 ^= tail[0] << 0;
k1 *= c1;
@ -351,37 +364,50 @@ void murmur_hash3_x64_128(const void* key, const int len, const uint32_t seed, v
switch (len & 15) {
case 15:
k2 ^= ((uint64_t)tail[14]) << 48;
[[fallthrough]];
case 14:
k2 ^= ((uint64_t)tail[13]) << 40;
[[fallthrough]];
case 13:
k2 ^= ((uint64_t)tail[12]) << 32;
[[fallthrough]];
case 12:
k2 ^= ((uint64_t)tail[11]) << 24;
[[fallthrough]];
case 11:
k2 ^= ((uint64_t)tail[10]) << 16;
[[fallthrough]];
case 10:
k2 ^= ((uint64_t)tail[9]) << 8;
[[fallthrough]];
case 9:
k2 ^= ((uint64_t)tail[8]) << 0;
k2 *= c2;
k2 = ROTL64(k2, 33);
k2 *= c1;
h2 ^= k2;
[[fallthrough]];
case 8:
k1 ^= ((uint64_t)tail[7]) << 56;
[[fallthrough]];
case 7:
k1 ^= ((uint64_t)tail[6]) << 48;
[[fallthrough]];
case 6:
k1 ^= ((uint64_t)tail[5]) << 40;
[[fallthrough]];
case 5:
k1 ^= ((uint64_t)tail[4]) << 32;
[[fallthrough]];
case 4:
k1 ^= ((uint64_t)tail[3]) << 24;
[[fallthrough]];
case 3:
k1 ^= ((uint64_t)tail[2]) << 16;
[[fallthrough]];
case 2:
k1 ^= ((uint64_t)tail[1]) << 8;
[[fallthrough]];
case 1:
k1 ^= ((uint64_t)tail[0]) << 0;
k1 *= c1;
@ -443,16 +469,22 @@ void murmur_hash3_x64_64(const void* key, const int len, const uint64_t seed, vo
switch (len & 7) {
case 7:
k1 ^= ((uint64_t)tail[6]) << 48;
[[fallthrough]];
case 6:
k1 ^= ((uint64_t)tail[5]) << 40;
[[fallthrough]];
case 5:
k1 ^= ((uint64_t)tail[4]) << 32;
[[fallthrough]];
case 4:
k1 ^= ((uint64_t)tail[3]) << 24;
[[fallthrough]];
case 3:
k1 ^= ((uint64_t)tail[2]) << 16;
[[fallthrough]];
case 2:
k1 ^= ((uint64_t)tail[1]) << 8;
[[fallthrough]];
case 1:
k1 ^= ((uint64_t)tail[0]) << 0;
k1 *= c1;

View File

@ -242,6 +242,7 @@ inline T StringParser::string_to_int_internal(const char* s, int len, ParseResul
case '-':
negative = true;
max_val = StringParser::numeric_limits<T>(false) + 1;
[[fallthrough]];
case '+':
++i;
}
@ -345,6 +346,7 @@ inline T StringParser::string_to_int_internal(const char* s, int len, int base,
case '-':
negative = true;
max_val = StringParser::numeric_limits<T>(false) + 1;
[[fallthrough]];
case '+':
i = 1;
}
@ -568,6 +570,7 @@ inline T StringParser::string_to_decimal(const char* s, int len, int type_precis
switch (*s) {
case '-':
is_negative = true;
[[fallthrough]];
case '+':
++s;
--len;

View File

@ -139,7 +139,7 @@ void ThreadPoolToken::shutdown() {
break;
}
transition(State::QUIESCING);
FALLTHROUGH_INTENDED;
[[fallthrough]];
case State::QUIESCING:
// The token is already quiescing. Just wait for a worker thread to
// switch it to QUIESCED.

View File

@ -243,6 +243,7 @@ int64_t base64_decode(const char* data, size_t length, char* decoded_data) {
return 0;
case 2:
k++;
[[fallthrough]];
case 3:
decoded_data[k] = 0;
default:

View File

@ -119,18 +119,19 @@ Status VExpr::create_expr(doris::ObjectPool* pool, const doris::TExprNode& texpr
case TExprNodeType::JSON_LITERAL:
case TExprNodeType::NULL_LITERAL: {
*expr = pool->add(new VLiteral(texpr_node));
return Status::OK();
break;
}
case TExprNodeType::ARRAY_LITERAL: {
*expr = pool->add(new VArrayLiteral(texpr_node));
return Status::OK();
break;
}
case TExprNodeType::MAP_LITERAL: {
*expr = pool->add(new VMapLiteral(texpr_node));
break;
}
case TExprNodeType::STRUCT_LITERAL: {
*expr = pool->add(new VStructLiteral(texpr_node));
return Status::OK();
break;
}
case doris::TExprNodeType::SLOT_REF: {
*expr = pool->add(new VSlotRef(texpr_node));
@ -349,7 +350,7 @@ FunctionContext::TypeDesc VExpr::column_type_to_type_desc(const TypeDescriptor&
break;
case TYPE_OBJECT:
out.type = FunctionContext::TYPE_OBJECT;
// FIXME(cmy): is this fallthrough meaningful?
break;
case TYPE_QUANTILE_STATE:
out.type = FunctionContext::TYPE_QUANTILE_STATE;
break;

View File

@ -213,8 +213,10 @@ std::string VLiteral::value() const {
case TYPE_BOOLEAN:
case TYPE_TINYINT:
out << *(reinterpret_cast<const int8_t*>(ref.data));
break;
case TYPE_SMALLINT:
out << *(reinterpret_cast<const int16_t*>(ref.data));
break;
case TYPE_INT: {
out << *(reinterpret_cast<const int32_t*>(ref.data));
break;

View File

@ -38,8 +38,6 @@ namespace doris::vectorized {
Status Channel::init(RuntimeState* state) {
_be_number = state->be_number();
_capacity = std::max(1, _buffer_size / std::max(_row_desc.get_row_size(), 1));
if (_brpc_dest_addr.hostname.empty()) {
LOG(WARNING) << "there is no brpc destination address's hostname"
", maybe version is not compatible.";

View File

@ -222,7 +222,6 @@ public:
PlanNodeId dest_node_id, int buffer_size, bool is_transfer_chain,
bool send_query_statistics_with_every_batch)
: _parent(parent),
_buffer_size(buffer_size),
_row_desc(row_desc),
_fragment_instance_id(fragment_instance_id),
_dest_node_id(dest_node_id),
@ -231,7 +230,8 @@ public:
_need_close(false),
_brpc_dest_addr(brpc_dest),
_is_transfer_chain(is_transfer_chain),
_send_query_statistics_with_every_batch(send_query_statistics_with_every_batch) {
_send_query_statistics_with_every_batch(send_query_statistics_with_every_batch),
_capacity(std::max(1, buffer_size / std::max(_row_desc.get_row_size(), 1))) {
std::string localhost = BackendOptions::get_localhost();
_is_local = (_brpc_dest_addr.hostname == localhost) &&
(_brpc_dest_addr.port == config::brpc_port);
@ -331,7 +331,6 @@ protected:
Status close_internal();
VDataStreamSender* _parent;
int _buffer_size;
const RowDescriptor& _row_desc;
TUniqueId _fragment_instance_id;

View File

@ -255,11 +255,13 @@ TEST_F(TestRowsetTree, TestTreeRandomized) {
int r = strcmp(s1.c_str(), s2.c_str());
switch (op) {
case BOUND_LESS_THAN:
if (r == 0) continue; // pass through.
if (r == 0) continue;
[[fallthrough]];
case BOUND_LESS_EQUAL:
return std::pair<string, string>(std::min(s1, s2), std::max(s1, s2));
case BOUND_GREATER_THAN:
if (r == 0) continue; // pass through.
if (r == 0) continue;
[[fallthrough]];
case BOUND_GREATER_EQUAL:
return std::pair<string, string>(std::max(s1, s2), std::min(s1, s2));
case BOUND_EQUAL: