summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2022-04-13 11:36:53 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-18 16:23:30 +0000
commitc9c6b145e47ce97f077bc1af3d266db64e8afb65 (patch)
tree75cffd948f94ec2f732b7e5345bd51f267b4f366
parent8ad97ab6e15eb185438f37b2e9a2e3d9724f9493 (diff)
downloadmongo-c9c6b145e47ce97f077bc1af3d266db64e8afb65.tar.gz
SERVER-55204 Error on fallthrough unless the attribute is used
-rw-r--r--SConstruct5
-rw-r--r--src/SConscript23
-rw-r--r--src/mongo/bson/bson_comparator_interface_base.cpp1
-rw-r--r--src/mongo/bson/bsonelement.cpp1
-rw-r--r--src/mongo/client/cyrus_sasl_client_session.cpp2
-rw-r--r--src/mongo/db/catalog/collection_catalog.cpp1
-rw-r--r--src/mongo/db/exec/document_value/value.cpp1
-rw-r--r--src/mongo/db/exec/plan_cache_util.cpp1
-rw-r--r--src/mongo/db/exec/sbe/vm/arith.cpp2
-rw-r--r--src/mongo/db/exec/sbe/vm/vm.cpp4
-rw-r--r--src/mongo/db/exec/trial_stage.cpp1
-rw-r--r--src/mongo/db/index/wildcard_key_generator.cpp1
-rw-r--r--src/mongo/db/pipeline/document_source_group.cpp1
-rw-r--r--src/mongo/db/pipeline/expression.cpp4
-rw-r--r--src/mongo/db/query/canonical_query_encoder.cpp2
-rw-r--r--src/mongo/db/query/fle/server_rewrite.cpp1
-rw-r--r--src/mongo/db/query/optimizer/cascades/logical_props_derivation.cpp1
-rw-r--r--src/mongo/db/query/optimizer/rewrites/const_eval.cpp1
-rw-r--r--src/mongo/db/query/sbe_stage_builder.cpp1
-rw-r--r--src/mongo/db/repl/oplog.cpp2
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp5
-rw-r--r--src/mongo/db/repl/tenant_migration_donor_access_blocker.cpp1
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp2
-rw-r--r--src/mongo/db/service_entry_point_common.cpp7
-rw-r--r--src/mongo/db/storage/key_string.cpp14
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp2
-rw-r--r--src/mongo/embedded/periodic_runner_embedded.cpp3
-rw-r--r--src/mongo/s/service_entry_point_mongos.cpp2
-rw-r--r--src/mongo/tools/bridge.cpp5
-rw-r--r--src/mongo/unittest/unittest.cpp6
-rw-r--r--src/mongo/util/net/ssl/detail/io.hpp3
-rw-r--r--src/third_party/boost/boost/date_time/time_facet.hpp3
-rw-r--r--src/third_party/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp6
33 files changed, 89 insertions, 26 deletions
diff --git a/SConstruct b/SConstruct
index 408693bf142..6aa3b3aded5 100644
--- a/SConstruct
+++ b/SConstruct
@@ -2899,18 +2899,23 @@ def doConfigure(myenv):
def AddToCFLAGSIfSupported(env, flag):
return AddFlagIfSupported(env, 'C', '.c', flag, False, CFLAGS=[flag])
+ env.AddMethod(AddToCFLAGSIfSupported)
def AddToCCFLAGSIfSupported(env, flag):
return AddFlagIfSupported(env, 'C', '.c', flag, False, CCFLAGS=[flag])
+ env.AddMethod(AddToCCFLAGSIfSupported)
def AddToCXXFLAGSIfSupported(env, flag):
return AddFlagIfSupported(env, 'C++', '.cpp', flag, False, CXXFLAGS=[flag])
+ env.AddMethod(AddToCXXFLAGSIfSupported)
def AddToLINKFLAGSIfSupported(env, flag):
return AddFlagIfSupported(env, 'C', '.c', flag, True, LINKFLAGS=[flag])
+ env.AddMethod(AddToLINKFLAGSIfSupported)
def AddToSHLINKFLAGSIfSupported(env, flag):
return AddFlagIfSupported(env, 'C', '.c', flag, True, SHLINKFLAGS=[flag])
+ env.AddMethod(AddToSHLINKFLAGSIfSupported)
if myenv.ToolchainIs('gcc', 'clang'):
# This tells clang/gcc to use the gold linker if it is available - we prefer the gold linker
diff --git a/src/SConscript b/src/SConscript
index b046e91173c..25f9eb93146 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -8,6 +8,8 @@ import SCons
Import('env')
Import('module_sconscripts')
+env = env.Clone()
+
# Add any "global" dependencies here. This is where we make every build node
# depend on a list of other build nodes, such as an allocator or libunwind
# or libstdx or similar.
@@ -21,6 +23,12 @@ env.AppendUnique(
# that we need in the mongo sconscript
env.SConscript('third_party/SConscript', exports=['env'])
+# Ensure our subsequent modifications are not shared with the
+# third_party env. Normally that SConscript would have done a clone,
+# so handled that isolation itself, but it doesn't since it needs to
+# alter the env in ways that we need to use up here.
+env = env.Clone()
+
# Inject common dependencies from third_party globally for all core mongo code
# and modules. Ideally, pcre wouldn't be here, but enough things require it
# now that it seems hopeless to remove it.
@@ -33,6 +41,21 @@ env.InjectThirdParty(libraries=[
'variant',
])
+
+# It would be somewhat better if this could be applied down in
+# `src/mongo/SConscript`, since the goal of doing it here rather than
+# up in SConstruct is to only enforce this rule for code that we wrote
+# and exclude third party sources. However, doing it in
+# `src/mongo/SConscript`` would also exclude applying it for modules,
+# and we do want this enabled for enterprise.
+
+if env.ToolchainIs('gcc'):
+ # With GCC, use the implicit fallthrough flag variant that doesn't
+ # care about your feeble attempts to use comments to explain yourself.
+ env.AddToCCFLAGSIfSupported('-Wimplicit-fallthrough=5')
+elif env.ToolchainIs('clang'):
+ env.AddToCCFLAGSIfSupported('-Wimplicit-fallthrough')
+
# Run the core mongodb SConscript.
env.SConscript('mongo/SConscript', exports=['env'])
diff --git a/src/mongo/bson/bson_comparator_interface_base.cpp b/src/mongo/bson/bson_comparator_interface_base.cpp
index 96aaf1575a7..e0d85f3e926 100644
--- a/src/mongo/bson/bson_comparator_interface_base.cpp
+++ b/src/mongo/bson/bson_comparator_interface_base.cpp
@@ -109,6 +109,7 @@ void BSONComparatorInterfaceBase<T>::hashCombineBSONElement(
// Else, fall through and convert the decimal to a double and hash.
// At this point the decimal fits into the range of doubles, is infinity, or is NaN,
// which doubles have a cheaper representation for.
+ [[fallthrough]];
}
case mongo::NumberDouble:
case mongo::NumberLong:
diff --git a/src/mongo/bson/bsonelement.cpp b/src/mongo/bson/bsonelement.cpp
index 430b259699b..dd331399950 100644
--- a/src/mongo/bson/bsonelement.cpp
+++ b/src/mongo/bson/bsonelement.cpp
@@ -209,6 +209,7 @@ BSONObj BSONElement::_jsonStringGenerator(const Generator& g,
break;
}
// fall through if scope is empty
+ [[fallthrough]];
}
case Code:
g.writeCode(buffer, _asCode());
diff --git a/src/mongo/client/cyrus_sasl_client_session.cpp b/src/mongo/client/cyrus_sasl_client_session.cpp
index 84ae1ab0b5a..c92c4927d26 100644
--- a/src/mongo/client/cyrus_sasl_client_session.cpp
+++ b/src/mongo/client/cyrus_sasl_client_session.cpp
@@ -296,7 +296,7 @@ Status CyrusSaslClientSession::step(StringData inputData, std::string* outputDat
switch (result) {
case SASL_OK:
_success = true;
- // Fall through
+ [[fallthrough]];
case SASL_CONTINUE:
*outputData = std::string(output, outputSize);
return Status::OK();
diff --git a/src/mongo/db/catalog/collection_catalog.cpp b/src/mongo/db/catalog/collection_catalog.cpp
index 1c938446046..30a14810133 100644
--- a/src/mongo/db/catalog/collection_catalog.cpp
+++ b/src/mongo/db/catalog/collection_catalog.cpp
@@ -157,6 +157,7 @@ public:
catalog.registerCollection(opCtx, uuid, std::move(collection));
});
// Fallthrough to the createCollection case to finish committing the collection.
+ [[fallthrough]];
}
case UncommittedCatalogUpdates::Entry::Action::kCreatedCollection: {
auto collPtr = entry.collection.get();
diff --git a/src/mongo/db/exec/document_value/value.cpp b/src/mongo/db/exec/document_value/value.cpp
index 248514180f0..97573281dbb 100644
--- a/src/mongo/db/exec/document_value/value.cpp
+++ b/src/mongo/db/exec/document_value/value.cpp
@@ -908,6 +908,7 @@ void Value::hash_combine(size_t& seed,
// Else, fall through and convert the decimal to a double and hash.
// At this point the decimal fits into the range of doubles, is infinity, or is NaN,
// which doubles have a cheaper representation for.
+ [[fallthrough]];
}
// This converts all numbers to doubles, which ignores the low-order bits of
// NumberLongs > 2**53 and precise decimal numbers without double representations,
diff --git a/src/mongo/db/exec/plan_cache_util.cpp b/src/mongo/db/exec/plan_cache_util.cpp
index 166e01ba6d6..14745c4d128 100644
--- a/src/mongo/db/exec/plan_cache_util.cpp
+++ b/src/mongo/db/exec/plan_cache_util.cpp
@@ -182,6 +182,7 @@ plan_cache_debug_info::DebugInfoSBE buildDebugInfo(const QuerySolution* solution
} else {
secondaryStats.collectionScans++;
}
+ [[fallthrough]];
}
default:
break;
diff --git a/src/mongo/db/exec/sbe/vm/arith.cpp b/src/mongo/db/exec/sbe/vm/arith.cpp
index e4c67775ad8..89dc552f7f1 100644
--- a/src/mongo/db/exec/sbe/vm/arith.cpp
+++ b/src/mongo/db/exec/sbe/vm/arith.cpp
@@ -144,6 +144,7 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
false, value::TypeTags::NumberInt32, value::bitcastFrom<int32_t>(result)};
}
// The result does not fit into int32_t so fallthru to the wider type.
+ [[fallthrough]];
}
case value::TypeTags::NumberInt64: {
int64_t result;
@@ -154,6 +155,7 @@ std::tuple<bool, value::TypeTags, value::Value> genericArithmeticOp(value::TypeT
false, value::TypeTags::NumberInt64, value::bitcastFrom<int64_t>(result)};
}
// The result does not fit into int64_t so fallthru to the wider type.
+ [[fallthrough]];
}
case value::TypeTags::NumberDecimal: {
Decimal128 result;
diff --git a/src/mongo/db/exec/sbe/vm/vm.cpp b/src/mongo/db/exec/sbe/vm/vm.cpp
index a7e69fb7dee..e3e8adbffcb 100644
--- a/src/mongo/db/exec/sbe/vm/vm.cpp
+++ b/src/mongo/db/exec/sbe/vm/vm.cpp
@@ -2365,7 +2365,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoubleSum
value::TypeTags::NumberInt32,
value::bitcastFrom<int32_t>(result)};
}
- // Fall through to the larger type.
+ [[fallthrough]]; // To the larger type
}
case value::TypeTags::NumberInt64: {
if (sum.fitsLong()) {
@@ -2373,7 +2373,7 @@ std::tuple<bool, value::TypeTags, value::Value> ByteCode::builtinDoubleDoubleSum
value::TypeTags::NumberInt64,
value::bitcastFrom<int64_t>(sum.getLong())};
}
- // Fall through to the larger type.
+ [[fallthrough]]; // To the larger type.
}
case value::TypeTags::NumberDouble: {
return {false,
diff --git a/src/mongo/db/exec/trial_stage.cpp b/src/mongo/db/exec/trial_stage.cpp
index 32d303c8f7d..66442c21eda 100644
--- a/src/mongo/db/exec/trial_stage.cpp
+++ b/src/mongo/db/exec/trial_stage.cpp
@@ -119,6 +119,7 @@ PlanStage::StageState TrialStage::_workTrialPlan(WorkingSetID* out) {
// Increment the 'advanced' count and fall through into NEED_TIME so that we check for
// the end of the trial period and assess the results for both NEED_TIME and ADVANCED.
++_specificStats.trialAdvanced;
+ [[fallthrough]];
}
case PlanStage::NEED_TIME:
// Check whether we have completed the evaluation phase.
diff --git a/src/mongo/db/index/wildcard_key_generator.cpp b/src/mongo/db/index/wildcard_key_generator.cpp
index e43b2a21eb0..6aa2aa64d7b 100644
--- a/src/mongo/db/index/wildcard_key_generator.cpp
+++ b/src/mongo/db/index/wildcard_key_generator.cpp
@@ -156,6 +156,7 @@ void WildcardKeyGenerator::_traverseWildcard(SharedBufferFragmentBuilder& pooled
// Add an entry for the multi-key path, and then fall through to BSONType::Object.
_addMultiKey(pooledBufferBuilder, *path, multikeyPaths);
+ [[fallthrough]];
case BSONType::Object:
if (_addKeyForEmptyLeaf(pooledBufferBuilder, elem, *path, keys, id))
diff --git a/src/mongo/db/pipeline/document_source_group.cpp b/src/mongo/db/pipeline/document_source_group.cpp
index 4b79d54f7c2..80a2dc60488 100644
--- a/src/mongo/db/pipeline/document_source_group.cpp
+++ b/src/mongo/db/pipeline/document_source_group.cpp
@@ -211,6 +211,7 @@ DocumentSource::GetNextResult DocumentSourceGroup::getNextSpilled() {
switch (numAccumulators) { // mirrors switch in spill()
case 1: // Single accumulators serialize as a single Value.
_currentAccumulators[0]->process(_firstPartOfNextGroup.second, true);
+ [[fallthrough]];
case 0: // No accumulators so no Values.
break;
default: { // Multiple accumulators serialize as an array of Values.
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 76ec9a5debb..f6487b8e108 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -398,11 +398,11 @@ Value ExpressionAdd::evaluate(const Document& root, Variables* variables) const
dassert(nonDecimalTotal.isInteger());
if (nonDecimalTotal.fitsLong())
return Value(nonDecimalTotal.getLong());
- // Fallthrough.
+ [[fallthrough]];
case NumberInt:
if (nonDecimalTotal.fitsLong())
return Value::createIntOrLong(nonDecimalTotal.getLong());
- // Fallthrough.
+ [[fallthrough]];
case NumberDouble:
return Value(nonDecimalTotal.getDouble());
default:
diff --git a/src/mongo/db/query/canonical_query_encoder.cpp b/src/mongo/db/query/canonical_query_encoder.cpp
index f41f6827694..ee6efa914b1 100644
--- a/src/mongo/db/query/canonical_query_encoder.cpp
+++ b/src/mongo/db/query/canonical_query_encoder.cpp
@@ -133,7 +133,7 @@ void encodeUserString(StringData s, BuilderType* builder) {
} else {
*builder << '\\';
}
- // Fall through to default case.
+ [[fallthrough]];
default:
if constexpr (hasAppendChar<BuilderType>) {
builder->appendChar(c);
diff --git a/src/mongo/db/query/fle/server_rewrite.cpp b/src/mongo/db/query/fle/server_rewrite.cpp
index a69b06bc397..38e757b9123 100644
--- a/src/mongo/db/query/fle/server_rewrite.cpp
+++ b/src/mongo/db/query/fle/server_rewrite.cpp
@@ -463,6 +463,7 @@ std::unique_ptr<MatchExpression> FLEQueryRewriter::_rewrite(MatchExpression* exp
if (rewritten) {
return std::make_unique<ExprMatchExpression>(rewritten.release(), expCtx());
}
+ [[fallthrough]];
}
default:
return nullptr;
diff --git a/src/mongo/db/query/optimizer/cascades/logical_props_derivation.cpp b/src/mongo/db/query/optimizer/cascades/logical_props_derivation.cpp
index 510bad791e3..617d5a2074c 100644
--- a/src/mongo/db/query/optimizer/cascades/logical_props_derivation.cpp
+++ b/src/mongo/db/query/optimizer/cascades/logical_props_derivation.cpp
@@ -85,6 +85,7 @@ static void populateDistributionPaths(const PartialSchemaRequirements& req,
distributions.emplace(distributionAndPaths._type,
std::move(distributionProjections));
}
+ [[fallthrough]];
}
default:
diff --git a/src/mongo/db/query/optimizer/rewrites/const_eval.cpp b/src/mongo/db/query/optimizer/rewrites/const_eval.cpp
index 723bd29400d..e680406c006 100644
--- a/src/mongo/db/query/optimizer/rewrites/const_eval.cpp
+++ b/src/mongo/db/query/optimizer/rewrites/const_eval.cpp
@@ -415,6 +415,7 @@ void ConstEval::transport(ABT& n, const BinaryOp& op, ABT& lhs, ABT& rhs) {
}
}
}
+ [[fallthrough]];
}
default:
diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp
index db4e9a50e23..573fa246ea3 100644
--- a/src/mongo/db/query/sbe_stage_builder.cpp
+++ b/src/mongo/db/query/sbe_stage_builder.cpp
@@ -3088,6 +3088,7 @@ std::pair<std::unique_ptr<sbe::PlanStage>, PlanStageSlots> SlotBasedStageBuilder
childReqs.setIsBuildingUnionForTailableCollScan(true);
return makeUnionForTailableCollScan(root, childReqs);
}
+ [[fallthrough]];
default:
break;
}
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index b4a1d1e88d4..6a45d15edce 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -2025,8 +2025,8 @@ Status applyCommand_inlock(OperationContext* opCtx,
"error"_attr = status,
"oplogEntry"_attr = redact(entry.toBSONForLogging()));
}
+ [[fallthrough]];
}
- // fallthrough
case ErrorCodes::OK:
done = true;
break;
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 01818cca93b..9ae47741942 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -3604,7 +3604,8 @@ Status ReplicationCoordinatorImpl::_doReplSetReconfig(OperationContext* opCtx,
"Node not yet initialized; use the replSetInitiate command");
case kConfigReplicationDisabled:
invariant(
- false); // should be unreachable due to !_settings.usingReplSets() check above
+ false); // should be unreachable due to !_settings.usingReplSets() check above
+ [[fallthrough]]; // Placate clang.
case kConfigInitiating:
case kConfigReconfiguring:
case kConfigHBReconfiguring:
@@ -4575,7 +4576,7 @@ void ReplicationCoordinatorImpl::_performPostMemberStateUpdateAction(
break;
case kActionRollbackOrRemoved:
_externalState->closeConnections();
- /* FALLTHROUGH */
+ [[fallthrough]];
case kActionSteppedDown:
_externalState->onStepDownHook();
ReplicaSetAwareServiceRegistry::get(_service).onStepDown();
diff --git a/src/mongo/db/repl/tenant_migration_donor_access_blocker.cpp b/src/mongo/db/repl/tenant_migration_donor_access_blocker.cpp
index d74890d7e65..141b2c1e6a5 100644
--- a/src/mongo/db/repl/tenant_migration_donor_access_blocker.cpp
+++ b/src/mongo/db/repl/tenant_migration_donor_access_blocker.cpp
@@ -94,6 +94,7 @@ Status TenantMigrationDonorAccessBlocker::checkIfCanWrite(Timestamp writeTs) {
// As a sanity check, we track the highest allowed write timestamp to ensure no
// writes are allowed with a timestamp higher than the block timestamp.
_highestAllowedWriteTimestamp = std::max(writeTs, _highestAllowedWriteTimestamp);
+ [[fallthrough]];
case BlockerState::State::kAborted:
return Status::OK();
case BlockerState::State::kBlockWrites:
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
index ccda6697c83..1b9f825d3d9 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
@@ -428,8 +428,8 @@ void MigrationChunkClonerSourceLegacy::cancelClone(OperationContext* opCtx) noex
"Failed to cancel migration",
"error"_attr = redact(status));
}
+ [[fallthrough]];
}
- // Intentional fall through
case kNew:
_cleanup();
break;
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index be2b96c0657..43894e827c5 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -2103,9 +2103,10 @@ std::unique_ptr<HandleRequest::OpRunner> HandleRequest::makeOpRunner() {
case dbQuery:
if (!executionContext->nsString().isCommand())
return std::make_unique<QueryOpRunner>(this);
- // FALLTHROUGH: it's a query containing a command. Ideally, we'd like to let through
- // only hello|isMaster commands but at this point the command hasn't been parsed yet, so
- // we don't know what it is.
+ // Fallthrough because it's a query containing a command. Ideally, we'd like to let
+ // through only hello|isMaster commands but at this point the command hasn't been parsed
+ // yet, so we don't know what it is.
+ [[fallthrough]];
case dbMsg:
return std::make_unique<CommandOpRunner>(this);
case dbGetMore:
diff --git a/src/mongo/db/storage/key_string.cpp b/src/mongo/db/storage/key_string.cpp
index 908bd51908a..d4a9e8efde3 100644
--- a/src/mongo/db/storage/key_string.cpp
+++ b/src/mongo/db/storage/key_string.cpp
@@ -1658,7 +1658,7 @@ void toBsonValue(uint8_t ctype,
case CType::kNumericNegativeLargeMagnitude:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositiveLargeMagnitude: {
const uint8_t originalType = typeBits->readNumeric();
keyStringAssert(31231,
@@ -1725,7 +1725,7 @@ void toBsonValue(uint8_t ctype,
case CType::kNumericNegativeSmallMagnitude:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositiveSmallMagnitude: {
const uint8_t originalType = typeBits->readNumeric();
@@ -1856,7 +1856,7 @@ void toBsonValue(uint8_t ctype,
case CType::kNumericNegative1ByteInt:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositive1ByteInt:
case CType::kNumericPositive2ByteInt:
@@ -2105,7 +2105,7 @@ void filterKeyFromKeyString(uint8_t ctype, BufReader* reader, bool inverted, Ver
case CType::kNumericNegativeLargeMagnitude:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositiveLargeMagnitude: {
uint64_t encoded = readType<uint64_t>(reader, inverted);
encoded = endian::bigToNative(encoded);
@@ -2131,7 +2131,7 @@ void filterKeyFromKeyString(uint8_t ctype, BufReader* reader, bool inverted, Ver
case CType::kNumericNegativeSmallMagnitude:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositiveSmallMagnitude: {
uint64_t encoded = readType<uint64_t>(reader, inverted);
@@ -2193,7 +2193,7 @@ void filterKeyFromKeyString(uint8_t ctype, BufReader* reader, bool inverted, Ver
case CType::kNumericNegative1ByteInt:
inverted = !inverted;
isNegative = true;
- // fallthrough (format is the same as positive, but inverted)
+ [[fallthrough]]; // format is the same as positive, but inverted
case CType::kNumericPositive1ByteInt:
case CType::kNumericPositive2ByteInt:
@@ -2440,7 +2440,7 @@ void TypeBits::appendZero(uint8_t zeroType) {
break;
}
zeroType = kV1NegativeDoubleZero;
- // fallthrough for 5-bit encodings
+ [[fallthrough]]; // fallthrough for 5-bit encodings
case kDecimalZero0xxx:
case kDecimalZero1xxx:
case kDecimalZero2xxx:
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
index ca2e5d8c1b4..969db98506e 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
@@ -634,7 +634,7 @@ void WiredTigerRecoveryUnit::_txnOpen() {
_readAtTimestamp = _beginTransactionAtAllDurableTimestamp(session);
break;
}
- // Intentionally continue to the next case to read at the _readAtTimestamp.
+ [[fallthrough]]; // Continue to the next case to read at the _readAtTimestamp.
}
case ReadSource::kProvided: {
WiredTigerBeginTxnBlock txnOpen(
diff --git a/src/mongo/embedded/periodic_runner_embedded.cpp b/src/mongo/embedded/periodic_runner_embedded.cpp
index 68c94fa541d..87adf0842ce 100644
--- a/src/mongo/embedded/periodic_runner_embedded.cpp
+++ b/src/mongo/embedded/periodic_runner_embedded.cpp
@@ -111,11 +111,12 @@ bool PeriodicRunnerEmbedded::tryPump() {
switch (jobExecStatus) {
default:
invariant(false);
+ [[fallthrough]]; // Placate clang
case PeriodicJobImpl::ExecutionStatus::kPaused:
case PeriodicJobImpl::ExecutionStatus::kNotScheduled:
// Paused jobs should be moved to the paused list and removed from the running heap
_Pausedjobs.push_back(std::move(_jobs.back()));
- // fall through
+ [[fallthrough]];
case PeriodicJobImpl::ExecutionStatus::kCanceled:
// Cancelled jobs should be removed
_jobs.pop_back();
diff --git a/src/mongo/s/service_entry_point_mongos.cpp b/src/mongo/s/service_entry_point_mongos.cpp
index 43e2d5213f0..f2d3cb2b0ad 100644
--- a/src/mongo/s/service_entry_point_mongos.cpp
+++ b/src/mongo/s/service_entry_point_mongos.cpp
@@ -148,7 +148,7 @@ Future<DbResponse> HandleRequest::handleRequest() {
return Future<DbResponse>::makeReady(
makeErrorResponseToDeprecatedOpQuery("OP_QUERY is no longer supported"));
}
- // FALLTHROUGH: it's a query containing a command
+ [[fallthrough]]; // It's a query containing a command
case dbMsg:
return std::make_unique<CommandOpRunner>(shared_from_this())->run();
case dbGetMore: {
diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp
index ba5fa67a856..6150bb2f77b 100644
--- a/src/mongo/tools/bridge.cpp
+++ b/src/mongo/tools/bridge.cpp
@@ -388,8 +388,9 @@ Future<DbResponse> ServiceEntryPointBridge::handleRequest(OperationContext* opCt
}
return Future<DbResponse>::makeReady({Message()});
}
- // Forward the message to 'dest' after waiting for 'hostSettings.delay'
- // milliseconds.
+ // Forward the message to 'dest' after waiting for 'hostSettings.delay'
+ // milliseconds.
+ [[fallthrough]];
case HostSettings::State::kForward:
sleepmillis(durationCount<Milliseconds>(hostSettings.delay));
break;
diff --git a/src/mongo/unittest/unittest.cpp b/src/mongo/unittest/unittest.cpp
index 94adc7f1046..219726d8b29 100644
--- a/src/mongo/unittest/unittest.cpp
+++ b/src/mongo/unittest/unittest.cpp
@@ -336,6 +336,12 @@ bool isSubset(BSONObj haystack, BSONObj needle) {
case Array:
// not supported
invariant(false);
+ // This annotation shouldn't really be needed because
+ // `invariantFailed` is annotated to be `noreturn`,
+ // but clang 12 doesn't seem to be able to capitalize
+ // on that fact to see that we are not actually
+ // falling through.
+ [[fallthrough]];
default:
if (SimpleBSONElementComparator::kInstance.compare(foundElement, element) != 0) {
return false;
diff --git a/src/mongo/util/net/ssl/detail/io.hpp b/src/mongo/util/net/ssl/detail/io.hpp
index 90453c3d8e8..b48f7dbc3ec 100644
--- a/src/mongo/util/net/ssl/detail/io.hpp
+++ b/src/mongo/util/net/ssl/detail/io.hpp
@@ -214,6 +214,7 @@ public:
break;
}
}
+ [[fallthrough]];
default:
if (bytes_transferred == ~std::size_t(0))
@@ -248,7 +249,7 @@ public:
core_.pending_write_.expires_at(core_.neg_infin());
// Fall through to call handler.
-
+ [[fallthrough]];
default:
// Pass the result to the handler.
diff --git a/src/third_party/boost/boost/date_time/time_facet.hpp b/src/third_party/boost/boost/date_time/time_facet.hpp
index eaa365913a3..0b740216957 100644
--- a/src/third_party/boost/boost/date_time/time_facet.hpp
+++ b/src/third_party/boost/boost/date_time/time_facet.hpp
@@ -1140,6 +1140,9 @@ namespace date_time {
// %s is the same as %S%f so we drop through into %f if we are
// not at the end of the stream
}
+ // MONGODB MODIFICATION: Without this we can't use
+ // the automated fallthrough detection.
+ BOOST_FALLTHROUGH;
/* Falls through. */
case 'f':
{
diff --git a/src/third_party/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp b/src/third_party/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp
index 0ece2808910..2aadcdd74ab 100644
--- a/src/third_party/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp
+++ b/src/third_party/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp
@@ -119,6 +119,12 @@ namespace boost { namespace property_tree {
case object:
default:
BOOST_ASSERT(false); // must start with string, i.e. call new_value
+ // MONGODB MODIFICATION: The use of `BOOST_ASSERT(false)` above is probably a bug,
+ // because falling through into the `key` case doesn't look like what we ought to
+ // do, and that is what would happen if BOOST_ASSERT was disabled. However, we honor
+ // the behavior of the code as written, and add a fallthrough annotation so we can
+ // make use of it in our own code.
+ BOOST_FALLTHROUGH;
case key: {
l.t->push_back(std::make_pair(key_buffer, Ptree()));
l.k = object;