Bug 1570499 - Part 1: Replace MOZ_FALLTHROUGH macro with C++17's [[fallthrough]] attribute. r=froydnj
authorChris Peterson <cpeterson@mozilla.com>
Fri, 20 Dec 2019 07:16:43 +0000
changeset 507983 68b0f6bd38ad89654bde1da2f3755597f6807a43
parent 507982 96684cc146fe5411122c60f537846af24f33ddd3
child 507984 1802196cadec4a90f4aa21f9ac2fed0ab2bbed58
push id36935
push usercsabou@mozilla.com
push dateFri, 20 Dec 2019 15:52:27 +0000
treeherdermozilla-central@028b40d8140c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1570499
milestone73.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1570499 - Part 1: Replace MOZ_FALLTHROUGH macro with C++17's [[fallthrough]] attribute. r=froydnj This changeset is a simple find and replace of `MOZ_FALLTHROUGH` and `[[fallthrough]]`. Unfortunately, the MOZ_FALLTHROUGH_ASSERT macro (to assert on case fallthrough in debug builds) is still necessary after switching from [[clang::fallthrough]] to [[fallthrough]] because: * MOZ_ASSERT(false) followed by [[fallthrough]] triggers a -Wunreachable-code warning in DEBUG builds * but MOZ_ASSERT(false) without [[fallthrough]] triggers a -Wimplicit-fallthrough warning in NDEBUG builds. Differential Revision: https://phabricator.services.mozilla.com/D56440
docshell/base/nsDocShell.cpp
dom/base/Document.cpp
dom/base/Element.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsXMLContentSerializer.cpp
dom/bindings/Codegen.py
dom/canvas/WebGL2ContextState.cpp
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLQuery.cpp
dom/events/EventStateManager.cpp
dom/html/HTMLInputElement.cpp
dom/media/AudioConfig.cpp
dom/media/MediaManager.cpp
dom/media/encoder/Muxer.cpp
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/mp4/MP4Demuxer.cpp
dom/media/platforms/android/AndroidDataEncoder.cpp
dom/media/platforms/apple/AppleVTEncoder.cpp
dom/media/webaudio/MediaBufferDecoder.cpp
dom/media/webm/WebMBufferedParser.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/quota/Client.cpp
dom/smil/SMILParserUtils.cpp
dom/storage/StorageDBThread.cpp
dom/storage/StorageDBUpdater.cpp
dom/svg/SVGPathSegListSMILType.cpp
dom/svg/SVGTransformListParser.cpp
dom/system/linux/GpsdLocationProvider.cpp
dom/xslt/xpath/txLocationStep.cpp
dom/xslt/xslt/txOutputFormat.cpp
editor/libeditor/EditorEventListener.cpp
extensions/permissions/nsPermissionManager.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/GestureEventListener.cpp
gfx/layers/apz/util/APZEventState.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxTextRun.cpp
gfx/vr/VRPuppetCommandBuffer.cpp
hal/linux/UPowerClient.cpp
image/AnimationSurfaceProvider.cpp
image/decoders/nsJPEGDecoder.cpp
intl/unicharutil/util/GreekCasing.cpp
js/src/builtin/ReflectParse.cpp
js/src/builtin/String.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/NameFunctions.cpp
js/src/frontend/Parser.cpp
js/src/frontend/TokenStream.cpp
js/src/gc/GC.cpp
js/src/irregexp/RegExpEngine.cpp
js/src/irregexp/RegExpParser.cpp
js/src/jit/BaselineBailouts.cpp
js/src/jit/CacheIR.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/Lowering.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/RangeAnalysis.cpp
js/src/jit/arm/disasm/Disasm-arm.cpp
js/src/jit/mips32/MoveEmitter-mips32.cpp
js/src/jit/mips32/Simulator-mips32.cpp
js/src/jit/mips32/Trampoline-mips32.cpp
js/src/jit/mips64/Simulator-mips64.cpp
js/src/new-regexp/regexp-shim.h
js/src/shell/js.cpp
js/src/util/DoubleToString.cpp
js/src/wasm/WasmBaselineCompile.cpp
js/src/wasm/WasmTextToBinary.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCShellImpl.cpp
layout/base/PresShell.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/generic/CSSAlignUtils.cpp
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFloatManager.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsLineLayout.cpp
layout/generic/nsTextFrame.cpp
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/printing/PrintPreviewUserEventSuppressor.cpp
layout/style/ImageLoader.cpp
layout/tables/SpanningCellSorter.cpp
layout/tables/nsCellMap.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/xul/nsXULPopupManager.cpp
media/mtransport/transportlayerdtls.cpp
mfbt/Assertions.h
modules/libjar/nsJARInputStream.cpp
mozglue/linker/XZStream.cpp
mozglue/misc/Printf.cpp
netwerk/base/nsStandardURL.cpp
netwerk/base/nsURLHelper.cpp
netwerk/cache2/CacheHashUtils.cpp
netwerk/cache2/CacheIndex.cpp
netwerk/cache2/CacheStorageService.cpp
netwerk/cookie/nsCookiePermission.cpp
netwerk/cookie/nsCookieService.cpp
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
netwerk/streamconv/converters/nsHTTPCompressConv.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
parser/html/nsHtml5Highlighter.cpp
security/sandbox/linux/SandboxFilter.cpp
storage/mozStoragePrivateHelpers.cpp
toolkit/components/antitracking/AntiTrackingCommon.cpp
toolkit/components/places/nsAnnotationService.cpp
toolkit/components/places/nsNavHistoryResult.cpp
toolkit/components/satchel/nsFormFillController.cpp
toolkit/mozapps/update/updater/updater.cpp
toolkit/recordreplay/ProcessRedirect.cpp
tools/fuzzing/faulty/Faulty.cpp
tools/power/rapl.cpp
uriloader/exthandler/nsExternalHelperAppService.cpp
widget/GfxDriverInfo.cpp
widget/GfxInfoBase.cpp
widget/WidgetEventImpl.cpp
widget/cocoa/nsChildView.mm
widget/cocoa/nsLookAndFeel.mm
widget/cocoa/nsNativeThemeCocoa.mm
widget/gtk/nsNativeThemeGTK.cpp
widget/windows/KeyboardLayout.cpp
widget/windows/TSFTextStore.cpp
widget/windows/nsWindow.cpp
xpcom/base/MemoryInfo.cpp
xpcom/base/nsDebugImpl.cpp
xpcom/ds/nsCheapSets.h
xpcom/ds/nsPersistentProperties.cpp
xpcom/ds/nsVariant.cpp
xpcom/io/nsWildCard.cpp
xpcom/string/nsTextFormatter.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -10131,17 +10131,17 @@ nsresult nsDocShell::DoChannelLoad(nsICh
       }
       break;
     }
 
     case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE:
     case LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE:
       loadFlags |=
           nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::LOAD_FRESH_CONNECTION;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case LOAD_RELOAD_CHARSET_CHANGE: {
       // Use SetAllowStaleCacheContent (not LOAD_FROM_CACHE flag) since we
       // only want to force cache load for this channel, not the whole
       // loadGroup.
       nsCOMPtr<nsICacheInfoChannel> cachingChannel =
           do_QueryInterface(aChannel);
       if (cachingChannel) {
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -9242,17 +9242,17 @@ nsINode* Document::AdoptNode(nsINode& aA
 
       break;
     }
     case DOCUMENT_FRAGMENT_NODE: {
       if (adoptedNode->IsShadowRoot()) {
         rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
         return nullptr;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case ELEMENT_NODE:
     case PROCESSING_INSTRUCTION_NODE:
     case TEXT_NODE:
     case CDATA_SECTION_NODE:
     case COMMENT_NODE:
     case DOCUMENT_TYPE_NODE: {
       // Don't allow adopting a node's anonymous subtree out from under it.
@@ -9578,17 +9578,17 @@ nsViewportInfo Document::GetViewportInfo
       }
       if (!metaData.mUserScalable.IsEmpty()) {
         hasValidContents = true;
       }
 
       mWidthStrEmpty = metaData.mWidth.IsEmpty();
 
       mViewportType = hasValidContents ? Specified : NoValidContent;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case Specified:
     case NoValidContent:
     default:
       LayoutDeviceToScreenScale effectiveMinScale = mScaleMinFloat;
       LayoutDeviceToScreenScale effectiveMaxScale = mScaleMaxFloat;
       bool effectiveValidMaxScale = mValidMaxScale;
 
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2800,32 +2800,32 @@ void Element::GetEventTargetParentForLin
 
   // We do the status bar updates in GetEventTargetParent so that the status bar
   // gets updated even if the event is consumed before we have a chance to set
   // it.
   switch (aVisitor.mEvent->mMessage) {
     // Set the status bar similarly for mouseover and focus
     case eMouseOver:
       aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eFocus: {
       InternalFocusEvent* focusEvent = aVisitor.mEvent->AsFocusEvent();
       if (!focusEvent || !focusEvent->mIsRefocus) {
         nsAutoString target;
         GetLinkTarget(target);
         nsContentUtils::TriggerLink(this, absURI, target,
                                     /* click */ false, /* isTrusted */ true);
         // Make sure any ancestor links don't also TriggerLink
         aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
       }
       break;
     }
     case eMouseOut:
       aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eBlur: {
       nsresult rv = LeaveLink(aVisitor.mPresContext);
       if (NS_SUCCEEDED(rv)) {
         aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
       }
       break;
     }
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1877,17 +1877,17 @@ static bool CCRunnerFired(TimeStamp aDea
       }
 
       // If we're called during idle time, try to find some work to do by
       // advancing to the next state, effectively bypassing some possible forget
       // skippable calls.
       MOZ_ASSERT(!didDoWork);
 
       sCCRunnerState = CCRunnerState::LateTimer;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case CCRunnerState::LateTimer:
       if (!ShouldTriggerCC(suspected)) {
         if (ShouldFireForgetSkippable(suspected)) {
           FireForgetSkippable(suspected, /* aRemoveChildless = */ false,
                               aDeadline);
           didDoWork = true;
         }
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -1394,17 +1394,17 @@ bool nsXMLContentSerializer::AppendForma
   bool sawBlankOrTab = false;
   bool leaveLoop = false;
 
   do {
     switch (*aPos) {
       case ' ':
       case '\t':
         sawBlankOrTab = true;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case '\n':
         ++aPos;
         // do not increase mColPos,
         // because we will reduce the whitespace to a single char
         break;
       default:
         leaveLoop = true;
         break;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8333,17 +8333,17 @@ class CGCase(CGList):
     the body (allowed to be None if there is no body), and an optional
     argument (defaulting to False) for whether to fall through.
     """
     def __init__(self, expression, body, fallThrough=False):
         CGList.__init__(self, [])
         self.append(CGGeneric("case " + expression + ": {\n"))
         bodyList = CGList([body])
         if fallThrough:
-            bodyList.append(CGGeneric("MOZ_FALLTHROUGH;\n"))
+            bodyList.append(CGGeneric("[[fallthrough]];\n"))
         else:
             bodyList.append(CGGeneric("break;\n"))
         self.append(CGIndenter(bodyList))
         self.append(CGGeneric("}\n"))
 
 
 class CGMethodCall(CGThing):
     """
--- a/dom/canvas/WebGL2ContextState.cpp
+++ b/dom/canvas/WebGL2ContextState.cpp
@@ -113,17 +113,17 @@ JS::Value WebGL2Context::GetParameter(JS
 
     case LOCAL_GL_MAX_ELEMENT_INDEX:
       // GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
       // compatibility
       if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
         return JS::NumberValue(UINT32_MAX);
 
       /*** fall through to fGetInteger64v ***/
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
     case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
     case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
       GLint64 val;
       gl->fGetInteger64v(pname, &val);
       return JS::DoubleValue(static_cast<double>(val));
     }
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -891,17 +891,17 @@ JS::Value WebGLContext::GetRenderbufferP
   if (!mBoundRenderbuffer) {
     ErrorInvalidOperation("No renderbuffer is bound.");
     return JS::NullValue();
   }
 
   switch (pname) {
     case LOCAL_GL_RENDERBUFFER_SAMPLES:
       if (!IsWebGL2()) break;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case LOCAL_GL_RENDERBUFFER_WIDTH:
     case LOCAL_GL_RENDERBUFFER_HEIGHT:
     case LOCAL_GL_RENDERBUFFER_RED_SIZE:
     case LOCAL_GL_RENDERBUFFER_GREEN_SIZE:
     case LOCAL_GL_RENDERBUFFER_BLUE_SIZE:
     case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
     case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE:
--- a/dom/canvas/WebGLQuery.cpp
+++ b/dom/canvas/WebGLQuery.cpp
@@ -136,17 +136,17 @@ void WebGLQuery::GetQueryParameter(GLenu
     case LOCAL_GL_QUERY_RESULT:
       switch (mTarget) {
         case LOCAL_GL_TIME_ELAPSED_EXT:
         case LOCAL_GL_TIMESTAMP_EXT:
           if (mContext->Has64BitTimestamps()) {
             gl->fGetQueryObjectui64v(mGLName, pname, &val);
             break;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         default:
           gl->fGetQueryObjectuiv(mGLName, LOCAL_GL_QUERY_RESULT, (GLuint*)&val);
           break;
       }
 
       switch (mTarget) {
         case LOCAL_GL_ANY_SAMPLES_PASSED:
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -594,17 +594,17 @@ nsresult EventStateManager::PreHandleEve
         case MouseButton::eLeft:
           if (Prefs::ClickHoldContextMenu()) {
             KillClickHoldTimer();
           }
           mInTouchDrag = false;
           StopTrackingDragGesture(true);
           sNormalLMouseEventInProcess = false;
           // then fall through...
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case MouseButton::eRight:
         case MouseButton::eMiddle:
           RefPtr<EventStateManager> esm =
               ESMFromContentOrThis(aOverrideClickTarget);
           esm->SetClickCount(mouseEvent, aStatus, aOverrideClickTarget);
           break;
       }
       break;
@@ -649,26 +649,26 @@ nsresult EventStateManager::PreHandleEve
       } else {
         // We should synthetize corresponding pointer events
         GeneratePointerEnterExit(ePointerLeave, mouseEvent);
         GenerateMouseEnterExit(mouseEvent);
         // This is a window level mouse exit event and should stop here
         aEvent->mMessage = eVoidEvent;
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eMouseMove:
     case ePointerDown:
       if (aEvent->mMessage == ePointerDown) {
         PointerEventHandler::ImplicitlyCapturePointer(aTargetFrame, aEvent);
         if (mouseEvent->mInputSource != MouseEvent_Binding::MOZ_SOURCE_TOUCH) {
           NotifyTargetUserActivation(aEvent, aTargetContent);
         }
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ePointerMove: {
       // on the Mac, GenerateDragGesture() may not return until the drag
       // has completed and so |aTargetFrame| may have been deleted (moving
       // a bookmark, for example).  If this is the case, however, we know
       // that ClearFrameRefs() has been called and it cleared out
       // |mCurrentTarget|. As a result, we should pass |mCurrentTarget|
       // into UpdateCursor().
       if (!mInTouchDrag) {
@@ -734,22 +734,22 @@ nsresult EventStateManager::PreHandleEve
 
           if (HandleAccessKey(keyEvent, aPresContext, accessCharCodes)) {
             *aStatus = nsEventStatus_eConsumeNoDefault;
           }
         }
       }
     }
       // then fall through...
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eKeyDown:
       if (aEvent->mMessage == eKeyDown) {
         NotifyTargetUserActivation(aEvent, aTargetContent);
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eKeyUp: {
       nsIContent* content = GetFocusedContent();
       if (content) mCurrentTargetContent = content;
 
       // NOTE: Don't refer TextComposition::IsComposing() since UI Events
       //       defines that KeyboardEvent.isComposing is true when it's
       //       dispatched after compositionstart and compositionend.
       //       TextComposition::IsComposing() is false even before
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3882,17 +3882,17 @@ nsresult HTMLInputElement::PostHandleEve
               case NS_FORM_INPUT_RADIO: {
                 // Checkbox and Radio try to submit on Enter press
                 if (keyEvent->mKeyCode != NS_VK_SPACE) {
                   MaybeSubmitForm(MOZ_KnownLive(aVisitor.mPresContext));
 
                   break;  // If we are submitting, do not send click event
                 }
                 // else fall through and treat Space like click...
-                MOZ_FALLTHROUGH;
+                [[fallthrough]];
               }
               case NS_FORM_INPUT_BUTTON:
               case NS_FORM_INPUT_RESET:
               case NS_FORM_INPUT_SUBMIT:
               case NS_FORM_INPUT_FILE:
               case NS_FORM_INPUT_IMAGE:  // Bug 34418
               case NS_FORM_INPUT_COLOR: {
                 DispatchSimulatedClick(this, aVisitor.mEvent->IsTrusted(),
@@ -3904,17 +3904,17 @@ nsresult HTMLInputElement::PostHandleEve
           if (aVisitor.mEvent->mMessage == eKeyPress &&
               mType == NS_FORM_INPUT_RADIO && !keyEvent->IsAlt() &&
               !keyEvent->IsControl() && !keyEvent->IsMeta()) {
             bool isMovingBack = false;
             switch (keyEvent->mKeyCode) {
               case NS_VK_UP:
               case NS_VK_LEFT:
                 isMovingBack = true;
-                MOZ_FALLTHROUGH;
+                [[fallthrough]];
               case NS_VK_DOWN:
               case NS_VK_RIGHT:
                 // Arrow key pressed, focus+select prev/next radio button
                 nsIRadioGroupContainer* container = GetRadioGroupContainer();
                 if (container) {
                   nsAutoString name;
                   GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
                   RefPtr<HTMLInputElement> selectedRadioButton;
--- a/dom/media/AudioConfig.cpp
+++ b/dom/media/AudioConfig.cpp
@@ -275,46 +275,46 @@ bool AudioConfig::ChannelLayout::Mapping
 /* static */
 uint32_t AudioConfig::SampleSize(AudioConfig::SampleFormat aFormat) {
   switch (aFormat) {
     case FORMAT_U8:
       return 1;
     case FORMAT_S16:
       return 2;
     case FORMAT_S24:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case FORMAT_S24LSB:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case FORMAT_S32:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case FORMAT_FLT:
       return 4;
     case FORMAT_NONE:
     default:
       return 0;
   }
 }
 
 /* static */
 uint32_t AudioConfig::FormatToBits(AudioConfig::SampleFormat aFormat) {
   switch (aFormat) {
     case FORMAT_U8:
       return 8;
     case FORMAT_S16:
       return 16;
     case FORMAT_S24LSB:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case FORMAT_S24:
       return 24;
     case FORMAT_S32:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case FORMAT_FLT:
       return 32;
     case FORMAT_NONE:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       return 0;
   }
 }
 
 AudioConfig::AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
                          AudioConfig::SampleFormat aFormat, bool aInterleaved)
     : mChannelLayout(aChannelLayout),
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -2400,17 +2400,17 @@ RefPtr<MediaManager::StreamPromise> Medi
       case MediaSourceEnum::Browser:
         // If no window id is passed in then default to the caller's window.
         // Functional defaults are helpful in tests, but also a natural outcome
         // of the constraints API's limited semantics for requiring input.
         if (!vc.mBrowserWindow.WasPassed()) {
           nsPIDOMWindowOuter* outer = aWindow->GetOuterWindow();
           vc.mBrowserWindow.Construct(outer->WindowID());
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case MediaSourceEnum::Screen:
       case MediaSourceEnum::Window:
         // Deny screensharing request if support is disabled, or
         // the requesting document is not from a host on the whitelist.
         if (!Preferences::GetBool(
                 ((videoType == MediaSourceEnum::Browser)
                      ? "media.getusermedia.browser.enabled"
                      : "media.getusermedia.screensharing.enabled"),
--- a/dom/media/encoder/Muxer.cpp
+++ b/dom/media/encoder/Muxer.cpp
@@ -32,17 +32,17 @@ nsresult Muxer::SetMetadata(
         // In the case of Opus we need to calculate the codec delay based on the
         // pre-skip. For more information see:
         // https://tools.ietf.org/html/rfc7845#section-4.2
         // Calculate offset in microseconds
         OpusMetadata* opusMeta = static_cast<OpusMetadata*>(track.get());
         mAudioCodecDelay = static_cast<uint64_t>(
             LittleEndian::readUint16(opusMeta->mIdHeader.Elements() + 10) *
             PR_USEC_PER_SEC / 48000);
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       }
       case TrackMetadataBase::METADATA_VORBIS:
       case TrackMetadataBase::METADATA_AAC:
       case TrackMetadataBase::METADATA_AMR:
       case TrackMetadataBase::METADATA_EVRC:
         MOZ_ASSERT(!mHasAudio, "Only one audio track supported");
         mHasAudio = true;
         break;
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -743,24 +743,24 @@ mozilla::ipc::IPCResult ChromiumCDMChild
       // key status changing to "output-restricted", and is supposed to switch
       // to a stream that doesn't require OP. In order to keep the playback
       // pipeline rolling, just output a black frame. See bug 1343140.
       if (!frame.InitToBlack(mCodedSize.width, mCodedSize.height,
                              input.timestamp)) {
         Unused << SendDecodeFailed(cdm::kDecodeError);
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case cdm::kSuccess:
       if (frame.FrameBuffer()) {
         ReturnOutput(frame);
         break;
       }
       // CDM didn't set a frame buffer on the sample, report it as an error.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       Unused << SendDecodeFailed(rv);
       break;
   }
 
   return IPC_OK();
 }
 
--- a/dom/media/mp4/MP4Demuxer.cpp
+++ b/dom/media/mp4/MP4Demuxer.cpp
@@ -387,17 +387,17 @@ already_AddRefed<MediaRawData> MP4TrackD
     return nullptr;
   }
   if (mInfo->GetAsVideoInfo()) {
     sample->mExtraData = mInfo->GetAsVideoInfo()->mExtraData;
     if (mType == kH264 && !sample->mCrypto.IsEncrypted()) {
       H264::FrameType type = H264::GetFrameType(sample);
       switch (type) {
         case H264::FrameType::I_FRAME:
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case H264::FrameType::OTHER: {
           bool keyframe = type == H264::FrameType::I_FRAME;
           if (sample->mKeyframe != keyframe) {
             NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe "
                                        "@ pts:%" PRId64 " dur:%" PRId64
                                        " dts:%" PRId64,
                                        keyframe ? "" : "non-",
                                        sample->mTime.ToMicroseconds(),
--- a/dom/media/platforms/android/AndroidDataEncoder.cpp
+++ b/dom/media/platforms/android/AndroidDataEncoder.cpp
@@ -368,22 +368,22 @@ RefPtr<MediaDataEncoder::EncodePromise> 
 
   REJECT_IF_ERROR();
 
   switch (mDrainState) {
     case DrainState::DRAINABLE:
       mInputBufferInfo->Set(0, 0, -1, MediaCodec::BUFFER_FLAG_END_OF_STREAM);
       mJavaEncoder->Input(nullptr, mInputBufferInfo, nullptr);
       mDrainState = DrainState::DRAINING;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case DrainState::DRAINING:
       if (mEncodedData.IsEmpty()) {
         return mDrainPromise.Ensure(__func__);  // Pending promise.
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case DrainState::DRAINED:
       if (mEncodedData.Length() > 0) {
         EncodedData pending;
         pending.SwapElements(mEncodedData);
         return EncodePromise::CreateAndResolve(std::move(pending), __func__);
       } else {
         return EncodePromise::CreateAndResolve(EncodedData(), __func__);
       }
--- a/dom/media/platforms/apple/AppleVTEncoder.cpp
+++ b/dom/media/platforms/apple/AppleVTEncoder.cpp
@@ -513,23 +513,23 @@ CVPixelBufferRef AppleVTEncoder::CreateC
   size_t heights[3] = {};
   size_t strides[3] = {};
   switch (numPlanes) {
     case 3:
       addresses[2] = yuv->mCrChannel;
       widths[2] = yuv->mCbCrSize.width;
       heights[2] = yuv->mCbCrSize.height;
       strides[2] = yuv->mCbCrStride;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       addresses[1] = yuv->mCbChannel;
       widths[1] = yuv->mCbCrSize.width;
       heights[1] = yuv->mCbCrSize.height;
       strides[1] = yuv->mCbCrStride;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       addresses[0] = yuv->mYChannel;
       widths[0] = yuv->mYSize.width;
       heights[0] = yuv->mYSize.height;
       strides[0] = yuv->mYStride;
       break;
     default:
       return nullptr;
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -688,17 +688,17 @@ void WebAudioDecodeJob::OnFailure(ErrorC
     case NoAudio:
       errorMessage = "MediaDecodeAudioDataNoAudio";
       break;
     case NoError:
       MOZ_FALLTHROUGH_ASSERT("Who passed NoError to OnFailure?");
       // Fall through to get some sort of a sane error message if this actually
       // happens at runtime.
     case UnknownError:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       errorMessage = "MediaDecodeAudioDataUnknownError";
       break;
   }
 
   Document* doc = nullptr;
   if (nsPIDOMWindowInner* pWindow = mContext->GetParentObject()) {
     doc = pWindow->GetExtantDoc();
--- a/dom/media/webm/WebMBufferedParser.cpp
+++ b/dom/media/webm/WebMBufferedParser.cpp
@@ -141,17 +141,17 @@ bool WebMBufferedParser::Append(const un
           case TRACKS_ID:
             mSkipBytes = mElement.mSize.mValue;
             mState = CHECK_INIT_FOUND;
             break;
           case EBML_ID:
             mLastInitStartOffset =
                 mCurrentOffset + (p - aBuffer) -
                 (mElement.mID.mLength + mElement.mSize.mLength);
-            MOZ_FALLTHROUGH;
+            [[fallthrough]];
           default:
             mSkipBytes = mElement.mSize.mValue;
             mState = SKIP_DATA;
             mNextState = READ_ELEMENT_ID;
             break;
         }
         break;
       case READ_VINT: {
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1487,17 +1487,17 @@ NPError _getvalue(NPP npp, NPNVariable v
 
     // we no longer hand out any XPCOM objects
     case NPNVDOMElement:
     case NPNVDOMWindow:
     case NPNVserviceManager:
       // old XPCOM objects, no longer supported, but null out the out
       // param to avoid crashing plugins that still try to use this.
       *(nsISupports**)result = nullptr;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     default:
       NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
                      ("NPN_getvalue unhandled get value: %d\n", variable));
       return NPERR_GENERIC_ERROR;
   }
 }
 
--- a/dom/quota/Client.cpp
+++ b/dom/quota/Client.cpp
@@ -103,17 +103,17 @@ bool TypeTo_impl(Client::Type aType, T& 
       ClientTypeTraits<Client::Type::SDB>::To(aData);
       return true;
 
     case Client::LS:
       if (CachedNextGenLocalStorageEnabled()) {
         ClientTypeTraits<Client::Type::LS>::To(aData);
         return true;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case Client::TYPE_MAX:
     default:
       return false;
   }
 
   MOZ_CRASH("Should never get here!");
 }
--- a/dom/smil/SMILParserUtils.cpp
+++ b/dom/smil/SMILParserUtils.cpp
@@ -170,17 +170,17 @@ bool ParseClockValue(RangedPtr<const cha
   uint32_t minutes, seconds, multiplier;
 
   switch (clockType) {
     case FULL_CLOCK_VALUE:
       if (!SVGContentUtils::ParseInteger(iter, aEnd, hours) ||
           !ParseColon(iter, aEnd)) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case PARTIAL_CLOCK_VALUE:
       if (!ParseSecondsOrMinutes(iter, aEnd, minutes) ||
           !ParseColon(iter, aEnd) ||
           !ParseSecondsOrMinutes(iter, aEnd, seconds)) {
         return false;
       }
       if (iter != aEnd && (*iter != '.' || !SVGContentUtils::ParseNumber(
                                                iter, aEnd, fraction))) {
--- a/dom/storage/StorageDBThread.cpp
+++ b/dom/storage/StorageDBThread.cpp
@@ -355,17 +355,17 @@ nsresult StorageDBThread::InsertDBOp(Sto
         // We need to do this to prevent load of the DB data before the scope
         // has actually been cleared from the database.  Preloads are processed
         // immediately before update and clear operations on the database that
         // are flushed periodically in batches.
         MonitorAutoUnlock unlock(mThreadObserver->GetMonitor());
         aOperation->Finalize(NS_OK);
         return NS_OK;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case DBOperation::opGetUsage:
       if (aOperation->Type() == DBOperation::opPreloadUrgent) {
         SetHigherPriority();  // Dropped back after urgent preload execution
         mPreloads.InsertElementAt(0, aOperation);
       } else {
         mPreloads.AppendElement(aOperation);
       }
--- a/dom/storage/StorageDBUpdater.cpp
+++ b/dom/storage/StorageDBUpdater.cpp
@@ -414,17 +414,17 @@ nsresult Update(mozIStorageConnection* a
 
       aWorkerConnection->RemoveFunction(
           NS_LITERAL_CSTRING("GET_ORIGIN_SUFFIX"));
       aWorkerConnection->RemoveFunction(NS_LITERAL_CSTRING("GET_ORIGIN_KEY"));
 
       rv = aWorkerConnection->SetSchemaVersion(1);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case 1: {
       nsCOMPtr<mozIStorageFunction> oaStripAddonId(new StripOriginAddonId());
       rv = aWorkerConnection->CreateFunction(
           NS_LITERAL_CSTRING("STRIP_ADDON_ID"), 1, oaStripAddonId);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = aWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
@@ -433,17 +433,17 @@ nsresult Update(mozIStorageConnection* a
           "WHERE originAttributes LIKE '^%'"));
       NS_ENSURE_SUCCESS(rv, rv);
 
       aWorkerConnection->RemoveFunction(NS_LITERAL_CSTRING("STRIP_ADDON_ID"));
 
       rv = aWorkerConnection->SetSchemaVersion(2);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case CURRENT_SCHEMA_VERSION:
       // Ensure the tables and indexes are up.  This is mostly a no-op
       // in common scenarios.
       rv = CreateSchema1Tables(aWorkerConnection);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Nothing more to do here, this is the current schema version
--- a/dom/svg/SVGPathSegListSMILType.cpp
+++ b/dom/svg/SVGPathSegListSMILType.cpp
@@ -323,25 +323,25 @@ static void ConvertPathSegmentData(SVGPa
       aResult[7] = aStart[7];
       AdjustSegmentForRelativeness(adjustmentType, aResult + 6, aState);
       break;
     case PATHSEG_CURVETO_CUBIC_ABS:
     case PATHSEG_CURVETO_CUBIC_REL:
       aResult[5] = aStart[5];
       aResult[6] = aStart[6];
       AdjustSegmentForRelativeness(adjustmentType, aResult + 5, aState);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case PATHSEG_CURVETO_QUADRATIC_ABS:
     case PATHSEG_CURVETO_QUADRATIC_REL:
     case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
     case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
       aResult[3] = aStart[3];
       aResult[4] = aStart[4];
       AdjustSegmentForRelativeness(adjustmentType, aResult + 3, aState);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case PATHSEG_MOVETO_ABS:
     case PATHSEG_MOVETO_REL:
     case PATHSEG_LINETO_ABS:
     case PATHSEG_LINETO_REL:
     case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
     case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
       aResult[1] = aStart[1];
       aResult[2] = aStart[2];
--- a/dom/svg/SVGTransformListParser.cpp
+++ b/dom/svg/SVGTransformListParser.cpp
@@ -128,17 +128,17 @@ bool SVGTransformListParser::ParseTransl
 
   if (!ParseArguments(t, ArrayLength(t), &count)) {
     return false;
   }
 
   switch (count) {
     case 1:
       t[1] = 0.f;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2: {
       SVGTransform* transform = mTransforms.AppendElement(fallible);
       if (!transform) {
         return false;
       }
       transform->SetTranslate(t[0], t[1]);
       return true;
     }
@@ -153,17 +153,17 @@ bool SVGTransformListParser::ParseScale(
 
   if (!ParseArguments(s, ArrayLength(s), &count)) {
     return false;
   }
 
   switch (count) {
     case 1:
       s[1] = s[0];
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2: {
       SVGTransform* transform = mTransforms.AppendElement(fallible);
       if (!transform) {
         return false;
       }
       transform->SetScale(s[0], s[1]);
       return true;
     }
@@ -178,17 +178,17 @@ bool SVGTransformListParser::ParseRotate
 
   if (!ParseArguments(r, ArrayLength(r), &count)) {
     return false;
   }
 
   switch (count) {
     case 1:
       r[1] = r[2] = 0.f;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 3: {
       SVGTransform* transform = mTransforms.AppendElement(fallible);
       if (!transform) {
         return false;
       }
       transform->SetRotate(r[0], r[1], r[2]);
       return true;
     }
--- a/dom/system/linux/GpsdLocationProvider.cpp
+++ b/dom/system/linux/GpsdLocationProvider.cpp
@@ -229,17 +229,17 @@ class GpsdLocationProvider::PollRunnable
         continue;
       }
 
       switch (gpsData.fix.mode) {
         case MODE_3D:
           if (!IsNaN(gpsData.fix.altitude)) {
             alt = gpsData.fix.altitude;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case MODE_2D:
           if (!IsNaN(gpsData.fix.latitude)) {
             lat = gpsData.fix.latitude;
           }
           if (!IsNaN(gpsData.fix.longitude)) {
             lon = gpsData.fix.longitude;
           }
           if (!IsNaN(gpsData.fix.epx) && !IsNaN(gpsData.fix.epy)) {
@@ -279,23 +279,23 @@ class GpsdLocationProvider::PollRunnable
 #else
     return GeolocationPositionError_Binding::POSITION_UNAVAILABLE;
 #endif  // GPSD_MAJOR_API_VERSION
   }
 
   static int ErrnoToError(int aErrno) {
     switch (aErrno) {
       case EACCES:
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case EPERM:
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case EROFS:
         return GeolocationPositionError_Binding::PERMISSION_DENIED;
       case ETIME:
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case ETIMEDOUT:
         return GeolocationPositionError_Binding::TIMEOUT;
       default:
         return GeolocationPositionError_Binding::POSITION_UNAVAILABLE;
     }
   }
 
  private:
--- a/dom/xslt/xpath/txLocationStep.cpp
+++ b/dom/xslt/xpath/txLocationStep.cpp
@@ -35,17 +35,17 @@ nsresult LocationStep::evaluate(txIEvalC
 
   txXPathTreeWalker walker(aContext->getContextNode());
 
   switch (mAxisIdentifier) {
     case ANCESTOR_AXIS: {
       if (!walker.moveToParent()) {
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case ANCESTOR_OR_SELF_AXIS: {
       nodes->setReverse();
 
       do {
         rv = appendIfMatching(walker, aContext, nodes);
         NS_ENSURE_SUCCESS(rv, rv);
       } while (walker.moveToParent());
@@ -61,17 +61,17 @@ nsresult LocationStep::evaluate(txIEvalC
         rv = appendIfMatching(walker, aContext, nodes);
         NS_ENSURE_SUCCESS(rv, rv);
       } while (walker.moveToNextAttribute());
       break;
     }
     case DESCENDANT_OR_SELF_AXIS: {
       rv = appendIfMatching(walker, aContext, nodes);
       NS_ENSURE_SUCCESS(rv, rv);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case DESCENDANT_AXIS: {
       rv = appendMatchingDescendants(walker, aContext, nodes);
       NS_ENSURE_SUCCESS(rv, rv);
       break;
     }
     case FOLLOWING_AXIS: {
       if (txXPathNodeUtils::isAttribute(walker.getCurrentPosition())) {
--- a/dom/xslt/xslt/txOutputFormat.cpp
+++ b/dom/xslt/xslt/txOutputFormat.cpp
@@ -59,17 +59,17 @@ void txOutputFormat::merge(txOutputForma
 
   if (mMediaType.IsEmpty()) mMediaType = aOutputFormat.mMediaType;
 }
 
 void txOutputFormat::setFromDefaults() {
   switch (mMethod) {
     case eMethodNotSet: {
       mMethod = eXMLOutput;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case eXMLOutput: {
       if (mVersion.IsEmpty()) mVersion.AppendLiteral("1.0");
 
       if (mEncoding.IsEmpty()) mEncoding.AppendLiteral("UTF-8");
 
       if (mOmitXMLDeclaration == eNotSet) mOmitXMLDeclaration = eFalse;
 
--- a/editor/libeditor/EditorEventListener.cpp
+++ b/editor/libeditor/EditorEventListener.cpp
@@ -397,17 +397,17 @@ EditorEventListener::HandleEvent(Event* 
     }
     // click
     case eMouseClick: {
       WidgetMouseEvent* widgetMouseEvent = internalEvent->AsMouseEvent();
       // Don't handle non-primary click events
       if (widgetMouseEvent->mButton != MouseButton::eLeft) {
         return NS_OK;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     // auxclick
     case eMouseAuxClick: {
       WidgetMouseEvent* widgetMouseEvent = internalEvent->AsMouseEvent();
       if (NS_WARN_IF(!widgetMouseEvent)) {
         return NS_OK;
       }
       // If the preceding mousedown event or mouseup event was consumed,
--- a/extensions/permissions/nsPermissionManager.cpp
+++ b/extensions/permissions/nsPermissionManager.cpp
@@ -1106,17 +1106,17 @@ nsresult nsPermissionManager::InitDB(boo
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mDBConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("ALTER TABLE moz_hosts ADD expireTime INTEGER"));
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // TODO: we want to make default version as version 2 in order to fix bug
       // 784875.
       case 0:
       case 2: {
         // Add appId/isInBrowserElement fields.
         rv = mDBConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("ALTER TABLE moz_hosts ADD appId INTEGER"));
@@ -1126,34 +1126,34 @@ nsresult nsPermissionManager::InitDB(boo
             "ALTER TABLE moz_hosts ADD isInBrowserElement INTEGER"));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mDBConn->SetSchemaVersion(3);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // Version 3->4 is the creation of the modificationTime field.
       case 3: {
         rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
             "ALTER TABLE moz_hosts ADD modificationTime INTEGER"));
         NS_ENSURE_SUCCESS(rv, rv);
 
         // We leave the modificationTime at zero for all existing records; using
         // now() would mean, eg, that doing "remove all from the last hour"
         // within the first hour after migration would remove all permissions.
 
         rv = mDBConn->SetSchemaVersion(4);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // In version 5, host appId, and isInBrowserElement were merged into a
       // single origin entry
       //
       // In version 6, the tables were renamed for backwards compatability
       // reasons with version 4 and earlier.
       //
       // In version 7, a bug in the migration used for version 4->5 was
@@ -1236,17 +1236,17 @@ nsresult nsPermissionManager::InitDB(boo
             NS_ENSURE_SUCCESS(rv, rv);
           }
 
           rv = mDBConn->SetSchemaVersion(6);
           NS_ENSURE_SUCCESS(rv, rv);
         }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // At this point, the version 5 table has been migrated to a version 6
       // table We are guaranteed to have at least one of moz_hosts and
       // moz_perms. If we have moz_hosts, we will migrate moz_hosts into
       // moz_perms (even if we already have a moz_perms, as we need a
       // re-migration due to bug 1186034).
       //
       // After this migration, we are guaranteed to have both a moz_hosts (for
@@ -1409,17 +1409,17 @@ nsresult nsPermissionManager::InitDB(boo
         }
 #endif
 
         rv = mDBConn->SetSchemaVersion(7);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // The version 7-8 migration is the re-migration of localhost and
       // ip-address entries due to errors in the previous version 7 migration
       // which caused localhost and ip-address entries to be incorrectly
       // discarded. The version 7 migration logic has been corrected, and thus
       // this logic only needs to execute if the user is currently on version 7.
       case 7: {
         // This migration will be relatively expensive as we need to perform
@@ -1502,17 +1502,17 @@ nsresult nsPermissionManager::InitDB(boo
 
         // Even if we didn't perform the migration, we want to bump the schema
         // version to 8.
         rv = mDBConn->SetSchemaVersion(8);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // The version 8-9 migration removes the unnecessary backup moz-hosts
       // database contents. as the data no longer needs to be migrated
       case 8: {
         // We only want to clear out the old table if it is a backup. If it
         // isn't a backup, we don't need to touch it.
         bool hostsIsBackupExists = false;
         mDBConn->TableExists(NS_LITERAL_CSTRING("moz_hosts_is_backup"),
@@ -1531,25 +1531,25 @@ nsresult nsPermissionManager::InitDB(boo
           NS_ENSURE_SUCCESS(rv, rv);
         }
 
         rv = mDBConn->SetSchemaVersion(9);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 9: {
         rv = mDBConn->SetSchemaVersion(10);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 10: {
         // Filter out the rows with storage access API permissions with a
         // granted origin, and remove the granted origin part from the
         // permission type.
         rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
             "UPDATE moz_perms "
             "SET type=SUBSTR(type, 0, INSTR(SUBSTR(type, INSTR(type, '^') + "
@@ -1558,17 +1558,17 @@ nsresult nsPermissionManager::InitDB(boo
             "SUBSTR(type, 0, 18) == \"storageAccessAPI^\";"));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
         // fall through to the next upgrade
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // current version.
       case HOSTS_SCHEMA_VERSION:
         break;
 
       // downgrading.
       // if columns have been added to the table, we can still use the ones we
       // understand safely. if columns have been deleted or altered, just
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1336,17 +1336,17 @@ nsEventStatus AsyncPanZoomController::On
     case OVERSCROLL_ANIMATION:
     case WHEEL_SCROLL:
     case KEYBOARD_SCROLL:
     case PAN_MOMENTUM:
     case AUTOSCROLL:
       MOZ_ASSERT(GetCurrentTouchBlock());
       GetCurrentTouchBlock()->GetOverscrollHandoffChain()->CancelAnimations(
           ExcludeOverscroll);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case SCROLLBAR_DRAG:
     case NOTHING: {
       ParentLayerPoint point = GetFirstTouchPoint(aEvent);
       mStartTouch = GetFirstExternalTouchPoint(aEvent);
       mX.StartTouch(point.x, aEvent.mTime);
       mY.StartTouch(point.y, aEvent.mTime);
       if (RefPtr<GeckoContentController> controller =
               GetGeckoContentController()) {
@@ -1456,17 +1456,17 @@ nsEventStatus AsyncPanZoomController::On
   if (mState != NOTHING) {
     RecursiveMutexAutoLock lock(mRecursiveMutex);
   }
 
   switch (mState) {
     case FLING:
       // Should never happen.
       NS_WARNING("Received impossible touch end in OnTouchEnd.");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ANIMATING_ZOOM:
     case SMOOTH_SCROLL:
     case NOTHING:
       // May happen if the user double-taps and drags without lifting after the
       // second tap. Ignore if this happens.
       return nsEventStatus_eIgnore;
 
     case TOUCHING:
--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -533,17 +533,17 @@ void GestureEventListener::HandleInputTi
 
   mLongTapTimeoutTask = nullptr;
 
   switch (mState) {
     case GESTURE_FIRST_SINGLE_TOUCH_DOWN:
       // just in case MaxTapTime > ContextMenuDelay cancel MaxTap timer
       // and fall through
       CancelMaxTapTimeoutTask();
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN: {
       SetState(GESTURE_LONG_TOUCH_DOWN);
       mAsyncPanZoomController->HandleGestureEvent(
           CreateTapEvent(mLastTouchInput, TapGestureInput::TAPGESTURE_LONG));
       break;
     }
     default:
       NS_WARNING("Unhandled state upon long tap timeout");
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -360,20 +360,20 @@ void APZEventState::ProcessTouchEvent(co
       break;
     }
 
     case eTouchEnd:
       if (isTouchPrevented) {
         mTouchEndCancelled = true;
         mEndTouchIsClick = false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eTouchCancel:
       mActiveElementManager->HandleTouchEndEvent(mEndTouchIsClick);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eTouchMove: {
       if (mPendingTouchPreventedResponse) {
         MOZ_ASSERT(aGuid == mPendingTouchPreventedGuid);
       }
       sentContentResponse = SendPendingTouchPreventedResponse(isTouchPrevented);
       break;
     }
 
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -478,28 +478,28 @@ void gfxFontShaper::MergeFontFeatures(
   uint32_t variantCaps = aStyle->variantCaps;
   switch (variantCaps) {
     case NS_FONT_VARIANT_CAPS_NORMAL:
       break;
 
     case NS_FONT_VARIANT_CAPS_ALLSMALL:
       mergedFeatures.Put(HB_TAG('c', '2', 's', 'c'), 1);
       // fall through to the small-caps case
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case NS_FONT_VARIANT_CAPS_SMALLCAPS:
       mergedFeatures.Put(HB_TAG('s', 'm', 'c', 'p'), 1);
       break;
 
     case NS_FONT_VARIANT_CAPS_ALLPETITE:
       mergedFeatures.Put(aAddSmallCaps ? HB_TAG('c', '2', 's', 'c')
                                        : HB_TAG('c', '2', 'p', 'c'),
                          1);
       // fall through to the petite-caps case
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case NS_FONT_VARIANT_CAPS_PETITECAPS:
       mergedFeatures.Put(aAddSmallCaps ? HB_TAG('s', 'm', 'c', 'p')
                                        : HB_TAG('p', 'c', 'a', 'p'),
                          1);
       break;
 
     case NS_FONT_VARIANT_CAPS_TITLING:
@@ -3267,17 +3267,17 @@ bool gfxFont::InitFakeSmallCapsRun(DrawT
                                       aOrientation)) {
             ok = false;
           }
           break;
 
         case kUppercaseReduce:
           // use reduced-size font, then fall through to uppercase the text
           f = smallCapsFont;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         case kUppercase:
           // apply uppercase transform to the string
           nsDependentSubstring origString(aText + runStart, runLength);
           nsAutoString convertedString;
           AutoTArray<bool, 50> charsToMergeArray;
           AutoTArray<bool, 50> deletedCharsArray;
 
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -1880,17 +1880,17 @@ void gfxFontGroup::FamilyFace::CheckStat
     switch (state) {
       case gfxUserFontEntry::STATUS_LOAD_PENDING:
       case gfxUserFontEntry::STATUS_LOADING:
         SetLoading(true);
         break;
       case gfxUserFontEntry::STATUS_FAILED:
         SetInvalid();
         // fall-thru to the default case
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       default:
         SetLoading(false);
     }
     if (ufe->WaitForUserFont()) {
       aSkipDrawing = true;
     }
   }
 }
--- a/gfx/vr/VRPuppetCommandBuffer.cpp
+++ b/gfx/vr/VRPuppetCommandBuffer.cpp
@@ -194,37 +194,37 @@ bool VRPuppetCommandBuffer::RunCommand(u
                     (uint8_t*)&mPendingState + (aCommand & 0x00000000ffffffff);
       break;
     case VRPuppet_Command::VRPuppet_Commit:
       memcpy(&mCommittedState, &mPendingState, sizeof(VRSystemState));
       break;
 
     case VRPuppet_Command::VRPuppet_Data7:
       WriteData((aCommand & 0x00ff000000000000) >> 48);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data6:
       WriteData((aCommand & 0x0000ff0000000000) >> 40);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data5:
       WriteData((aCommand & 0x000000ff00000000) >> 32);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data4:
       WriteData((aCommand & 0x00000000ff000000) >> 24);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data3:
       WriteData((aCommand & 0x0000000000ff0000) >> 16);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data2:
       WriteData((aCommand & 0x000000000000ff00) >> 8);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
       // Purposefully, no break
     case VRPuppet_Command::VRPuppet_Data1:
       WriteData(aCommand & 0x00000000000000ff);
       break;
   }
   return true;
 }
 
--- a/hal/linux/UPowerClient.cpp
+++ b/hal/linux/UPowerClient.cpp
@@ -419,17 +419,17 @@ void UPowerClient::UpdateSavedInfo(GHash
    */
   switch (g_value_get_uint(
       static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "State")))) {
     case eState_Unknown:
       mCharging = kDefaultCharging;
       break;
     case eState_FullyCharged:
       isFull = true;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eState_Charging:
     case eState_PendingCharge:
       mCharging = true;
       break;
     case eState_Discharging:
     case eState_Empty:
     case eState_PendingDischarge:
       mCharging = false;
--- a/image/AnimationSurfaceProvider.cpp
+++ b/image/AnimationSurfaceProvider.cpp
@@ -291,17 +291,17 @@ bool AnimationSurfaceProvider::CheckForN
     if (mFrames->HasRedecodeError()) {
       mDecoder = nullptr;
       return false;
     }
 
     switch (status) {
       case AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE:
         continueDecoding = true;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case AnimationFrameBuffer::InsertStatus::DISCARD_YIELD:
         RequestFrameDiscarding();
         break;
       case AnimationFrameBuffer::InsertStatus::CONTINUE:
         continueDecoding = true;
         break;
       case AnimationFrameBuffer::InsertStatus::YIELD:
         break;
--- a/image/decoders/nsJPEGDecoder.cpp
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -382,17 +382,17 @@ LexerTransition<nsJPEGDecoder::State> ns
       mPipe = std::move(*pipe);
 
       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
               ("        JPEGDecoderAccounting: nsJPEGDecoder::"
                "Write -- created image frame with %ux%u pixels",
                mInfo.image_width, mInfo.image_height));
 
       mState = JPEG_START_DECOMPRESS;
-      MOZ_FALLTHROUGH;  // to start decompressing.
+      [[fallthrough]];  // to start decompressing.
     }
 
     case JPEG_START_DECOMPRESS: {
       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
                 "nsJPEGDecoder::Write -- entering"
                 " JPEG_START_DECOMPRESS case");
       // Step 4: set parameters for decompression
 
@@ -411,17 +411,17 @@ LexerTransition<nsJPEGDecoder::State> ns
                 ("} (I/O suspension after jpeg_start_decompress())"));
         return Transition::ContinueUnbuffered(
             State::JPEG_DATA);  // I/O suspension
       }
 
       // If this is a progressive JPEG ...
       mState = mInfo.buffered_image ? JPEG_DECOMPRESS_PROGRESSIVE
                                     : JPEG_DECOMPRESS_SEQUENTIAL;
-      MOZ_FALLTHROUGH;  // to decompress sequential JPEG.
+      [[fallthrough]];  // to decompress sequential JPEG.
     }
 
     case JPEG_DECOMPRESS_SEQUENTIAL: {
       if (mState == JPEG_DECOMPRESS_SEQUENTIAL) {
         LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
                   "nsJPEGDecoder::Write -- "
                   "JPEG_DECOMPRESS_SEQUENTIAL case");
 
@@ -439,17 +439,17 @@ LexerTransition<nsJPEGDecoder::State> ns
             break;
           case WriteState::FAILURE:
             mState = JPEG_ERROR;
             MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
                     ("} (Error in pipeline from OutputScalines())"));
             return Transition::TerminateFailure();
         }
       }
-      MOZ_FALLTHROUGH;  // to decompress progressive JPEG.
+      [[fallthrough]];  // to decompress progressive JPEG.
     }
 
     case JPEG_DECOMPRESS_PROGRESSIVE: {
       if (mState == JPEG_DECOMPRESS_PROGRESSIVE) {
         LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
                   "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case");
 
         int status;
@@ -516,17 +516,17 @@ LexerTransition<nsJPEGDecoder::State> ns
             case WriteState::FAILURE:
               mState = JPEG_ERROR;
               MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
                       ("} (Error in pipeline from OutputScalines())"));
               return Transition::TerminateFailure();
           }
         }
       }
-      MOZ_FALLTHROUGH;  // to finish decompressing.
+      [[fallthrough]];  // to finish decompressing.
     }
 
     case JPEG_DONE: {
       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
                 "nsJPEGDecoder::ProcessData -- entering"
                 " JPEG_DONE case");
 
       // Step 7: Finish decompression
--- a/intl/unicharutil/util/GreekCasing.cpp
+++ b/intl/unicharutil/util/GreekCasing.cpp
@@ -243,17 +243,17 @@ uint32_t GreekCasing::UpperCase(uint32_t
     case GREEK_LOWER_ETA_TONOS:
     case GREEK_UPPER_ETA_TONOS:
       if (aState == kStart) {
         aState = kEtaAccMarked;
         aMarkEtaPos = true;  // mark in case we need to remove the tonos later
         return GREEK_UPPER_ETA_TONOS;  // treat as disjunctive eta for now
       }
       // if not in initial state, fall through to strip the accent
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case GREEK_LOWER_ETA_OXIA:
     case GREEK_UPPER_ETA_OXIA:
       aState = kEtaAcc;
       return GREEK_UPPER_ETA;
 
     case GREEK_LOWER_IOTA_TONOS:
     case GREEK_LOWER_IOTA_OXIA:
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -2302,17 +2302,17 @@ bool ASTSerializer::statement(ParseNode*
              builder.expressionStatement(expr, &pn->pn_pos, dst);
     }
 
     case ParseNodeKind::LexicalScope:
       pn = pn->as<LexicalScopeNode>().scopeBody();
       if (!pn->isKind(ParseNodeKind::StatementList)) {
         return statement(pn, dst);
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case ParseNodeKind::StatementList:
       return blockStatement(&pn->as<ListNode>(), dst);
 
     case ParseNodeKind::IfStmt: {
       TernaryNode* ifNode = &pn->as<TernaryNode>();
 
       ParseNode* testNode = ifNode->kid1();
--- a/js/src/builtin/String.cpp
+++ b/js/src/builtin/String.cpp
@@ -1797,35 +1797,35 @@ template <typename TextChar, typename Pa
 static const TextChar* FirstCharMatcherUnrolled(const TextChar* text,
                                                 uint32_t n, const PatChar pat) {
   const TextChar* textend = text + n;
   const TextChar* t = text;
 
   switch ((textend - t) & 7) {
     case 0:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 7:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 6:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 5:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 4:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 3:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       if (*t++ == pat) return t - 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       if (*t++ == pat) return t - 1;
   }
   while (textend != t) {
     if (t[0] == pat) return t;
     if (t[1] == pat) return t + 1;
     if (t[2] == pat) return t + 2;
     if (t[3] == pat) return t + 3;
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1228,17 +1228,17 @@ restart:
     case ParseNodeKind::CoalesceExpr:
     case ParseNodeKind::OrExpr:
     case ParseNodeKind::AndExpr:
     case ParseNodeKind::StrictEqExpr:
     case ParseNodeKind::StrictNeExpr:
     // Any subexpression of a comma expression could be effectful.
     case ParseNodeKind::CommaExpr:
       MOZ_ASSERT(!pn->as<ListNode>().empty());
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     // Subcomponents of a literal may be effectful.
     case ParseNodeKind::ArrayExpr:
     case ParseNodeKind::ObjectExpr:
       for (ParseNode* item : pn->as<ListNode>().contents()) {
         if (!checkSideEffects(item, answer)) {
           return false;
         }
         if (*answer) {
@@ -9568,17 +9568,17 @@ bool BytecodeEmitter::emitTree(
 
     case ParseNodeKind::ThrowStmt:
       if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
         return false;
       }
       if (!markStepBreakpoint()) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ParseNodeKind::VoidExpr:
     case ParseNodeKind::NotExpr:
     case ParseNodeKind::BitNotExpr:
     case ParseNodeKind::PosExpr:
     case ParseNodeKind::NegExpr:
       if (!emitUnary(&pn->as<UnaryNode>())) {
         return false;
       }
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -194,17 +194,17 @@ class NameResolver : public ParseNodeVis
           }
           break;
 
         case ParseNodeKind::PropertyDefinition:
         case ParseNodeKind::Shorthand:
           // Record the ParseNodeKind::PropertyDefinition/Shorthand but skip the
           // ParseNodeKind::Object so we're not flagged as a contributor.
           pos--;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         default:
           // Save any other nodes we encounter on the way up.
           MOZ_ASSERT(*size < MaxParents);
           nameable[(*size)++] = cur;
           break;
       }
     }
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -789,23 +789,23 @@ bool GeneralParser<ParseHandler, Unit>::
       // The BoundNames of LexicalDeclaration and ForDeclaration must not
       // contain 'let'. (CatchParameter is the only lexical binding form
       // without this restriction.)
       if (name == cx_->names().let) {
         errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
         return false;
       }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case DeclarationKind::Import:
       // Module code is always strict, so 'let' is always a keyword and never a
       // name.
       MOZ_ASSERT(name != cx_->names().let);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case DeclarationKind::SimpleCatchParameter:
     case DeclarationKind::CatchParameter: {
       if (ParseContext::Statement* stmt = pc_->innermostStatement()) {
         if (!checkLexicalDeclarationDirectlyWithinBlock(*stmt, kind, pos)) {
           return false;
         }
       }
@@ -6510,17 +6510,17 @@ GeneralParser<ParseHandler, Unit>::yield
     case TokenKind::Comma:
     case TokenKind::In:  // Annex B.3.6 `for (x = yield in y) ;`
       // No value.
       exprNode = null();
       break;
     case TokenKind::Mul:
       kind = ParseNodeKind::YieldStarExpr;
       tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       exprNode = assignExpr(inHandling, YieldIsKeyword, TripledotProhibited);
       if (!exprNode) {
         return null();
       }
   }
   if (kind == ParseNodeKind::YieldStarExpr) {
     return handler_.newYieldStarExpression(begin, exprNode);
@@ -8978,17 +8978,17 @@ typename ParseHandler::Node GeneralParse
         if (!kid) {
           return null();
         }
         pc_->lastAwaitOffset = begin;
         return handler_.newAwaitExpression(begin, kid);
       }
     }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     default: {
       Node expr =
           memberExpr(yieldHandling, tripledotHandling, tt,
                      /* allowCallSyntax = */ true, possibleError, invoked);
       if (!expr) {
         return null();
       }
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -3418,17 +3418,17 @@ bool TokenStreamSpecific<Unit, AnyCharsA
           unit = '\t';
           break;
         case 'v':
           unit = '\v';
           break;
 
         case '\r':
           matchLineTerminator('\n');
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case '\n': {
           // LineContinuation represents no code points.  We're manually
           // consuming a LineTerminatorSequence, so we must manually
           // update line/column info.
           if (!updateLineInfoForEOL()) {
             return false;
           }
 
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -6456,17 +6456,17 @@ void GCRuntime::incrementalSlice(SliceBu
 #ifdef DEBUG
       for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) {
         zone->gcSweepGroupIndex = 0;
       }
 #endif
 
       incrementalState = State::MarkRoots;
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::MarkRoots:
       if (!beginMarkPhase(reason, session)) {
         incrementalState = State::NotActive;
         return;
       }
 
       /* If we needed delayed marking for gray roots, then collect until done.
@@ -6479,17 +6479,17 @@ void GCRuntime::incrementalSlice(SliceBu
 
       incrementalState = State::Mark;
 
       if (isIncremental && useZeal &&
           hasZealMode(ZealMode::YieldBeforeMarking)) {
         break;
       }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::Mark:
       AutoGCRooter::traceAllWrappers(rt->mainContextFromOwnThread(), &marker);
 
       if (markUntilBudgetExhausted(budget, gcstats::PhaseKind::MARK) ==
           NotFinished) {
         break;
       }
@@ -6523,33 +6523,33 @@ void GCRuntime::incrementalSlice(SliceBu
           break;
         }
       }
 
       incrementalState = State::Sweep;
       lastMarkSlice = false;
       beginSweepPhase(reason, session);
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::Sweep:
       MOZ_ASSERT(nursery().isEmpty());
       storeBuffer().checkEmpty();
 
       AutoGCRooter::traceAllWrappers(rt->mainContextFromOwnThread(), &marker);
 
       if (performSweepActions(budget) == NotFinished) {
         break;
       }
 
       endSweepPhase(destroyingRuntime);
 
       incrementalState = State::Finalize;
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::Finalize: {
       gcstats::AutoPhase ap(stats(),
                             gcstats::PhaseKind::WAIT_BACKGROUND_THREAD);
 
       // Yield until background finalization is done.
       if (!budget.isUnlimited()) {
         // Poll for end of background sweeping
@@ -6573,17 +6573,17 @@ void GCRuntime::incrementalSlice(SliceBu
       MOZ_ASSERT(!startedCompacting);
       incrementalState = State::Compact;
 
       // Always yield before compacting since it is not incremental.
       if (isCompacting && !budget.isUnlimited()) {
         break;
       }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::Compact:
       if (isCompacting) {
         MOZ_ASSERT(nursery().isEmpty());
         storeBuffer().checkEmpty();
         if (!startedCompacting) {
           beginCompactPhase();
         }
@@ -6593,32 +6593,32 @@ void GCRuntime::incrementalSlice(SliceBu
         }
 
         endCompactPhase();
       }
 
       startDecommit();
       incrementalState = State::Decommit;
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case State::Decommit: {
       gcstats::AutoPhase ap(stats(),
                             gcstats::PhaseKind::WAIT_BACKGROUND_THREAD);
 
       // Yield until background decommit is done.
       if (!budget.isUnlimited() && decommitTask.wasStarted()) {
         break;
       }
 
       decommitTask.join();
 
       incrementalState = State::Finish;
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
 
     case State::Finish:
       finishCollection();
       incrementalState = State::NotActive;
       break;
   }
 
--- a/js/src/irregexp/RegExpEngine.cpp
+++ b/js/src/irregexp/RegExpEngine.cpp
@@ -3830,17 +3830,17 @@ EmitAtomMulti(RegExpCompiler* compiler,
             macro_assembler->CheckCharacter(chars[0], &ok);
             macro_assembler->CheckNotCharacter(chars[1], on_failure);
             macro_assembler->Bind(&ok);
         }
         break;
       }
       case 4:
         macro_assembler->CheckCharacter(chars[3], &ok);
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case 3:
         macro_assembler->CheckCharacter(chars[0], &ok);
         macro_assembler->CheckCharacter(chars[1], &ok);
         macro_assembler->CheckNotCharacter(chars[2], on_failure);
         macro_assembler->Bind(&ok);
         break;
       default:
         MOZ_CRASH("Bad length");
--- a/js/src/irregexp/RegExpParser.cpp
+++ b/js/src/irregexp/RegExpParser.cpp
@@ -639,17 +639,17 @@ RegExpParser<CharT>::ParseClassCharacter
       case '0':
         if (unicode_) {
             Advance();
             if (IsDecimalDigit(current()))
                 return ReportError(JSMSG_INVALID_DECIMAL_ESCAPE);
             *code = 0;
             return true;
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case '1': case '2': case '3': case '4': case '5': case '6': case '7':
         if (unicode_) {
             ReportError(JSMSG_INVALID_IDENTITY_ESCAPE);
             return false;
         }
         // For compatibility, outside of unicode mode, we interpret a decimal
         // escape that isn't a back reference (and therefore either \0 or not
         // valid according to the specification) as a 1..3 digit octal
@@ -1677,17 +1677,17 @@ RegExpParser<CharT>::ParseDisjunction()
               case 'D': case 'S': case 'W':
                 if (unicode_) {
                     Advance();
                     builder->AddAtom(UnicodeCharacterClassEscapeAtom(alloc, current(),
                                                                      ignore_case_));
                     Advance();
                     break;
                 }
-                MOZ_FALLTHROUGH;
+                [[fallthrough]];
               case 'd': case 's': case 'w': {
                 widechar c = Next();
                 Advance(2);
                 CharacterRangeVector* ranges =
                     alloc->newInfallible<CharacterRangeVector>(*alloc);
                 if (unicode_)
                     CharacterRange::AddClassEscapeUnicode(alloc, c, ranges, ignore_case_);
                 else
@@ -1719,17 +1719,17 @@ RegExpParser<CharT>::ParseDisjunction()
                     return ReportError(JSMSG_BACK_REF_OUT_OF_RANGE);
                 widechar first_digit = Next();
                 if (first_digit == '8' || first_digit == '9') {
                     // Treat as identity escape
                     builder->AddCharacter(first_digit);
                     Advance(2);
                     break;
                 }
-                MOZ_FALLTHROUGH;
+                [[fallthrough]];
               }
               case '0': {
                 if (unicode_) {
                     Advance(2);
                     if (IsDecimalDigit(current()))
                         return ReportError(JSMSG_INVALID_DECIMAL_ESCAPE);
                     builder->AddCharacter(0);
                     break;
@@ -1849,17 +1849,17 @@ RegExpParser<CharT>::ParseDisjunction()
             }
             break;
           case '{': {
             if (unicode_)
                 return ReportError(JSMSG_RAW_BRACE_IN_REGEXP);
             int dummy;
             if (ParseIntervalQuantifier(&dummy, &dummy))
                 return ReportError(JSMSG_NOTHING_TO_REPEAT);
-            MOZ_FALLTHROUGH;
+            [[fallthrough]];
           }
           default:
             if (unicode_) {
                 char16_t lead, trail;
                 if (ParseRawSurrogatePair(&lead, &trail)) {
                     builder->AddAtom(SurrogatePairAtom(alloc, lead, trail, ignore_case_));
                 } else {
                     widechar c = current();
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -2045,17 +2045,17 @@ bool jit::FinishBailoutToBaseline(Baseli
       // Do not return directly, as this was not frequent in the first place,
       // thus rely on the check for frequent bailouts to recompile the current
       // script.
       break;
 
     // Invalid assumption based on baseline code.
     case Bailout_OverflowInvalidate:
       outerScript->setHadOverflowBailout();
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case Bailout_DoubleOutput:
     case Bailout_ObjectIdentityOrTypeGuard:
       HandleBaselineInfoBailout(cx, outerScript, innerScript);
       break;
 
     case Bailout_ArgumentCheck:
       // Do nothing, bailout will resume before the argument monitor ICs.
       break;
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1636,17 +1636,17 @@ AttachDecision GetPropIRGenerator::tryAt
     return tryAttachGenericProxy(obj, objId, id, /* handleDOMProxies = */ true);
   }
 
   switch (type) {
     case ProxyStubType::None:
       break;
     case ProxyStubType::DOMExpando:
       TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id));
-      MOZ_FALLTHROUGH;  // Fall through to the generic shadowed case.
+      [[fallthrough]];  // Fall through to the generic shadowed case.
     case ProxyStubType::DOMShadowed:
       return tryAttachDOMProxyShadowed(obj, objId, id);
     case ProxyStubType::DOMUnshadowed:
       TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id));
       return tryAttachGenericProxy(obj, objId, id,
                                    /* handleDOMProxies = */ true);
     case ProxyStubType::Generic:
       return tryAttachGenericProxy(obj, objId, id,
@@ -4205,17 +4205,17 @@ AttachDecision SetPropIRGenerator::tryAt
                                  /* handleDOMProxies = */ true);
   }
 
   switch (type) {
     case ProxyStubType::None:
       break;
     case ProxyStubType::DOMExpando:
       TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id, rhsId));
-      MOZ_FALLTHROUGH;  // Fall through to the generic shadowed case.
+      [[fallthrough]];  // Fall through to the generic shadowed case.
     case ProxyStubType::DOMShadowed:
       return tryAttachDOMProxyShadowed(obj, objId, id, rhsId);
     case ProxyStubType::DOMUnshadowed:
       TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id, rhsId));
       return tryAttachGenericProxy(obj, objId, id, rhsId,
                                    /* handleDOMProxies = */ true);
     case ProxyStubType::Generic:
       return tryAttachGenericProxy(obj, objId, id, rhsId,
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1622,17 +1622,17 @@ class MOZ_RAII PoppedValueUseChecker {
           // These ops may leave their input on the stack without setting
           // the ImplicitlyUsed flag. If this value will be popped immediately,
           // we may replace it with |undefined|, but the difference is
           // not observable.
           MOZ_ASSERT(i == 0);
           if (current_->peek(-1) == popped_[0]) {
             break;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         default:
           MOZ_ASSERT(popped_[i]->isImplicitlyUsed() ||
                      // First value popped by JSOP_ENDITER is not used at all,
                      // it's similar to JSOP_POP above.
                      (op == JSOP_ENDITER && i == 0) ||
                      // MNewDerivedTypedObject instances are
                      // often dead unless they escape from the
@@ -2243,17 +2243,17 @@ AbortReasonOr<Ok> IonBuilder::inspectOpc
     case JSOP_BINDGNAME:
       if (!script()->hasNonSyntacticScope()) {
         if (JSObject* env = testGlobalLexicalBinding(info().getName(pc))) {
           pushConstant(ObjectValue(*env));
           return Ok();
         }
       }
       // Fall through to JSOP_BINDNAME
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case JSOP_BINDNAME:
       return jsop_bindname(info().getName(pc));
 
     case JSOP_BINDVAR:
       return jsop_bindvar();
 
     case JSOP_DUP:
       current->pushSlot(current->stackDepth() - 1);
@@ -2442,17 +2442,17 @@ AbortReasonOr<Ok> IonBuilder::inspectOpc
       return jsop_debugger();
 
     case JSOP_GIMPLICITTHIS:
       if (!script()->hasNonSyntacticScope()) {
         pushConstant(UndefinedValue());
         return Ok();
       }
       // Fallthrough to IMPLICITTHIS in non-syntactic scope case
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case JSOP_IMPLICITTHIS: {
       PropertyName* name = info().getAtom(pc)->asPropertyName();
       return jsop_implicitthis(name);
     }
 
     case JSOP_NEWTARGET:
       return jsop_newtarget();
 
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -1964,17 +1964,17 @@ void LIRGenerator::visitToDouble(MToDoub
 
     case MIRType::Undefined:
       MOZ_ASSERT(conversion != MToFPInstruction::NumbersOnly);
       lowerConstantDouble(GenericNaN(), convert);
       break;
 
     case MIRType::Boolean:
       MOZ_ASSERT(conversion != MToFPInstruction::NumbersOnly);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case MIRType::Int32: {
       LInt32ToDouble* lir =
           new (alloc()) LInt32ToDouble(useRegisterAtStart(opd));
       define(lir, convert);
       break;
     }
 
@@ -2017,17 +2017,17 @@ void LIRGenerator::visitToFloat32(MToFlo
 
     case MIRType::Undefined:
       MOZ_ASSERT(conversion != MToFPInstruction::NumbersOnly);
       lowerConstantFloat32(GenericNaN(), convert);
       break;
 
     case MIRType::Boolean:
       MOZ_ASSERT(conversion != MToFPInstruction::NumbersOnly);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case MIRType::Int32: {
       LInt32ToFloat32* lir =
           new (alloc()) LInt32ToFloat32(useRegisterAtStart(opd));
       define(lir, convert);
       break;
     }
 
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -3243,17 +3243,17 @@ IonBuilder::InliningResult IonBuilder::i
   bool possiblyWrapped = false;
   switch (types->forAllClasses(constraints(), IsTypedArrayClass)) {
     case TemporaryTypeSet::ForAllResult::ALL_FALSE:
       if (isPossiblyWrapped()) {
         // Don't inline if we never saw typed arrays, but always only proxies.
         return InliningStatus_NotInlined;
       }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case TemporaryTypeSet::ForAllResult::EMPTY:
       result = false;
       break;
 
     case TemporaryTypeSet::ForAllResult::ALL_TRUE:
       result = true;
       break;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2550,17 +2550,17 @@ static inline bool CanProduceNegativeZer
   // Test if this instruction can produce negative zero even when bailing out
   // and changing types.
   switch (def->op()) {
     case MDefinition::Opcode::Constant:
       if (def->type() == MIRType::Double &&
           def->toConstant()->toDouble() == -0.0) {
         return true;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case MDefinition::Opcode::BitAnd:
     case MDefinition::Opcode::BitOr:
     case MDefinition::Opcode::BitXor:
     case MDefinition::Opcode::BitNot:
     case MDefinition::Opcode::Lsh:
     case MDefinition::Opcode::Rsh:
       return false;
     default:
@@ -2636,17 +2636,17 @@ static inline bool NeedNegativeZeroCheck
         // change type and become -0.0 while the rhs has already been
         // optimized to not make a difference between zero and negative zero.
         MDefinition* lhs = use_def->toSub()->lhs();
         MDefinition* rhs = use_def->toSub()->rhs();
         if (rhs->id() < lhs->id() && CanProduceNegativeZero(lhs)) {
           return true;
         }
 
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       }
       case MDefinition::Opcode::StoreElement:
       case MDefinition::Opcode::LoadElement:
       case MDefinition::Opcode::LoadElementHole:
       case MDefinition::Opcode::LoadUnboxedScalar:
       case MDefinition::Opcode::LoadTypedArrayElementHole:
       case MDefinition::Opcode::CharCodeAt:
       case MDefinition::Opcode::Mod:
@@ -3582,17 +3582,17 @@ MDefinition* MTypeOf::foldsTo(TempAlloca
       break;
     case MIRType::Object:
       if (!inputMaybeCallableOrEmulatesUndefined()) {
         // Object is not callable and does not emulate undefined, so it's
         // safe to fold to "object".
         type = JSTYPE_OBJECT;
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       return this;
   }
 
   return MConstant::New(
       alloc, StringValue(TypeName(type, GetJitContext()->runtime->names())));
 }
 
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -287,27 +287,27 @@ bool RangeAnalysis::addBetaNodes() {
         }
         break;
       case JSOP_STRICTEQ:
         // A strict comparison can test for things other than numeric value.
         if (!compare->isNumericComparison()) {
           continue;
         }
         // Otherwise fall through to handle JSOP_STRICTEQ the same as JSOP_EQ.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case JSOP_EQ:
         comp.setDouble(bound, bound);
         break;
       case JSOP_STRICTNE:
         // A strict comparison can test for things other than numeric value.
         if (!compare->isNumericComparison()) {
           continue;
         }
         // Otherwise fall through to handle JSOP_STRICTNE the same as JSOP_NE.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case JSOP_NE:
         // Negative zero is not not-equal to zero.
         if (bound == 0) {
           comp.refineToExcludeNegativeZero();
           break;
         }
         continue;  // well, we could have
                    // [-\inf, bound-1] U [bound+1, \inf] but we only use
--- a/js/src/jit/arm/disasm/Disasm-arm.cpp
+++ b/js/src/jit/arm/disasm/Disasm-arm.cpp
@@ -1774,17 +1774,17 @@ void Decoder::DecodeSpecialCondition(Ins
             out_buffer_pos_ +=
                 SNPrintF(out_buffer_ + out_buffer_pos_, "dmb %s", option);
             break;
           default:
             Unknown(instr);
         }
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 0xB:
       if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
         int Rn = instr->Bits(19, 16);
         int offset = instr->Bits(11, 0);
         if (offset == 0) {
           out_buffer_pos_ +=
               SNPrintF(out_buffer_ + out_buffer_pos_, "pld [r%d]", Rn);
         } else if (instr->Bit(23) == 0) {
--- a/js/src/jit/mips32/MoveEmitter-mips32.cpp
+++ b/js/src/jit/mips32/MoveEmitter-mips32.cpp
@@ -39,17 +39,17 @@ void MoveEmitterMIPS::breakCycle(const M
         masm.loadDouble(getAdjustedAddress(to), temp);
         masm.storeDouble(temp, cycleSlot(slotId, 0));
       } else {
         masm.storeDouble(to.floatReg(), cycleSlot(slotId, 0));
       }
       break;
     case MoveOp::INT32:
       MOZ_ASSERT(sizeof(uintptr_t) == sizeof(int32_t));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case MoveOp::GENERAL:
       if (to.isMemory()) {
         Register temp = tempReg();
         masm.loadPtr(getAdjustedAddress(to), temp);
         masm.storePtr(temp, cycleSlot(0, 0));
       } else {
         // Second scratch register should not be moved by MoveEmitter.
         MOZ_ASSERT(to.reg() != spilledReg_);
@@ -90,17 +90,17 @@ void MoveEmitterMIPS::completeCycle(cons
         masm.loadDouble(cycleSlot(slotId, 0), temp);
         masm.storeDouble(temp, getAdjustedAddress(to));
       } else {
         masm.loadDouble(cycleSlot(slotId, 0), to.floatReg());
       }
       break;
     case MoveOp::INT32:
       MOZ_ASSERT(sizeof(uintptr_t) == sizeof(int32_t));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case MoveOp::GENERAL:
       MOZ_ASSERT(slotId == 0);
       if (to.isMemory()) {
         Register temp = tempReg();
         masm.loadPtr(cycleSlot(0, 0), temp);
         masm.storePtr(temp, getAdjustedAddress(to));
       } else {
         // Second scratch register should not be moved by MoveEmitter.
--- a/js/src/jit/mips32/Simulator-mips32.cpp
+++ b/js/src/jit/mips32/Simulator-mips32.cpp
@@ -2612,17 +2612,17 @@ void Simulator::decodeTypeRegister(SimIn
             case ff_cvt_d_fmt:
               f = getFpuRegisterFloat(fs_reg);
               setFpuRegisterDouble(fd_reg, static_cast<double>(f));
               break;
             case ff_cvt_w_fmt:  // Convert float to word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_w_fmt: {  // Round double to word (round half to
                                     // even).
               float rounded = std::floor(fs_value + 0.5);
               int32_t result = static_cast<int32_t>(rounded);
               if ((result & 1) != 0 && result - fs_value == 0.5) {
                 // If the number is halfway between two integers,
                 // round to the even one.
                 result--;
@@ -2762,17 +2762,17 @@ void Simulator::decodeTypeRegister(SimIn
               setFCSRBit(fcsr_cc,
                          (ds_value <= dt_value) || (mozilla::IsNaN(ds_value) ||
                                                     mozilla::IsNaN(dt_value)));
               break;
             case ff_cvt_w_fmt:  // Convert double to word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_w_fmt: {  // Round double to word (round half to
                                     // even).
               double rounded = std::floor(ds_value + 0.5);
               int32_t result = static_cast<int32_t>(rounded);
               if ((result & 1) != 0 && result - ds_value == 0.5) {
                 // If the number is halfway between two integers,
                 // round to the even one.
                 result--;
--- a/js/src/jit/mips32/Trampoline-mips32.cpp
+++ b/js/src/jit/mips32/Trampoline-mips32.cpp
@@ -722,17 +722,17 @@ bool JitRuntime::generateVMWrapper(JSCon
       uint32_t pushed = masm.framePushed();
       masm.PushEmptyRooted(f.outParamRootType);
       outParamSize = masm.framePushed() - pushed;
     } break;
 
     case Type_Bool:
     case Type_Int32:
       MOZ_ASSERT(sizeof(uintptr_t) == sizeof(uint32_t));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case Type_Pointer:
       outParamSize = sizeof(uintptr_t);
       masm.reserveStack(outParamSize);
       break;
 
     case Type_Double:
       outParamSize = sizeof(double);
       masm.reserveStack(outParamSize);
@@ -840,17 +840,17 @@ bool JitRuntime::generateVMWrapper(JSCon
 
     case Type_Value:
       masm.loadValue(Address(StackPointer, 0), JSReturnOperand);
       masm.freeStack(sizeof(Value));
       break;
 
     case Type_Int32:
       MOZ_ASSERT(sizeof(uintptr_t) == sizeof(uint32_t));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case Type_Pointer:
       masm.load32(Address(StackPointer, 0), ReturnReg);
       masm.freeStack(sizeof(uintptr_t));
       break;
 
     case Type_Bool:
       masm.load8ZeroExtend(Address(StackPointer, 0), ReturnReg);
       masm.freeStack(sizeof(uintptr_t));
--- a/js/src/jit/mips64/Simulator-mips64.cpp
+++ b/js/src/jit/mips64/Simulator-mips64.cpp
@@ -2820,17 +2820,17 @@ void Simulator::decodeTypeRegister(SimIn
   switch (op) {
     case op_cop1:
       switch (instr->rsFieldRaw()) {
         case rs_bc1:  // Branch on coprocessor condition.
           MOZ_CRASH();
           break;
         case rs_cfc1:
           setRegister(rt_reg, alu_out);
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case rs_mfc1:
           setRegister(rt_reg, alu_out);
           break;
         case rs_dmfc1:
           setRegister(rt_reg, alu_out);
           break;
         case rs_mfhc1:
           setRegister(rt_reg, alu_out);
@@ -2913,17 +2913,17 @@ void Simulator::decodeTypeRegister(SimIn
             case ff_cvt_d_fmt:
               f = getFpuRegisterFloat(fs_reg);
               setFpuRegisterDouble(fd_reg, static_cast<double>(f));
               break;
             case ff_cvt_w_fmt:  // Convert float to word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_w_fmt: {  // Round double to word (round half to
                                     // even).
               float rounded = std::floor(fs_value + 0.5);
               int32_t result = I32(rounded);
               if ((result & 1) != 0 && result - fs_value == 0.5) {
                 // If the number is halfway between two integers,
                 // round to the even one.
                 result--;
@@ -2962,17 +2962,17 @@ void Simulator::decodeTypeRegister(SimIn
                 setFpuRegisterLo(fd_reg, kFPUInvalidResult);
               }
               break;
             }
             case ff_cvt_l_fmt:  // Mips64r2: Truncate float to 64-bit long-word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_l_fmt: {  // Mips64r2 instruction.
               float rounded = fs_value > 0 ? std::floor(fs_value + 0.5)
                                            : std::ceil(fs_value - 0.5);
               i64 = I64(rounded);
               setFpuRegister(fd_reg, i64);
               if (setFCSRRoundError<int64_t>(fs_value, rounded)) {
                 setFpuRegister(fd_reg, kFPUInvalidResult64);
               }
@@ -3086,17 +3086,17 @@ void Simulator::decodeTypeRegister(SimIn
               setFCSRBit(fcsr_cc,
                          (ds_value <= dt_value) || (mozilla::IsNaN(ds_value) ||
                                                     mozilla::IsNaN(dt_value)));
               break;
             case ff_cvt_w_fmt:  // Convert double to word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_w_fmt: {  // Round double to word (round half to
                                     // even).
               double rounded = std::floor(ds_value + 0.5);
               int32_t result = I32(rounded);
               if ((result & 1) != 0 && result - ds_value == 0.5) {
                 // If the number is halfway between two integers,
                 // round to the even one.
                 result--;
@@ -3140,17 +3140,17 @@ void Simulator::decodeTypeRegister(SimIn
             case ff_cvt_s_fmt:  // Convert double to float (single).
               setFpuRegisterFloat(fd_reg, static_cast<float>(ds_value));
               break;
             case ff_cvt_l_fmt:  // Mips64r2: Truncate double to 64-bit
                                 // long-word.
               // Rounding modes are not yet supported.
               MOZ_ASSERT((FCSR_ & 3) == 0);
               // In rounding mode 0 it should behave like ROUND.
-              MOZ_FALLTHROUGH;
+              [[fallthrough]];
             case ff_round_l_fmt: {  // Mips64r2 instruction.
               double rounded = ds_value > 0 ? std::floor(ds_value + 0.5)
                                             : std::ceil(ds_value - 0.5);
               i64 = I64(rounded);
               setFpuRegister(fd_reg, i64);
               if (setFCSRRoundError<int64_t>(ds_value, rounded)) {
                 setFpuRegister(fd_reg, kFPUInvalidResult64);
               }
--- a/js/src/new-regexp/regexp-shim.h
+++ b/js/src/new-regexp/regexp-shim.h
@@ -35,17 +35,17 @@ class Isolate;
 class RegExpMatchInfo;
 class RegExpStack;
 
 }  // namespace internal
 }  // namespace v8
 
 #define V8_WARN_UNUSED_RESULT MOZ_MUST_USE
 #define V8_EXPORT_PRIVATE MOZ_EXPORT
-#define V8_FALLTHROUGH MOZ_FALLTHROUGH
+#define V8_FALLTHROUGH [[fallthrough]]
 
 #define FATAL(x) MOZ_CRASH(x)
 #define UNREACHABLE() MOZ_CRASH("unreachable code")
 #define UNIMPLEMENTED() MOZ_CRASH("unimplemented code")
 #define STATIC_ASSERT(exp) static_assert(exp, #exp)
 
 #define DCHECK MOZ_ASSERT
 #define DCHECK_EQ(lhs, rhs) MOZ_ASSERT((lhs) == (rhs))
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2040,17 +2040,17 @@ static bool CacheEntry_setBytecode(JSCon
 
 static bool ConvertTranscodeResultToJSException(JSContext* cx,
                                                 JS::TranscodeResult rv) {
   switch (rv) {
     case JS::TranscodeResult_Ok:
       return true;
 
     default:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case JS::TranscodeResult_Failure:
       MOZ_ASSERT(!cx->isExceptionPending());
       JS_ReportErrorASCII(cx, "generic warning");
       return false;
     case JS::TranscodeResult_Failure_BadBuildId:
       MOZ_ASSERT(!cx->isExceptionPending());
       JS_ReportErrorASCII(cx, "the build-id does not match");
       return false;
--- a/js/src/util/DoubleToString.cpp
+++ b/js/src/util/DoubleToString.cpp
@@ -133,17 +133,17 @@ char* js_dtostr(DtoaState* state, char* 
           minNDigits = decPt + precision;
         else
           minNDigits = decPt;
         break;
 
       case DTOSTR_EXPONENTIAL:
         MOZ_ASSERT(precision > 0);
         minNDigits = precision;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case DTOSTR_STANDARD_EXPONENTIAL:
         exponentialNotation = true;
         break;
 
       case DTOSTR_PRECISION:
         MOZ_ASSERT(precision > 0);
         minNDigits = precision;
         if (decPt < -5 || decPt > precision) exponentialNotation = true;
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -5728,20 +5728,20 @@ class BaseCompiler final : public BaseCo
 
   void needLoadTemps(const MemoryAccessDesc& access, RegI32* temp1,
                      RegI32* temp2, RegI32* temp3) {
 #if defined(JS_CODEGEN_ARM)
     if (IsUnaligned(access)) {
       switch (access.type()) {
         case Scalar::Float64:
           *temp3 = needI32();
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case Scalar::Float32:
           *temp2 = needI32();
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         default:
           *temp1 = needI32();
           break;
       }
     }
 #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     *temp1 = needI32();
 #endif
--- a/js/src/wasm/WasmTextToBinary.cpp
+++ b/js/src/wasm/WasmTextToBinary.cpp
@@ -716,17 +716,17 @@ class WasmTokenStream {
       case WasmToken::Name:
         *ref = AstRef(token.name());
         break;
       case WasmToken::Index:
         if (token.index() != AstNoIndex) {
           *ref = AstRef(token.index());
           break;
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       default:
         generateError(token, error);
         return false;
     }
     return true;
   }
 };
 
@@ -915,17 +915,17 @@ WasmToken WasmTokenStream::next() {
         return WasmToken(WasmToken::Infinity, begin, cur_);
       }
       if (consume(u"nan")) {
         return nan(begin);
       }
       if (!IsWasmDigit(*cur_)) {
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case '0':
     case '1':
     case '2':
     case '3':
     case '4':
     case '5':
     case '6':
     case '7':
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -188,17 +188,17 @@ bool XPCConvert::NativeData2JS(JSContext
         buf->AddRef();
       }
       return true;
     }
 
     case nsXPTType::T_CHAR_STR: {
       const char* p = *static_cast<const char* const*>(s);
       arrlen = p ? strlen(p) : 0;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case nsXPTType::T_PSTRING_SIZE_IS: {
       const char* p = *static_cast<const char* const*>(s);
       if (!p) {
         d.setNull();
         return true;
       }
 
@@ -219,17 +219,17 @@ bool XPCConvert::NativeData2JS(JSContext
 
       d.setString(str);
       return true;
     }
 
     case nsXPTType::T_WCHAR_STR: {
       const char16_t* p = *static_cast<const char16_t* const*>(s);
       arrlen = p ? nsCharTraits<char16_t>::length(p) : 0;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case nsXPTType::T_PWSTRING_SIZE_IS: {
       const char16_t* p = *static_cast<const char16_t* const*>(s);
       if (!p) {
         d.setNull();
         return true;
       }
 
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -868,17 +868,17 @@ static void ProcessArgsForCompartment(JS
       case 'f':
       case 'e':
         if (++i == argc) {
           return;
         }
         break;
       case 'S':
         ContextOptionsRef(cx).toggleWerror();
-        MOZ_FALLTHROUGH;  // because -S implies -s
+        [[fallthrough]];  // because -S implies -s
       case 's':
         ContextOptionsRef(cx).toggleExtraWarnings();
         break;
     }
   }
 }
 
 static bool ProcessArgs(AutoJSAPI& jsapi, char** argv, int argc,
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -7479,17 +7479,17 @@ Element* PresShell::EventHandler::Comput
             (keyDownIsChrome && BrowserParent::GetFrom(eventTargetElement))) {
           eventTargetElement = sLastKeyDownEventTargetElement;
         }
       }
 
       if (aGUIEvent->mMessage == eKeyUp) {
         sLastKeyDownEventTargetElement = nullptr;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       return eventTargetElement;
   }
 }
 
 bool PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell(
     Element* aEventTargetElement, WidgetGUIEvent* aGUIEvent,
     nsEventStatus* aEventStatus, nsresult* aRv) {
@@ -8002,17 +8002,17 @@ void PresShell::EventHandler::RecordEven
       Telemetry::AccumulateTimeDelta(Telemetry::INPUT_EVENT_QUEUED_KEYBOARD_MS,
                                      aEvent->mTimeStamp);
       return;
 
     case eMouseDown:
     case eMouseUp:
       Telemetry::AccumulateTimeDelta(Telemetry::INPUT_EVENT_QUEUED_CLICK_MS,
                                      aEvent->mTimeStamp);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ePointerDown:
     case ePointerUp:
       GetPresContext()->RecordInteractionTime(
           nsPresContext::InteractionType::ClickInteraction, aEvent->mTimeStamp);
       return;
 
     case eMouseMove:
       if (aEvent->mFlags.mHandledByAPZ) {
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4425,17 +4425,17 @@ nsCSSFrameConstructor::FindDisplayData(c
       // their parent reflows them with BoxReflow() which means they have to get
       // actual-XUL frames).
       if (!StaticPrefs::layout_css_emulate_moz_box_with_flex() ||
           aElement.IsXULElement(nsGkAtoms::scrollcorner)) {
         static const FrameConstructionData data =
             SCROLLABLE_ABSPOS_CONTAINER_XUL_FCDATA(NS_NewBoxFrame);
         return &data;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case StyleDisplayInside::Flex:
     case StyleDisplayInside::WebkitBox: {
       static const FrameConstructionData nonScrollableData =
           FCDATA_DECL(0, NS_NewFlexContainerFrame);
       static const FrameConstructionData data =
           FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame);
       return MOZ_UNLIKELY(propagatedScrollToViewport) ? &nonScrollableData
--- a/layout/generic/CSSAlignUtils.cpp
+++ b/layout/generic/CSSAlignUtils.cpp
@@ -125,17 +125,17 @@ nscoord CSSAlignUtils::AlignJustifySelf(
       if (MOZ_LIKELY(isSameSide == (aAlignment == NS_STYLE_ALIGN_BASELINE))) {
         offset = marginStart + aBaselineAdjust;
       } else {
         nscoord size = aChildSize.Size(aAxis, wm);
         offset = aCBSize - (size + marginEnd) - aBaselineAdjust;
       }
       break;
     case NS_STYLE_ALIGN_STRETCH:
-      MOZ_FALLTHROUGH;  // ComputeSize() deals with it
+      [[fallthrough]];  // ComputeSize() deals with it
     case NS_STYLE_ALIGN_START:
       offset = marginStart;
       break;
     case NS_STYLE_ALIGN_END: {
       nscoord size = aChildSize.Size(aAxis, wm);
       offset = aCBSize - (size + marginEnd);
       break;
     }
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -3218,17 +3218,17 @@ CrossAxisPositionTracker::CrossAxisPosit
   if (mPackingSpaceRemaining != 0) {
     switch (mAlignContent) {
       case NS_STYLE_ALIGN_BASELINE:
       case NS_STYLE_ALIGN_LAST_BASELINE:
         NS_WARNING(
             "NYI: "
             "align-items/align-self:left/right/self-start/self-end/baseline/"
             "last baseline");
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case NS_STYLE_ALIGN_FLEX_START:
         // All packing space should go at the end --> nothing to do here.
         break;
       case NS_STYLE_ALIGN_FLEX_END:
         // All packing space goes at the beginning
         mPosition += mPackingSpaceRemaining;
         break;
       case NS_STYLE_ALIGN_CENTER:
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -2437,20 +2437,20 @@ bool nsFloatManager::FloatInfo::MayNarro
 LogicalRect nsFloatManager::ShapeInfo::ComputeShapeBoxRect(
     const StyleShapeSource& aShapeOutside, nsIFrame* const aFrame,
     const LogicalRect& aMarginRect, WritingMode aWM) {
   LogicalRect rect = aMarginRect;
 
   switch (aShapeOutside.GetReferenceBox()) {
     case StyleGeometryBox::ContentBox:
       rect.Deflate(aWM, aFrame->GetLogicalUsedPadding(aWM));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case StyleGeometryBox::PaddingBox:
       rect.Deflate(aWM, aFrame->GetLogicalUsedBorder(aWM));
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case StyleGeometryBox::BorderBox:
       rect.Deflate(aWM, aFrame->GetLogicalUsedMargin(aWM));
       break;
     case StyleGeometryBox::MarginBox:
       // Do nothing. rect is already a margin rect.
       break;
     case StyleGeometryBox::NoBox:
     default:
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3144,17 +3144,17 @@ void nsIFrame::BuildDisplayListForStacki
     switch (decision) {
       case nsDisplayTransform::FullPrerender:
         allowAsyncAnimation = true;
         visibleRect = dirtyRect;
         break;
       case nsDisplayTransform::PartialPrerender:
         allowAsyncAnimation = true;
         visibleRect = dirtyRect;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
         // fall through to the NoPrerender case
       case nsDisplayTransform::NoPrerender:
         if (overflow.IsEmpty() && !extend3DContext) {
           return;
         }
 
         // If we're in preserve-3d then grab the dirty rect that was given to
         // the root and transform using the combined transform.
@@ -8598,17 +8598,17 @@ nsresult nsIFrame::PeekOffset(nsPeekOffs
       // mWordMovementType to eEndWord if we're moving forwards, and to
       // eStartWord if we're moving backwards.
       if (aPos->mDirection == eDirPrevious) {
         aPos->mWordMovementType = eStartWord;
       } else {
         aPos->mWordMovementType = eEndWord;
       }
       // Intentionally fall through the eSelectWord case.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eSelectWord: {
       // wordSelectEatSpace means "are we looking for a boundary between
       // whitespace and non-whitespace (in the direction we're moving in)". It
       // is true when moving forward and looking for a beginning of a word, or
       // when moving backwards and looking for an end of a word.
       bool wordSelectEatSpace;
       if (aPos->mWordMovementType != eDefaultBehavior) {
         // aPos->mWordMovementType possible values:
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -6009,17 +6009,17 @@ void nsGridContainerFrame::Tracks::Align
 
   // Optimize the cases where we just need to set each track's position.
   nscoord pos = 0;
   bool distribute = true;
   switch (alignment) {
     case NS_STYLE_ALIGN_BASELINE:
     case NS_STYLE_ALIGN_LAST_BASELINE:
       NS_WARNING("NYI: 'first/last baseline' (bug 1151204)");  // XXX
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case NS_STYLE_ALIGN_START:
       distribute = false;
       break;
     case NS_STYLE_ALIGN_END:
       pos = space;
       distribute = false;
       break;
     case NS_STYLE_ALIGN_CENTER:
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -2956,17 +2956,17 @@ void nsLineLayout::ExpandRubyBox(PerFram
       }
       if (gaps > 0) {
         JustificationApplicationState state(gaps, aReservedISize);
         ApplyFrameJustification(aFrame->mSpan, state);
         break;
       }
       // If there are no justification opportunities for space-between,
       // fall-through to center per spec.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case StyleRubyAlign::Center:
       // Indent all children by half of the reserved inline size.
       for (PerFrameData* child = aFrame->mSpan->mFirstFrame; child;
            child = child->mNext) {
         child->mBounds.IStart(lineWM) += aReservedISize / 2;
         child->mFrame->SetRect(lineWM, child->mBounds, aContainerSize);
       }
@@ -3143,17 +3143,17 @@ void nsLineLayout::TextAlignLine(nsLineB
                      "Unprocessed justification gaps");
           MOZ_ASSERT(
               applyState.mWidth.mConsumed == applyState.mWidth.mAvailable,
               "Unprocessed justification width");
           break;
         }
         // Fall through to the default case if we could not justify to fill
         // the space.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       }
 
       case NS_STYLE_TEXT_ALIGN_START:
         // default alignment is to start edge so do nothing
         break;
 
       case NS_STYLE_TEXT_ALIGN_LEFT:
       case NS_STYLE_TEXT_ALIGN_MOZ_LEFT:
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -7848,17 +7848,17 @@ bool ClusterIterator::IsPunctuation() {
   // kept together with any adjacent letter/number. (Bug 1066756)
   uint32_t ch = mFrag->CharAt(mCharIndex);
   uint8_t cat = unicode::GetGeneralCategory(ch);
   switch (cat) {
     case HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: /* Pc */
       if (ch == '_' && !sStopAtUnderscore) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION:    /* Pd */
     case HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION:   /* Pe */
     case HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION:   /* Pf */
     case HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: /* Pi */
     case HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION:   /* Po */
     case HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION:    /* Ps */
     case HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL:     /* Sc */
     // Deliberately omitted:
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -3634,17 +3634,17 @@ void nsCSSRendering::GetTableBorderSolid
               SolidBeveledBorderSegment{rightRect,
                                         aBorderColor,
                                         {aStartBevelSide, startBevel},
                                         {aEndBevelSide, endBevel}});
         }
         break;
       }
       // else fall through to solid
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case StyleBorderStyle::Solid:
       aSegments.AppendElement(
           SolidBeveledBorderSegment{aBorder,
                                     aBorderColor,
                                     {aStartBevelSide, aStartBevelOffset},
                                     {aEndBevelSide, aEndBevelOffset}});
       break;
     case StyleBorderStyle::Outset:
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -1207,17 +1207,17 @@ Color MakeBorderColor(nscolor aColor, Bo
   int k = 0;
 
   switch (aBorderColorStyle) {
     case BorderColorStyleNone:
       return Color(0.f, 0.f, 0.f, 0.f);  // transparent black
 
     case BorderColorStyleLight:
       k = 1;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case BorderColorStyleDark:
       NS_GetSpecial3DColors(colors, aColor);
       return Color::FromABGR(colors[k]);
 
     case BorderColorStyleSolid:
     default:
       return Color::FromABGR(aColor);
   }
--- a/layout/printing/PrintPreviewUserEventSuppressor.cpp
+++ b/layout/printing/PrintPreviewUserEventSuppressor.cpp
@@ -151,17 +151,17 @@ PrintPreviewUserEventSuppressor::HandleE
             RefPtr<Element> result;
             fm->MoveFocus(win, fromElement,
                           forward ? nsIFocusManager::MOVEFOCUS_FORWARD
                                   : nsIFocusManager::MOVEFOCUS_BACKWARD,
                           nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
           }
         }
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case eEventAction_Suppress:
         aEvent->StopPropagation();
         aEvent->PreventDefault();
         break;
       case eEventAction_StopPropagation:
         aEvent->StopPropagation();
         break;
       case eEventAction_Propagate:
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -527,17 +527,17 @@ static void InvalidateImages(nsIFrame* a
           // XXX: handle Blob data
           invalidateFrame = true;
           break;
         case layers::WebRenderUserData::UserDataType::eImage:
           if (static_cast<layers::WebRenderImageData*>(data.get())
                   ->UsingSharedSurface(aRequest->GetProducerId())) {
             break;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         default:
           invalidateFrame = true;
           break;
       }
     }
   }
 
   if (invalidateFrame) {
--- a/layout/tables/SpanningCellSorter.cpp
+++ b/layout/tables/SpanningCellSorter.cpp
@@ -86,17 +86,17 @@ int SpanningCellSorter::SortArray(const 
 SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) {
   NS_ASSERTION(mState != DONE, "done enumerating, stop calling");
 
   switch (mState) {
     case ADDING:
       /* prepare to enumerate the array */
       mState = ENUMERATING_ARRAY;
       mEnumerationIndex = 0;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ENUMERATING_ARRAY:
       while (mEnumerationIndex < ARRAY_SIZE && !mArray[mEnumerationIndex])
         ++mEnumerationIndex;
       if (mEnumerationIndex < ARRAY_SIZE) {
         Item* result = mArray[mEnumerationIndex];
         *aColSpan = IndexToSpan(mEnumerationIndex);
         NS_ASSERTION(result, "logic error");
 #ifdef DEBUG_SPANNING_CELL_SORTER
@@ -116,29 +116,29 @@ SpanningCellSorter::Item* SpanningCellSo
         int32_t j = 0;
         for (auto iter = mHashTable.Iter(); !iter.Done(); iter.Next()) {
           sh[j++] = static_cast<HashTableEntry*>(iter.Get());
         }
         NS_QuickSort(sh, mHashTable.EntryCount(), sizeof(sh[0]), SortArray,
                      nullptr);
         mSortedHashTable = sh;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ENUMERATING_HASH:
       if (mEnumerationIndex < mHashTable.EntryCount()) {
         Item* result = mSortedHashTable[mEnumerationIndex]->mItems;
         *aColSpan = mSortedHashTable[mEnumerationIndex]->mColSpan;
         NS_ASSERTION(result, "holes in hash table");
 #ifdef DEBUG_SPANNING_CELL_SORTER
         printf(
             "SpanningCellSorter[%p]:"
             " returning list for colspan=%d from hash\n",
             static_cast<void*>(this), *aColSpan);
 #endif
         ++mEnumerationIndex;
         return result;
       }
       mState = DONE;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case DONE:;
   }
   return nullptr;
 }
--- a/layout/tables/nsCellMap.cpp
+++ b/layout/tables/nsCellMap.cpp
@@ -813,17 +813,17 @@ void nsTableCellMap::ResetBStartStart(Lo
   if (!mBCInfo) ABORT0();
 
   BCCellData* cellData;
   BCData* bcData = nullptr;
 
   switch (aSide) {
     case eLogicalSideBEnd:
       aRowIndex++;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eLogicalSideBStart:
       cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex - aRowGroupStart,
                                                  aColIndex);
       if (cellData) {
         bcData = &cellData->mData;
       } else {
         NS_ASSERTION(aSide == eLogicalSideBEnd, "program error");
         // try the next row group
@@ -835,17 +835,17 @@ void nsTableCellMap::ResetBStartStart(Lo
           } else {
             bcData = GetBEndMostBorder(aColIndex);
           }
         }
       }
       break;
     case eLogicalSideIEnd:
       aColIndex++;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eLogicalSideIStart:
       cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex - aRowGroupStart,
                                                  aColIndex);
       if (cellData) {
         bcData = &cellData->mData;
       } else {
         NS_ASSERTION(aSide == eLogicalSideIEnd, "program error");
         bcData = GetIEndMostBorder(aRowIndex);
@@ -875,17 +875,17 @@ void nsTableCellMap::SetBCBorderEdge(Log
   int32_t yPos = aRowIndex;
   int32_t rgYPos = aRowIndex - aCellMapStart;
   bool changed;
 
   switch (aSide) {
     case eLogicalSideBEnd:
       rgYPos++;
       yPos++;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eLogicalSideBStart:
       lastIndex = xPos + aLength - 1;
       for (xIndex = xPos; xIndex <= lastIndex; xIndex++) {
         changed = aChanged && (xIndex == xPos);
         BCData* bcData = nullptr;
         cellData = (BCCellData*)aCellMap.GetDataAt(rgYPos, xIndex);
         if (!cellData) {
           int32_t numRgRows = aCellMap.GetRowCount();
@@ -919,17 +919,17 @@ void nsTableCellMap::SetBCBorderEdge(Log
         if (bcData) {
           bcData->SetBStartEdge(aOwner, aSize, changed);
         } else
           NS_ERROR("Cellmap: BStart edge not found");
       }
       break;
     case eLogicalSideIEnd:
       xPos++;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eLogicalSideIStart:
       // since bStart, bEnd borders were set, there should already be a cellData
       // entry
       lastIndex = rgYPos + aLength - 1;
       for (yIndex = rgYPos; yIndex <= lastIndex; yIndex++) {
         changed = aChanged && (yIndex == rgYPos);
         cellData = (BCCellData*)aCellMap.GetDataAt(yIndex, xPos);
         if (cellData) {
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -573,17 +573,17 @@ void nsTableCellFrame::BlockDirAlignChil
       if (!GetContentEmpty()) {
         // Align the baselines of the child frame with the baselines of
         // other children in the same row which have 'vertical-align: baseline'
         kidBStart = bStartInset + aMaxAscent - GetCellBaseline();
         break;
       }
       // Empty cells don't participate in baseline alignment -
       // fallback to start alignment.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case StyleVerticalAlignKeyword::Top:
       // Align the top of the child frame with the top of the content area,
       kidBStart = bStartInset;
       break;
 
     case StyleVerticalAlignKeyword::Bottom:
       // Align the bottom of the child frame with the bottom of the content
       // area,
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -6706,51 +6706,51 @@ Maybe<BCBorderParameters> BCBlockDirSeg:
     case eTableOwner:
       owner = aIter.mTable;
       break;
     case eAjaColGroupOwner:
       side = eLogicalSideIEnd;
       if (!aIter.IsTableIEndMost() && (relColIndex > 0)) {
         col = aIter.mBlockDirInfo[relColIndex - 1].mCol;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eColGroupOwner:
       if (col) {
         owner = col->GetParent();
       }
       break;
     case eAjaColOwner:
       side = eLogicalSideIEnd;
       if (!aIter.IsTableIEndMost() && (relColIndex > 0)) {
         col = aIter.mBlockDirInfo[relColIndex - 1].mCol;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eColOwner:
       owner = col;
       break;
     case eAjaRowGroupOwner:
       NS_ERROR("a neighboring rowgroup can never own a vertical border");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eRowGroupOwner:
       NS_ASSERTION(aIter.IsTableIStartMost() || aIter.IsTableIEndMost(),
                    "row group can own border only at table edge");
       owner = mFirstRowGroup;
       break;
     case eAjaRowOwner:
       NS_ERROR("program error");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eRowOwner:
       NS_ASSERTION(aIter.IsTableIStartMost() || aIter.IsTableIEndMost(),
                    "row can own border only at table edge");
       owner = mFirstRow;
       break;
     case eAjaCellOwner:
       side = eLogicalSideIEnd;
       cell = mAjaCell;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eCellOwner:
       owner = cell;
       break;
   }
   if (owner) {
     ::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle,
                         &result.mBorderColor);
     result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
@@ -7105,52 +7105,52 @@ Maybe<BCBorderParameters> BCInlineDirSeg
   result.mBorderColor = 0xFFFFFFFF;
 
   switch (mOwner) {
     case eTableOwner:
       owner = aIter.mTable;
       break;
     case eAjaColGroupOwner:
       NS_ERROR("neighboring colgroups can never own an inline-dir border");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eColGroupOwner:
       NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(),
                    "col group can own border only at the table edge");
       col = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1);
       if (!col) ABORT1(Nothing());
       owner = col->GetParent();
       break;
     case eAjaColOwner:
       NS_ERROR("neighboring column can never own an inline-dir border");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eColOwner:
       NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(),
                    "col can own border only at the table edge");
       owner = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1);
       break;
     case eAjaRowGroupOwner:
       side = eLogicalSideBEnd;
       rg = (aIter.IsTableBEndMost()) ? aIter.mRg : aIter.mPrevRg;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eRowGroupOwner:
       owner = rg;
       break;
     case eAjaRowOwner:
       side = eLogicalSideBEnd;
       row = (aIter.IsTableBEndMost()) ? aIter.mRow : aIter.mPrevRow;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eRowOwner:
       owner = row;
       break;
     case eAjaCellOwner:
       side = eLogicalSideBEnd;
       // if this is null due to the damage area origin-y > 0, then the border
       // won't show up anyway
       cell = mAjaCell;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eCellOwner:
       owner = cell;
       break;
   }
   if (owner) {
     ::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle,
                         &result.mBorderColor);
     result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -2144,17 +2144,17 @@ bool nsXULPopupManager::HandleKeyboardEv
     case KeyboardEvent_Binding::DOM_VK_DOWN:
 #ifndef XP_MACOSX
       // roll up the popup when alt+up/down are pressed within a menulist.
       if (aKeyEvent->AltKey() && aTopVisibleMenuItem &&
           aTopVisibleMenuItem->Frame()->IsMenuList()) {
         Rollup(0, false, nullptr, nullptr);
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 #endif
 
     case KeyboardEvent_Binding::DOM_VK_LEFT:
     case KeyboardEvent_Binding::DOM_VK_RIGHT:
     case KeyboardEvent_Binding::DOM_VK_HOME:
     case KeyboardEvent_Binding::DOM_VK_END:
       HandleKeyboardNavigation(keyCode);
       break;
@@ -2190,17 +2190,17 @@ bool nsXULPopupManager::HandleKeyboardEv
         // close popups or deactivate menubar when Tab or F10 are pressed
         Rollup(0, false, nullptr, nullptr);
         break;
       } else if (mActiveMenuBar) {
         mActiveMenuBar->MenuClosed();
         break;
       }
       // Intentional fall-through to RETURN case
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case KeyboardEvent_Binding::DOM_VK_RETURN: {
       // If there is a popup open, check if the current item needs to be opened.
       // Otherwise, tell the active menubar, if any, to activate the menu. The
       // Enter method will return a menu if one needs to be opened as a result.
       nsMenuFrame* menuToOpen = nullptr;
       WidgetGUIEvent* GUIEvent = aKeyEvent->WidgetEventPtr()->AsGUIEvent();
 
--- a/media/mtransport/transportlayerdtls.cpp
+++ b/media/mtransport/transportlayerdtls.cpp
@@ -900,17 +900,17 @@ void TransportLayerDtls::Handshake() {
     timer_ = nullptr;
   } else {
     int32_t err = PR_GetError();
     switch (err) {
       case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
         MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring");
         // If this were TLS (and not DTLS), this would be fatal, but
         // here we're required to ignore bad messages, so fall through
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case PR_WOULD_BLOCK_ERROR:
         MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Handshake would have blocked");
         PRIntervalTime timeout;
         rv = DTLS_GetHandshakeTimeout(ssl_fd_.get(), &timeout);
         if (rv == SECSuccess) {
           uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout);
 
           MOZ_MTLOG(ML_DEBUG,
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -624,30 +624,30 @@ struct AssertionConditionType {
   } while (false)
 
 /**
  * MOZ_FALLTHROUGH_ASSERT is an annotation to suppress compiler warnings about
  * switch cases that MOZ_ASSERT(false) (or its alias MOZ_ASSERT_UNREACHABLE) in
  * debug builds, but intentionally fall through in release builds to handle
  * unexpected values.
  *
- * Why do we need MOZ_FALLTHROUGH_ASSERT in addition to MOZ_FALLTHROUGH? In
+ * Why do we need MOZ_FALLTHROUGH_ASSERT in addition to [[fallthrough]]? In
  * release builds, the MOZ_ASSERT(false) will expand to `do { } while (false)`,
- * requiring a MOZ_FALLTHROUGH annotation to suppress a -Wimplicit-fallthrough
+ * requiring a [[fallthrough]] annotation to suppress a -Wimplicit-fallthrough
  * warning. In debug builds, the MOZ_ASSERT(false) will expand to something like
- * `if (true) { MOZ_CRASH(); }` and the MOZ_FALLTHROUGH annotation will cause
+ * `if (true) { MOZ_CRASH(); }` and the [[fallthrough]] annotation will cause
  * a -Wunreachable-code warning. The MOZ_FALLTHROUGH_ASSERT macro breaks this
  * warning stalemate.
  *
  * // Example before MOZ_FALLTHROUGH_ASSERT:
  * switch (foo) {
  *   default:
  *     // This case wants to assert in debug builds, fall through in release.
  *     MOZ_ASSERT(false); // -Wimplicit-fallthrough warning in release builds!
- *     MOZ_FALLTHROUGH;   // but -Wunreachable-code warning in debug builds!
+ *     [[fallthrough]];   // but -Wunreachable-code warning in debug builds!
  *   case 5:
  *     return 5;
  * }
  *
  * // Example with MOZ_FALLTHROUGH_ASSERT:
  * switch (foo) {
  *   default:
  *     // This case asserts in debug builds, falls through in release.
@@ -655,17 +655,17 @@ struct AssertionConditionType {
  *   case 5:
  *     return 5;
  * }
  */
 #ifdef DEBUG
 #  define MOZ_FALLTHROUGH_ASSERT(...) \
     MOZ_CRASH("MOZ_FALLTHROUGH_ASSERT: " __VA_ARGS__)
 #else
-#  define MOZ_FALLTHROUGH_ASSERT(...) MOZ_FALLTHROUGH
+#  define MOZ_FALLTHROUGH_ASSERT(...) [[fallthrough]]
 #endif
 
 /*
  * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided
  * expression, in debug builds and in release builds both.  Then, in debug
  * builds only, the value of the expression is asserted either true or false
  * using MOZ_ASSERT.
  */
--- a/modules/libjar/nsJARInputStream.cpp
+++ b/modules/libjar/nsJARInputStream.cpp
@@ -113,17 +113,17 @@ nsresult nsJARInputStream::InitDirectory
       case '[':
       case ']':
       case '^':
       case '~':
       case '(':
       case ')':
       case '\\':
         escDirName.Append('\\');
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       default:
         escDirName.Append(*curr);
     }
     ++curr;
   }
   nsAutoCString pattern = escDirName + NS_LITERAL_CSTRING("?*~") + escDirName +
                           NS_LITERAL_CSTRING("?*/?*");
   rv = mJar->mZip->FindInit(pattern.get(), &find);
--- a/mozglue/linker/XZStream.cpp
+++ b/mozglue/linker/XZStream.cpp
@@ -91,21 +91,21 @@ size_t XZStream::Decode(void* aOutBuf, s
   while (mBuffers.in_pos < mBuffers.in_size &&
          mBuffers.out_pos < mBuffers.out_size) {
     const xz_ret ret = xz_dec_run(mDec, &mBuffers);
 
     switch (ret) {
       case XZ_STREAM_END:
         // Stream ended, the next loop iteration should terminate.
         MOZ_ASSERT(mBuffers.in_pos == mBuffers.in_size);
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 #ifdef XZ_DEC_ANY_CHECK
       case XZ_UNSUPPORTED_CHECK:
         // Ignore unsupported check.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 #endif
       case XZ_OK:
         // Chunk decoded, proceed.
         break;
 
       case XZ_MEM_ERROR:
         ERROR("XZ decoding: memory allocation failed");
         return 0;
@@ -118,17 +118,17 @@ size_t XZStream::Decode(void* aOutBuf, s
         ERROR("XZ decoding: invalid stream format");
         return 0;
 
       case XZ_OPTIONS_ERROR:
         ERROR("XZ decoding: unsupported header options");
         return 0;
 
       case XZ_DATA_ERROR:
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case XZ_BUF_ERROR:
         ERROR("XZ decoding: corrupt input stream");
         return 0;
 
       default:
         MOZ_ASSERT_UNREACHABLE("XZ decoding: unknown error condition");
         return 0;
     }
--- a/mozglue/misc/Printf.cpp
+++ b/mozglue/misc/Printf.cpp
@@ -868,17 +868,17 @@ bool mozilla::PrintfTarget::vprint(const
 
       case 's':
         if (type == TYPE_INTN) {
           u.s = va_arg(ap, const char*);
           if (!cvt_s(u.s, width, prec, flags)) return false;
           break;
         }
         MOZ_ASSERT(type == TYPE_LONG);
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case 'S':
 #if defined(XP_WIN)
       {
         u.ws = va_arg(ap, const wchar_t*);
 
         int rv = WideCharToMultiByte(CP_ACP, 0, u.ws, -1, NULL, 0, NULL, NULL);
         if (rv == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
           if (!cvt_s("<unicode errors in string>", width, prec, flags)) {
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -440,17 +440,17 @@ inline nsresult ParseIPv4Number(const ns
                                 uint32_t& number, uint32_t maxNumber) {
   // Accumulate in the 64-bit value
   uint64_t value = 0;
   const char* current = input.BeginReading();
   const char* end = input.EndReading();
   switch (base) {
     case 16:
       ++current;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 8:
       ++current;
       break;
     case 10:
     default:
       break;
   }
   for (; current < end; ++current) {
--- a/netwerk/base/nsURLHelper.cpp
+++ b/netwerk/base/nsURLHelper.cpp
@@ -367,17 +367,17 @@ nsresult net_ResolveRelativePath(const n
   for (; !stop; ++beg) {
     c = (beg == end) ? '\0' : *beg;
     // printf("%c [name=%s] [path=%s]\n", c, name.get(), path.get());
     switch (c) {
       case '\0':
       case '#':
       case '?':
         stop = true;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case '/':
         // delimiter found
         if (name.EqualsLiteral("..")) {
           // pop path
           // If we already have the delim at end, then
           //  skip over that when searching for next one to the left
           int32_t offset = path.Length() - (needsDelim ? 1 : 2);
           // First check for errors
--- a/netwerk/cache2/CacheHashUtils.cpp
+++ b/netwerk/cache2/CacheHashUtils.cpp
@@ -72,45 +72,45 @@ CacheHash::Hash32_t CacheHash::Hash(cons
     len -= 12;
   }
 
   /*------------------------------------- handle the last 11 bytes */
   c += aSize;
   switch (len) { /* all the case statements fall through */
     case 11:
       c += (uint32_t(k[10]) << 24);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 10:
       c += (uint32_t(k[9]) << 16);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 9:
       c += (uint32_t(k[8]) << 8);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     /* the low-order byte of c is reserved for the length */
     case 8:
       b += (uint32_t(k[7]) << 24);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 7:
       b += (uint32_t(k[6]) << 16);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 6:
       b += (uint32_t(k[5]) << 8);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 5:
       b += k[4];
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 4:
       a += (uint32_t(k[3]) << 24);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 3:
       a += (uint32_t(k[2]) << 16);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       a += (uint32_t(k[1]) << 8);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       a += k[0];
       /* case 0: nothing left to add */
   }
   hashmix(a, b, c);
 
   return c;
 }
@@ -185,20 +185,20 @@ void CacheHash::Update(const char* aData
          (uint32_t(data[3]) << 24));
     data += 4;
     aLen -= 4;
   }
 
   switch (aLen) {
     case 3:
       mBuf += data[2] << 16;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       mBuf += data[1] << 8;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       mBuf += data[0];
   }
 
   mBufPos = aLen;
 }
 
 CacheHash::Hash32_t CacheHash::GetHash() {
--- a/netwerk/cache2/CacheIndex.cpp
+++ b/netwerk/cache2/CacheIndex.cpp
@@ -141,17 +141,17 @@ class CacheIndexEntryAutoManage {
     const CacheIndexEntry* entry = nullptr;
 
     switch (mIndex->mState) {
       case CacheIndex::READING:
       case CacheIndex::WRITING:
         if (!mDoNotSearchInUpdates) {
           entry = mIndex->mPendingUpdates.GetEntry(*mHash);
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case CacheIndex::BUILDING:
       case CacheIndex::UPDATING:
       case CacheIndex::READY:
         if (!entry && !mDoNotSearchInIndex) {
           entry = mIndex->mIndex.GetEntry(*mHash);
         }
         break;
       case CacheIndex::INITIAL:
@@ -441,17 +441,17 @@ nsresult CacheIndex::Shutdown() {
     LOG(
         ("CacheIndex::Shutdown() - Unexpected state. Did posting of "
          "PreShutdownInternal() fail?"));
   }
 
   switch (oldState) {
     case WRITING:
       index->FinishWrite(false);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case READY:
       if (index->mIndexOnDiskIsValid && !index->mDontMarkIndexClean) {
         if (!sanitize && NS_FAILED(index->WriteLogToDisk())) {
           index->RemoveJournalAndTempFile();
         }
       } else {
         index->RemoveJournalAndTempFile();
       }
@@ -1220,17 +1220,17 @@ nsresult CacheIndex::HasEntry(
   }
 
   const CacheIndexEntry* entry = nullptr;
 
   switch (index->mState) {
     case READING:
     case WRITING:
       entry = index->mPendingUpdates.GetEntry(hash);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case BUILDING:
     case UPDATING:
     case READY:
       if (!entry) {
         entry = index->mIndex.GetEntry(hash);
       }
       break;
     case INITIAL:
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -437,17 +437,17 @@ class WalkDiskCacheRunnable : public Wal
           // Invoke onCacheStorageInfo with valid information.
           NS_DispatchToMainThread(this);
 
           if (!mVisitEntries) {
             return NS_OK;  // done
           }
 
           mPass = ITERATE_METADATA;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         case ITERATE_METADATA:
           // Now grab the context iterator.
           if (!mIter) {
             rv =
                 CacheIndex::GetIterator(mLoadInfo, true, getter_AddRefs(mIter));
             if (NS_FAILED(rv)) {
               // Invoke onCacheEntryVisitCompleted now
--- a/netwerk/cookie/nsCookiePermission.cpp
+++ b/netwerk/cookie/nsCookiePermission.cpp
@@ -66,17 +66,17 @@ nsCookiePermission::CanSetCookie(nsIURI*
 
   nsCookie* cookie = static_cast<nsCookie*>(aCookie);
   uint32_t perm;
   mPermMgr->LegacyTestPermissionFromURI(aURI, &cookie->OriginAttributesRef(),
                                         NS_LITERAL_CSTRING("cookie"), &perm);
   switch (perm) {
     case nsICookiePermission::ACCESS_SESSION:
       *aIsSession = true;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case nsICookiePermission::ACCESS_ALLOW:
       *aResult = true;
       break;
 
     case nsICookiePermission::ACCESS_DENY:
       *aResult = false;
       break;
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -839,17 +839,17 @@ OpenDBResult nsCookieService::TryInitDB(
       // might one day see it and fix it.
       case 1: {
         // Add the lastAccessed column to the table.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
             "ALTER TABLE moz_cookies ADD lastAccessed INTEGER"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
       }
         // Fall through to the next upgrade.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 2: {
         // Add the baseDomain column and index to the table.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("ALTER TABLE moz_cookies ADD baseDomain TEXT"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         // Compute the baseDomains for the table. This must be done eagerly
@@ -897,17 +897,17 @@ OpenDBResult nsCookieService::TryInitDB(
         }
 
         // Create an index on baseDomain.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
             "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
       }
         // Fall through to the next upgrade.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 3: {
         // Add the creationTime column to the table, and create a unique index
         // on (name, host, path). Before we do this, we have to purge the table
         // of expired cookies such that we know that the (name, host, path)
         // index is truly unique -- otherwise we can't create the index. Note
         // that we can't just execute a statement to delete all rows where the
         // expiry column is in the past -- doing so would rely on the clock
@@ -993,17 +993,17 @@ OpenDBResult nsCookieService::TryInitDB(
 
         // Create a unique index on (name, host, path) to allow fast lookup.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("CREATE UNIQUE INDEX moz_uniqueid "
                                "ON moz_cookies (name, host, path)"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
       }
         // Fall through to the next upgrade.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 4: {
         // We need to add appId/inBrowserElement, plus change a constraint on
         // the table (unique entries now include appId/inBrowserElement):
         // this requires creating a new table and copying the data to it.  We
         // then rename the new table to the old name.
         //
         // Why we made this change: appId/inBrowserElement allow "cookie jars"
@@ -1041,17 +1041,17 @@ OpenDBResult nsCookieService::TryInitDB(
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("DROP TABLE moz_cookies_old"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 5"));
       }
         // Fall through to the next upgrade.
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 5: {
         // Change in the version: Replace the columns |appId| and
         // |inBrowserElement| by a single column |originAttributes|.
         //
         // Why we made this change: FxOS new security model (NSec) encapsulates
         // "appId/inIsolatedMozBrowser" in nsIPrincipal::originAttributes to
         // make it easier to modify the contents of this structure in the
@@ -1108,17 +1108,17 @@ OpenDBResult nsCookieService::TryInitDB(
         // Drop old table
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("DROP TABLE moz_cookies_old"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 6"));
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 6: {
         // We made a mistake in schema version 6. We cannot remove expected
         // columns of any version (checked in the default case) from cookie
         // database, because doing this would destroy the possibility of
         // downgrading database.
         //
         // This version simply restores appId and inBrowserElement columns in
@@ -1163,17 +1163,17 @@ OpenDBResult nsCookieService::TryInitDB(
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         rv = mDefaultDBState->syncConn->RemoveFunction(setInBrowserName);
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 7"));
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 7: {
         // Remove the appId field from moz_cookies.
         //
         // Unfortunately sqlite doesn't support dropping columns using ALTER
         // TABLE, so we need to go through the procedure documented in
         // https://www.sqlite.org/lang_altertable.html.
 
@@ -1248,28 +1248,28 @@ OpenDBResult nsCookieService::TryInitDB(
 
         // Recreate our index.
         rv = CreateIndex();
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 8"));
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 8: {
         // Add the sameSite column to the table.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(
             NS_LITERAL_CSTRING("ALTER TABLE moz_cookies ADD sameSite INTEGER"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 9"));
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case 9: {
         // Add the rawSameSite column to the table.
         rv = mDefaultDBState->syncConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
             "ALTER TABLE moz_cookies ADD rawSameSite INTEGER"));
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
 
         // Copy the current sameSite value into rawSameSite.
@@ -1280,17 +1280,17 @@ OpenDBResult nsCookieService::TryInitDB(
         COOKIE_LOGSTRING(LogLevel::Debug,
                          ("Upgraded database to schema version 10"));
 
         // No more upgrades. Update the schema version.
         rv =
             mDefaultDBState->syncConn->SetSchemaVersion(COOKIES_SCHEMA_VERSION);
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
       }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case COOKIES_SCHEMA_VERSION:
         break;
 
       case 0: {
         NS_WARNING("couldn't get schema version!");
 
         // the table may be usable; someone might've just clobbered the schema
@@ -1298,17 +1298,17 @@ OpenDBResult nsCookieService::TryInitDB(
         // below, by verifying the columns we care about are all there. for now,
         // re-set the schema version in the db, in case the checks succeed (if
         // they don't, we're dropping the table anyway).
         rv =
             mDefaultDBState->syncConn->SetSchemaVersion(COOKIES_SCHEMA_VERSION);
         NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
       }
         // fall through to downgrade check
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // downgrading.
       // if columns have been added to the table, we can still use the ones we
       // understand safely. if columns have been deleted or altered, just
       // blow away the table and start from scratch! if you change the way
       // a column is interpreted, make sure you also change its name so this
       // check will catch it.
       default: {
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -1506,17 +1506,17 @@ nsresult Http2Stream::OnReadSegment(cons
         return NS_BASE_STREAM_WOULD_BLOCK;
       }
       if (dataLength > mRequestBodyLenRemaining) {
         return NS_ERROR_UNEXPECTED;
       }
       mRequestBodyLenRemaining -= dataLength;
       GenerateDataFrameHeader(dataLength, !mRequestBodyLenRemaining);
       ChangeState(SENDING_BODY);
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case SENDING_BODY:
       MOZ_ASSERT(mTxInlineFrameUsed, "OnReadSegment Send Data Header 0b");
       rv = TransmitFrame(buf, countRead, false);
       MOZ_ASSERT(NS_FAILED(rv) || !mTxInlineFrameUsed,
                  "Transmit Frame should be all or nothing");
 
       LOG3(("TransmitFrame() rv=%" PRIx32 " returning %d data bytes. "
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -2817,17 +2817,17 @@ nsresult nsHttpChannel::ContinueProcessR
         mAuthRetryPending = true;  // see DoAuthRetry
       }
       break;
 
     case 425:
     case 429:
       // Do not cache 425 and 429.
       CloseCacheEntry(false);
-      MOZ_FALLTHROUGH;  // process normally
+      [[fallthrough]];  // process normally
     default:
       rv = ProcessNormal();
       MaybeInvalidateCacheEntryForSubsequentGet();
       break;
   }
 
   UpdateCacheDisposition(false, false);
   return rv;
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -1692,17 +1692,17 @@ nsresult nsHttpTransaction::HandleConten
       // wait to be called again...
       return NS_OK;
     }
 
     // check if this is a no-content response
     switch (mResponseHead->Status()) {
       case 101:
         mPreserveStream = true;
-        MOZ_FALLTHROUGH;  // to other no content cases:
+        [[fallthrough]];  // to other no content cases:
       case 204:
       case 205:
       case 304:
         mNoContent = true;
         LOG(("this response should not contain a body.\n"));
         break;
       case 421:
         LOG(("Misdirected Request.\n"));
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -2039,17 +2039,17 @@ void WebSocketChannel::PrimeNewOutgoingM
         if (NS_FAILED(rv)) {
           AbortSession(NS_ERROR_FILE_TOO_BIG);
           return;
         }
         // Now we're a binary string
         msgType = kMsgTypeBinaryString;
 
         // no break: fall down into binary string case
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case kMsgTypeBinaryString:
         mOutHeader[0] = kFinalFragBit | nsIWebSocketFrame::OPCODE_BINARY;
         break;
       case kMsgTypeFin:
         MOZ_ASSERT(false, "unreachable");  // avoid compiler warning
         break;
     }
--- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
+++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
@@ -47,17 +47,17 @@ void mozTXTToHTMLConv::EscapeChar(const 
       aStringToAppendTo.AppendLiteral("&amp;");
       break;
     case '"':
       if (inAttribute) {
         aStringToAppendTo.AppendLiteral("&quot;");
         break;
       }
       // else fall through
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       aStringToAppendTo += ch;
   }
 }
 
 // EscapeStr takes the passed in string and
 // escapes it IN PLACE.
 void mozTXTToHTMLConv::EscapeStr(nsString& aInString, bool inAttribute) {
@@ -88,17 +88,17 @@ void mozTXTToHTMLConv::EscapeStr(nsStrin
       case '"':
         if (inAttribute) {
           aInString.Cut(i, 1);
           aInString.InsertLiteral(u"&quot;", i);
           i += 6;
           break;
         }
         // else fall through
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       default:
         i++;
     }
   }
 }
 
 void mozTXTToHTMLConv::UnescapeStr(const char16_t* aInString, int32_t aStartPos,
                                    int32_t aLength, nsString& aOutString) {
@@ -450,17 +450,17 @@ bool mozTXTToHTMLConv::FindURL(const cha
   /* all modes but abbreviated are checked for text[pos] == ':',
      only abbreviated for '.', RFC2396E and abbreviated for '@' */
   for (modetype iState = unknown; iState <= mozTXTToHTMLConv_lastMode;
        iState = modetype(iState + 1))
     state[iState] = aInString[pos] == ':' ? unchecked : invalid;
   switch (aInString[pos]) {
     case '@':
       state[RFC2396E] = unchecked;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case '.':
       state[abbreviated] = unchecked;
       break;
     case ':':
       state[abbreviated] = invalid;
       break;
     default:
       break;
--- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
+++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
@@ -288,17 +288,17 @@ nsHTTPCompressConv::OnDataAvailable(nsIR
       if (rv != NS_OK) {
         return rv;
       }
 
       if (streamLen == 0) {
         return NS_OK;
       }
 
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case HTTP_COMPRESS_DEFLATE:
 
       if (mInpBuffer != nullptr && streamLen > mInpBufferLen) {
         unsigned char* originalInpBuffer = mInpBuffer;
         if (!(mInpBuffer = (unsigned char*)realloc(
                   originalInpBuffer, mInpBufferLen = streamLen))) {
           free(originalInpBuffer);
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
@@ -659,17 +659,17 @@ nsresult nsMultiMixedConv::ConsumeToken(
       break;
 
     case BODY_INIT:
       rv = SendStart();
       if (NS_FAILED(rv)) {
         return rv;
       }
       mParserState = BODY;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case BODY: {
       if (!token.Equals(mLFToken) && !token.Equals(mCRLFToken)) {
         if (token.Equals(mBoundaryTokenWithDashes) ||
             token.Equals(mBoundaryToken)) {
           // Allow CRLF to NOT be part of the boundary as well
           SwitchToControlParsing();
           mParserState = TRAIL_DASH1;
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -548,17 +548,17 @@ void nsHtml5Highlighter::FlushChars() {
       switch (c) {
         case '\r':
           // The input this code sees has been normalized so that there are
           // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
           // to show consistent LF line breaks to layout. It is OK to mutate
           // the input data, because there are no reparses in the View Source
           // case, so we won't need the original data in the buffer anymore.
           buf[i] = '\n';
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case '\n': {
           ++i;
           if (mCStart < i) {
             int32_t len = i - mCStart;
             AppendCharacters(buf, mCStart, len);
             mCStart = i;
           }
           ++mLineNumber;
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -903,17 +903,17 @@ class ContentSandboxPolicy : public Sand
       case SYS_GETPEERNAME:
       case SYS_SHUTDOWN:
         return Some(Allow());
       case SYS_ACCEPT:
       case SYS_ACCEPT4:
         if (mUsingRenderDoc) {
           return Some(Allow());
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 #endif
       default:
         return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
     }
   }
 
 #ifdef DESKTOP
   Maybe<ResultExpr> EvaluateIpcCall(int aCall) const override {
--- a/storage/mozStoragePrivateHelpers.cpp
+++ b/storage/mozStoragePrivateHelpers.cpp
@@ -200,17 +200,17 @@ Variant_base* convertVariantToStorageVar
       // Note this copies the array data.
       nsresult rv = aVariant->GetAsArray(&type, &iid, &len, &rawArray);
       NS_ENSURE_SUCCESS(rv, nullptr);
       if (type == nsIDataType::VTYPE_UINT8) {
         std::pair<uint8_t*, int> v(static_cast<uint8_t*>(rawArray), len);
         // Take ownership of the data avoiding a further copy.
         return new AdoptedBlobVariant(v);
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case nsIDataType::VTYPE_EMPTY:
     case nsIDataType::VTYPE_EMPTY_ARRAY:
     case nsIDataType::VTYPE_VOID:
       return new NullVariant();
     case nsIDataType::VTYPE_ID:
     case nsIDataType::VTYPE_INTERFACE:
     case nsIDataType::VTYPE_INTERFACE_IS:
--- a/toolkit/components/antitracking/AntiTrackingCommon.cpp
+++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp
@@ -479,17 +479,17 @@ void ReportUnblockingToConsole(
         const char* messageWithSameOrigin = nullptr;
 
         switch (aReason) {
           case AntiTrackingCommon::eStorageAccessAPI:
             messageWithSameOrigin = "CookieAllowedForTrackerByStorageAccessAPI";
             break;
 
           case AntiTrackingCommon::eOpenerAfterUserInteraction:
-            MOZ_FALLTHROUGH;
+            [[fallthrough]];
           case AntiTrackingCommon::eOpener:
             messageWithSameOrigin = "CookieAllowedForTrackerByHeuristic";
             break;
         }
 
         nsContentUtils::ReportToConsole(
             nsIScriptError::warningFlag, NS_LITERAL_CSTRING("Content Blocking"),
             doc, nsContentUtils::eNECKO_PROPERTIES, messageWithSameOrigin,
--- a/toolkit/components/places/nsAnnotationService.cpp
+++ b/toolkit/components/places/nsAnnotationService.cpp
@@ -110,31 +110,31 @@ nsAnnotationService::SetItemAnnotation(i
       if (NS_SUCCEEDED(rv)) {
         NS_ENSURE_SUCCESS(rv, rv);
         rv = SetAnnotationInt32Internal(aItemId, &bookmark, aName, valueInt,
                                         aFlags, aExpiration);
         NS_ENSURE_SUCCESS(rv, rv);
         break;
       }
       // Fall through int64_t case otherwise.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case nsIDataType::VTYPE_INT64:
     case nsIDataType::VTYPE_UINT64: {
       int64_t valueLong;
       nsresult rv = aValue->GetAsInt64(&valueLong);
       if (NS_SUCCEEDED(rv)) {
         NS_ENSURE_SUCCESS(rv, rv);
         rv = SetAnnotationInt64Internal(aItemId, &bookmark, aName, valueLong,
                                         aFlags, aExpiration);
         NS_ENSURE_SUCCESS(rv, rv);
         break;
       }
       // Fall through double case otherwise.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case nsIDataType::VTYPE_FLOAT:
     case nsIDataType::VTYPE_DOUBLE: {
       double valueDouble;
       nsresult rv = aValue->GetAsDouble(&valueDouble);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = SetAnnotationDoubleInternal(aItemId, &bookmark, aName, valueDouble,
                                        aFlags, aExpiration);
--- a/toolkit/components/places/nsNavHistoryResult.cpp
+++ b/toolkit/components/places/nsNavHistoryResult.cpp
@@ -2051,17 +2051,17 @@ nsresult nsNavHistoryQueryResultNode::On
 
       nsAutoCString host;
       if (NS_FAILED(aURI->GetAsciiHost(host))) return NS_OK;
 
       if (!mQuery->Domain().Equals(host)) return NS_OK;
 
       // Fall through to check the time, if the time is not present it will
       // still match.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
 
     case QUERYUPDATE_TIME: {
       // For these simple yet common cases we can check the time ourselves
       // before doing the overhead of creating a new result node.
       bool hasIt;
       mQuery->GetHasBeginTime(&hasIt);
       if (hasIt) {
@@ -2072,17 +2072,17 @@ nsresult nsNavHistoryQueryResultNode::On
       mQuery->GetHasEndTime(&hasIt);
       if (hasIt) {
         PRTime endTime = history->NormalizeTime(mQuery->EndTimeReference(),
                                                 mQuery->EndTime());
         if (aTime > endTime) return NS_OK;  // after our time range
       }
       // Now we know that our visit satisfies the time range, fall through to
       // the QUERYUPDATE_SIMPLE case below.
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
 
     case QUERYUPDATE_SIMPLE: {
       // The history service can tell us whether the new item should appear
       // in the result.  We first have to construct a node for it to check.
       RefPtr<nsNavHistoryResultNode> addition;
       nsresult rv = history->VisitIdToResultNode(aVisitId, mOptions,
                                                  getter_AddRefs(addition));
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -1084,17 +1084,17 @@ nsresult nsFormFillController::KeyPress(
     }
 #endif
     case KeyboardEvent_Binding::DOM_VK_PAGE_UP:
     case KeyboardEvent_Binding::DOM_VK_PAGE_DOWN: {
       if (keyEvent->CtrlKey() || keyEvent->AltKey() || keyEvent->MetaKey()) {
         break;
       }
     }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case KeyboardEvent_Binding::DOM_VK_UP:
     case KeyboardEvent_Binding::DOM_VK_DOWN:
     case KeyboardEvent_Binding::DOM_VK_LEFT:
     case KeyboardEvent_Binding::DOM_VK_RIGHT: {
       // Get the writing-mode of the relevant input element,
       // so that we can remap arrow keys if necessary.
       mozilla::WritingMode wm;
       if (mFocusedInput) {
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -4056,17 +4056,17 @@ int add_dir_entries(const NS_tchar* dirp
     switch (ftsdirEntry->fts_info) {
       // Filesystem objects that shouldn't be in the application's directories
       case FTS_SL:
       case FTS_SLNONE:
       case FTS_DEFAULT:
         LOG(("add_dir_entries: found a non-standard file: " LOG_S,
              ftsdirEntry->fts_path));
         // Fall through and try to remove as a file
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       // Files
       case FTS_F:
       case FTS_NSOK:
         // Add the file to be removed to the ActionList.
         NS_tsnprintf(foundpath, sizeof(foundpath) / sizeof(foundpath[0]),
                      NS_T("%s"), ftsdirEntry->fts_accpath);
         quotedpath = get_quoted_path(get_relative_path(foundpath));
@@ -4107,17 +4107,17 @@ int add_dir_entries(const NS_tchar* dirp
       case FTS_NS:
         // ENOENT is an acceptable error for FTS_DNR and FTS_NS and means that
         // we're racing with ourselves. Though strange, the entry will be
         // removed anyway.
         if (ENOENT == ftsdirEntry->fts_errno) {
           rv = OK;
           break;
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
 
       case FTS_ERR:
         rv = UNEXPECTED_FILE_OPERATION_ERROR;
         LOG(("add_dir_entries: fts_read() error: " LOG_S ", err: %d",
              ftsdirEntry->fts_path, ftsdirEntry->fts_errno));
         break;
 
       case FTS_DC:
--- a/toolkit/recordreplay/ProcessRedirect.cpp
+++ b/toolkit/recordreplay/ProcessRedirect.cpp
@@ -689,17 +689,17 @@ static size_t CopyInstruction(const char
       break;
     }
     switch (op->type) {
       case UD_OP_MEM:
         if (op->index == UD_R_RIP) {
           UnknownInstruction(aName, aIp, nbytes);
           return nbytes;
         }
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case UD_OP_REG:
         if (op->base == UD_R_RIP) {
           UnknownInstruction(aName, aIp, nbytes);
           return nbytes;
         }
         break;
       default:
         break;
--- a/tools/fuzzing/faulty/Faulty.cpp
+++ b/tools/fuzzing/faulty/Faulty.cpp
@@ -56,39 +56,39 @@ void FuzzIntegralType(T* v, bool largeVa
   static_assert(mozilla::IsIntegral<T>::value == true,
                 "T must be an integral type");
   switch (FuzzingTraits::Random(6)) {
     case 0:
       if (largeValues) {
         (*v) = RandomInteger<T>();
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       if (largeValues) {
         (*v) = RandomNumericLimit<T>();
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       if (largeValues) {
         (*v) = RandomIntegerRange<T>(std::numeric_limits<T>::min(),
                                      std::numeric_limits<T>::max());
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       switch (FuzzingTraits::Random(2)) {
         case 0:
           // Prevent underflow
           if (*v != std::numeric_limits<T>::min()) {
             (*v)--;
             break;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case 1:
           // Prevent overflow
           if (*v != std::numeric_limits<T>::max()) {
             (*v)++;
             break;
           }
       }
   }
@@ -103,41 +103,41 @@ void FuzzFloatingPointType(T* v, bool la
   static_assert(mozilla::IsFloatingPoint<T>::value == true,
                 "T must be a floating point type");
   switch (FuzzingTraits::Random(6)) {
     case 0:
       if (largeValues) {
         (*v) = RandomNumericLimit<T>();
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 1:
       if (largeValues) {
         (*v) = RandomFloatingPointRange<T>(std::numeric_limits<T>::min(),
                                            std::numeric_limits<T>::max());
         break;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       (*v) = RandomFloatingPoint<T>();
   }
 }
 
 /**
  * FuzzStringType mutates an incercepted string type of a pickled message.
  */
 template <typename T>
 void FuzzStringType(T& v, const T& literal1, const T& literal2) {
   switch (FuzzingTraits::Random(5)) {
     case 4:
       v = v + v;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 3:
       v = v + v;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 2:
       v = v + v;
       break;
     case 1:
       v += literal1;
       break;
     case 0:
       v = literal2;
--- a/tools/power/rapl.cpp
+++ b/tools/power/rapl.cpp
@@ -47,35 +47,16 @@
 #include <algorithm>
 #include <numeric>
 #include <vector>
 
 //---------------------------------------------------------------------------
 // Utilities
 //---------------------------------------------------------------------------
 
-// MOZ_FALLTHROUGH is an annotation to suppress compiler warnings about switch
-// cases that fall through without a break or return statement. MOZ_FALLTHROUGH
-// is only needed on cases that have code. This definition of MOZ_FALLTHROUGH
-// is identical to the one in mfbt/Attributes.h, which we don't use here because
-// this file avoids depending on Mozilla headers.
-#if defined(__clang__) && __cplusplus >= 201103L
-/* clang's fallthrough annotations are only available starting in C++11. */
-#  define MOZ_FALLTHROUGH [[clang::fallthrough]]
-#elif defined(_MSC_VER)
-/*
- * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
- * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
- */
-#  include <sal.h>
-#  define MOZ_FALLTHROUGH __fallthrough
-#else
-#  define MOZ_FALLTHROUGH /* FALLTHROUGH */
-#endif
-
 // The value of argv[0] passed to main(). Used in error messages.
 static const char* gArgv0;
 
 static void Abort(const char* aFormat, ...) {
   va_list vargs;
   va_start(vargs, aFormat);
   fprintf(stderr, "%s: ", gArgv0);
   vfprintf(stderr, aFormat, vargs);
@@ -327,17 +308,17 @@ class RAPL {
       case 58:  // 0x3a: Ivy Bridge
         // Supports package, cores, GPU.
         mIsGpuSupported = true;
         mIsRamSupported = false;
         break;
 
       case 63:  // 0x3f: Haswell-Server
         mHasRamUnitsQuirk = true;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case 45:  // 0x2d: Sandy Bridge-EP
       case 62:  // 0x3e: Ivy Bridge-E
         // Supports package, cores, RAM.
         mIsGpuSupported = false;
         mIsRamSupported = true;
         break;
 
       default:
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1768,17 +1768,17 @@ void nsExternalAppHandler::SendStatusCha
 #if defined(ANDROID)
       else if (type == kWriteError) {
         // On Android this means the SD card is missing (not in
         // SD slot).
         msgId = "SDAccessErrorCardMissing";
         break;
       }
 #endif
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     default:
       // Generic read/write/launch error message.
       switch (type) {
         case kReadError:
           msgId = "readError";
           break;
         case kWriteError:
--- a/widget/GfxDriverInfo.cpp
+++ b/widget/GfxDriverInfo.cpp
@@ -164,17 +164,17 @@ const GfxDeviceFamily* GfxDriverInfo::Ge
     case IntelHDGraphicsToIvyBridge:
       APPEND_DEVICE(0x015A); /* IntelIvyBridge_GT1_1 (HD Graphics) */
       // clang-format off
       APPEND_DEVICE(0x0152); /* IntelIvyBridge_GT1_2 (HD Graphics 2500, desktop) */
       APPEND_DEVICE(0x0162); /* IntelIvyBridge_GT2_1 (HD Graphics 4000, desktop) */
       APPEND_DEVICE(0x0166); /* IntelIvyBridge_GT2_2 (HD Graphics 4000, mobile) */
       APPEND_DEVICE(0x016A); /* IntelIvyBridge_GT2_3 (HD Graphics P4000, workstation) */
       // clang-format on
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case IntelHDGraphicsToSandyBridge:
       APPEND_DEVICE(0x0042); /* IntelHDGraphics */
       APPEND_DEVICE(0x0046); /* IntelMobileHDGraphics */
       APPEND_DEVICE(0x0102); /* IntelSandyBridge_1 */
       APPEND_DEVICE(0x0106); /* IntelSandyBridge_2 */
       APPEND_DEVICE(0x0112); /* IntelSandyBridge_3 */
       APPEND_DEVICE(0x0116); /* IntelSandyBridge_4 */
       APPEND_DEVICE(0x0122); /* IntelSandyBridge_5 */
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -1090,17 +1090,17 @@ void GfxInfoBase::EvaluateDownloadedBlac
           break;
 
         case nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION:
           if (!suggestedVersion.IsEmpty()) {
             SetPrefValueForDriverVersion(suggestedVersion);
           } else {
             RemovePrefForDriverVersion();
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         case nsIGfxInfo::FEATURE_BLOCKED_MISMATCHED_VERSION:
         case nsIGfxInfo::FEATURE_BLOCKED_DEVICE:
         case nsIGfxInfo::FEATURE_DISCOURAGED:
         case nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION:
           SetPrefValueForFeature(features[i], status, failureId);
           break;
       }
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -473,17 +473,17 @@ bool WidgetEvent::IsTargetedAtFocusedCon
 }
 
 bool WidgetEvent::IsAllowedToDispatchDOMEvent() const {
   switch (mClass) {
     case eMouseEventClass:
       if (mMessage == eMouseTouchDrag) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ePointerEventClass:
       // We want synthesized mouse moves to cause mouseover and mouseout
       // DOM events (EventStateManager::PreHandleEvent), but not mousemove
       // DOM events.
       // Synthesized button up events also do not cause DOM events because they
       // do not have a reliable mRefPoint.
       return AsMouseEvent()->mReason == WidgetMouseEvent::eReal;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1556,17 +1556,17 @@ InputContext nsChildView::GetInputContex
     case IMEState::ENABLED:
     case IMEState::PLUGIN:
       if (mTextInputHandler) {
         mInputContext.mIMEState.mOpen =
             mTextInputHandler->IsIMEOpened() ? IMEState::OPEN : IMEState::CLOSED;
         break;
       }
       // If mTextInputHandler is null, set CLOSED instead...
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default:
       mInputContext.mIMEState.mOpen = IMEState::CLOSED;
       break;
   }
   return mInputContext;
 }
 
 TextEventDispatcherListener* nsChildView::GetNativeTextEventDispatcherListener() {
--- a/widget/cocoa/nsLookAndFeel.mm
+++ b/widget/cocoa/nsLookAndFeel.mm
@@ -246,17 +246,17 @@ nsresult nsLookAndFeel::NativeGetColor(C
       //
     case ColorID::MozMacButtonactivetext:
     case ColorID::MozMacDefaultbuttontext:
       if (mHasColorButtonText) {
         aColor = mColorButtonText;
         break;
       }
       // Otherwise fall through and return the regular button text:
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case ColorID::Buttontext:
     case ColorID::MozButtonhovertext:
       aColor = mColorButtonHoverText;
       break;
     case ColorID::Captiontext:
     case ColorID::Menutext:
     case ColorID::Infotext:
     case ColorID::MozMenubartext:
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -4062,17 +4062,17 @@ bool nsNativeThemeCocoa::ThemeSupportsWi
     // Combobox dropdowns don't support native theming in vertical mode.
     case StyleAppearance::Menulist:
     case StyleAppearance::MenulistButton:
     case StyleAppearance::MozMenulistButton:
     case StyleAppearance::MenulistText:
       if (aFrame && aFrame->GetWritingMode().IsVertical()) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case StyleAppearance::Listbox:
 
     case StyleAppearance::Dialog:
     case StyleAppearance::Window:
     case StyleAppearance::MozWindowButtonBox:
     case StyleAppearance::MozWindowTitlebar:
     case StyleAppearance::Checkmenuitem:
--- a/widget/gtk/nsNativeThemeGTK.cpp
+++ b/widget/gtk/nsNativeThemeGTK.cpp
@@ -1360,17 +1360,17 @@ LayoutDeviceIntMargin nsNativeThemeGTK::
     } break;
     case StyleAppearance::Menuitem:
     case StyleAppearance::Checkmenuitem:
     case StyleAppearance::Radiomenuitem:
       // For regular menuitems, we will be using GetWidgetPadding instead of
       // GetWidgetBorder to pad up the widget's internals; other menuitems
       // will need to fall through and use the default case as before.
       if (IsRegularMenuItem(aFrame)) break;
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     default: {
       GetCachedWidgetBorder(aFrame, aAppearance, direction, &result);
     }
   }
 
   gint scale = GetMonitorScaleFactor(aFrame);
   result.top *= scale;
   result.right *= scale;
@@ -1826,17 +1826,17 @@ nsNativeThemeGTK::ThemeSupportsWidget(ns
 
   switch (aAppearance) {
     // Combobox dropdowns don't support native theming in vertical mode.
     case StyleAppearance::Menulist:
     case StyleAppearance::MenulistText:
       if (aFrame && aFrame->GetWritingMode().IsVertical()) {
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case StyleAppearance::Button:
     case StyleAppearance::ButtonFocus:
     case StyleAppearance::Radio:
     case StyleAppearance::Checkbox:
     case StyleAppearance::Toolbox:  // N/A
     case StyleAppearance::Toolbar:
     case StyleAppearance::Toolbarbutton:
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -2029,17 +2029,17 @@ nsEventStatus NativeKey::InitKeyEvent(Wi
       // If it was followed by a char message but it was consumed by somebody,
       // we should mark it as consumed because somebody must have handled it
       // and we should prevent to do "double action" for the key operation.
       // However, for compatibility with older version and other browsers,
       // we should dispatch the events even in the web content.
       if (mCharMessageHasGone) {
         aKeyEvent.PreventDefaultBeforeDispatch(CrossProcessForwarding::eAllow);
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case eKeyDownOnPlugin:
       aKeyEvent.mKeyCode = mDOMKeyCode;
       // Unique id for this keydown event and its associated keypress.
       sUniqueKeyEventId++;
       aKeyEvent.mUniqueId = sUniqueKeyEventId;
       break;
     case eKeyUp:
     case eKeyUpOnPlugin:
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -4811,17 +4811,17 @@ bool TSFTextStore::MaybeHackNoErrorLayou
       }
       // If we'll create native caret where we paint our caret.  Then, ATOK
       // will refer native caret.  So, we don't need to hack anything in
       // this case.
       if (TSFPrefs::NeedToCreateNativeCaretForLegacyATOK()) {
         MOZ_ASSERT(TSFStaticSink::IsATOKReferringNativeCaretActive());
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case TextInputProcessorID::eATOK2016:
     case TextInputProcessorID::eATOKUnknown:
       if (!TSFPrefs::DoNotReturnNoLayoutErrorToATOKOfCompositionString()) {
         return false;
       }
       // If the range is in the composition string, we should return rectangle
       // in it as far as possible.
       if (aACPStart < mContentForTSF.LatestCompositionStartOffset() ||
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3397,17 +3397,17 @@ void* nsWindow::GetNativeData(uint32_t a
     case NS_NATIVE_GRAPHIC:
       MOZ_ASSERT_UNREACHABLE("Not supported on Windows:");
       return nullptr;
     case NS_RAW_NATIVE_IME_CONTEXT: {
       void* pseudoIMEContext = GetPseudoIMEContext();
       if (pseudoIMEContext) {
         return pseudoIMEContext;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     }
     case NS_NATIVE_TSF_THREAD_MGR:
     case NS_NATIVE_TSF_CATEGORY_MGR:
     case NS_NATIVE_TSF_DISPLAY_ATTR_MGR:
       return IMEHandler::GetNativeData(this, aDataType);
 
     default:
       break;
@@ -7891,17 +7891,17 @@ bool nsWindow::DealWithPopups(HWND aWnd,
   UINT nativeMessage = WinUtils::GetNativeMessage(aMessage);
   switch (nativeMessage) {
     case WM_TOUCH:
       if (!IsTouchSupportEnabled(aWnd)) {
         // If APZ is disabled, don't allow touch inputs to dismiss popups. The
         // compatibility mouse events will do it instead.
         return false;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case WM_LBUTTONDOWN:
     case WM_RBUTTONDOWN:
     case WM_MBUTTONDOWN:
     case WM_NCLBUTTONDOWN:
     case WM_NCRBUTTONDOWN:
     case WM_NCMBUTTONDOWN:
       if (nativeMessage != WM_TOUCH && IsTouchSupportEnabled(aWnd) &&
           MOUSE_INPUT_SOURCE() == MouseEvent_Binding::MOZ_SOURCE_TOUCH) {
--- a/xpcom/base/MemoryInfo.cpp
+++ b/xpcom/base/MemoryInfo.cpp
@@ -55,33 +55,33 @@ MemoryInfo MemoryInfo::Get(const void* a
         result.mType += PageType::Private;
       }
 
       // The first 8 bits of AllocationProtect are an enum. The remaining bits
       // are flags.
       switch (basicInfo.AllocationProtect & 0xff) {
         case PAGE_EXECUTE_WRITECOPY:
           result.mPerms += Perm::CopyOnWrite;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case PAGE_EXECUTE_READWRITE:
           result.mPerms += Perm::Write;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case PAGE_EXECUTE_READ:
           result.mPerms += Perm::Read;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case PAGE_EXECUTE:
           result.mPerms += Perm::Execute;
           break;
 
         case PAGE_WRITECOPY:
           result.mPerms += Perm::CopyOnWrite;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case PAGE_READWRITE:
           result.mPerms += Perm::Write;
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
         case PAGE_READONLY:
           result.mPerms += Perm::Read;
           break;
 
         default:
           break;
       }
 
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -419,17 +419,17 @@ NS_DebugBreak(uint32_t aSeverity, const 
 
     case NS_ASSERT_STACK:
       nsTraceRefcnt::WalkTheStack(stderr);
       return;
 
     case NS_ASSERT_STACK_AND_ABORT:
       nsTraceRefcnt::WalkTheStack(stderr);
       // Fall through to abort
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case NS_ASSERT_ABORT:
       Abort(buf.buffer);
       return;
 
     case NS_ASSERT_TRAP:
     case NS_ASSERT_UNINITIALIZED:  // Default to "trap" behavior
       Break(buf.buffer);
--- a/xpcom/ds/nsCheapSets.h
+++ b/xpcom/ds/nsCheapSets.h
@@ -116,17 +116,17 @@ void nsCheapSet<EntryType>::Put(const Ke
     case ONE: {
       nsTHashtable<EntryType>* table = new nsTHashtable<EntryType>();
       EntryType* entry = GetSingleEntry();
       table->PutEntry(entry->GetKey());
       entry->~EntryType();
       mUnion.table = table;
       mState = MANY;
     }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case MANY:
       mUnion.table->PutEntry(aVal);
       return;
     default:
       MOZ_ASSERT_UNREACHABLE("bogus state");
       return;
   }
--- a/xpcom/ds/nsPersistentProperties.cpp
+++ b/xpcom/ds/nsPersistentProperties.cpp
@@ -176,17 +176,17 @@ bool nsPropertiesParser::ParseValueChara
             // Now there is nothing to append to the mValue since we are
             // skipping whitespaces at the beginning of the new line of the
             // multiline property. Set aTokenStart properly to ensure that
             // nothing is appended if we find regular line-end or the end of the
             // buffer.
             aTokenStart = aCur + 1;
             break;
           }
-          MOZ_FALLTHROUGH;
+          [[fallthrough]];
 
         case '\r':
           // we're done! We have a key and value
           mValue += Substring(aTokenStart, aCur);
           FinishValueState(aOldValue);
           mHaveMultiLine = false;
           break;
 
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -326,17 +326,17 @@ static nsresult CloneArray(uint16_t aInT
     case nsIDataType::VTYPE_WCHAR:
       memcpy(*aOutValue, aInValue, allocSize);
       break;
 
     case nsIDataType::VTYPE_INTERFACE_IS:
       if (aOutIID) {
         *aOutIID = *aInIID;
       }
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
     case nsIDataType::VTYPE_INTERFACE: {
       memcpy(*aOutValue, aInValue, allocSize);
 
       nsISupports** p = (nsISupports**)*aOutValue;
       for (i = aInCount; i > 0; ++p, --i)
         if (*p) {
           (*p)->AddRef();
@@ -683,17 +683,17 @@ nsresult nsDiscriminatedUnion::ToString(
     case nsIDataType::VTYPE_UTF8STRING:
     case nsIDataType::VTYPE_CSTRING:
     case nsIDataType::VTYPE_CHAR_STR:
     case nsIDataType::VTYPE_WCHAR_STR:
     case nsIDataType::VTYPE_STRING_SIZE_IS:
     case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     case nsIDataType::VTYPE_WCHAR:
       NS_ERROR("ToString being called for a string type - screwy logic!");
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
 
       // XXX We might want stringified versions of these... ???
 
     case nsIDataType::VTYPE_VOID:
     case nsIDataType::VTYPE_EMPTY:
       aOutString.SetIsVoid(true);
       return NS_OK;
 
--- a/xpcom/io/nsWildCard.cpp
+++ b/xpcom/io/nsWildCard.cpp
@@ -65,17 +65,17 @@ static int _valid_subexp(const T* aExpr,
         }
         if (!aExpr[x + 1]) { /* exclusion cannot be last character */
           return INVALID_SXP;
         }
         if (!x) { /* exclusion cannot be first character */
           return INVALID_SXP;
         }
         ++tld;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       case '*':
       case '?':
       case '$':
         ++nsc;
         break;
       case '[':
         ++nsc;
         if ((!aExpr[++x]) || (aExpr[x] == ']')) {
@@ -356,17 +356,17 @@ static int _shexp_match(const T* aStr, c
       case '?':
         break;
       case ')':
       case ']':
       case '|':
         return ABORTED;
       case '\\':
         ++y;
-        MOZ_FALLTHROUGH;
+        [[fallthrough]];
       default:
         if (aCaseInsensitive) {
           if (::upper(aStr[x]) != ::upper(aExpr[y])) {
             return NOMATCH;
           }
         } else {
           if (aStr[x] != aExpr[y]) {
             return NOMATCH;
--- a/xpcom/string/nsTextFormatter.cpp
+++ b/xpcom/string/nsTextFormatter.cpp
@@ -254,24 +254,24 @@ int nsTextFormatter::cvt_f(SprintfStateS
 
   switch (aType) {
     case 'f':
       numdigits = aPrec;
       mode = 3;
       break;
     case 'E':
       exp = 'E';
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 'e':
       numdigits = aPrec + 1;
       mode = 2;
       break;
     case 'G':
       exp = 'E';
-      MOZ_FALLTHROUGH;
+      [[fallthrough]];
     case 'g':
       if (aPrec == 0) {
         aPrec = 1;
       }
       numdigits = aPrec;
       mode = 2;
       break;
     default: