diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index f8bbfed8bb387..8779ffab13b86 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -6057,6 +6057,7 @@ bool Compiler::visitSwitchStmt(const SwitchStmt *S) { DefaultLabel); if (!this->visitStmt(S->getBody())) return false; + this->fallthrough(EndLabel); this->emitLabel(EndLabel); return LS.destroyLocals(); @@ -6064,6 +6065,7 @@ bool Compiler::visitSwitchStmt(const SwitchStmt *S) { template bool Compiler::visitCaseStmt(const CaseStmt *S) { + this->fallthrough(CaseLabels[S]); this->emitLabel(CaseLabels[S]); return this->visitStmt(S->getSubStmt()); } diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index 5028ebfa3de30..c6d79f9c60058 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -1270,6 +1270,17 @@ namespace StmtExprs { namespace CrossFuncLabelDiff { constexpr long a(bool x) { return x ? 0 : (intptr_t)&&lbl + (0 && ({lbl: 0;})); } } + + /// GCC agrees with the bytecode interpreter here. + void switchInSE() { + static_assert(({ // ref-error {{not an integral constant expression}} + int i = 20; + switch(10) { + case 10: i = 300; // ref-note {{a constant expression cannot modify an object that is visible outside that expression}} + } + i; + }) == 300); + } } #endif