xbolva00 updated this revision to Diff 204253. xbolva00 added a comment. Warn in more cases. Added many new tests.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63139/new/ https://reviews.llvm.org/D63139 Files: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaStmt.cpp Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -861,6 +861,20 @@ typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy; CaseRangesTy CaseRanges; + if (CompoundStmt *CS = dyn_cast<CompoundStmt>(BodyStmt)) { + for (auto It = CS->body_begin(); It != CS->body_end(); ++It) { + auto *S = *It; + if (isa<LabelStmt>(S) || isa<CaseStmt>(S) || isa<DefaultStmt>(S)) + break; + Diag(S->getBeginLoc(), diag::warn_unreachable_stmt_in_switch); + } + } else if (isa<LabelStmt>(BodyStmt) || isa<CaseStmt>(BodyStmt) || + isa<DefaultStmt>(BodyStmt)) { + // No warning + } else { + Diag(BodyStmt->getBeginLoc(), diag::warn_unreachable_stmt_in_switch); + } + DefaultStmt *TheDefaultStmt = nullptr; bool CaseListIsErroneous = false; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8188,6 +8188,8 @@ def err_default_not_in_switch : Error< "'default' statement not in switch statement">; def err_case_not_in_switch : Error<"'case' statement not in switch statement">; +def warn_unreachable_stmt_in_switch : Warning< + "statement will be never executed">, InGroup<SwitchUnreachable>, DefaultIgnore; def warn_bool_switch_condition : Warning< "switch condition has boolean value">, InGroup<SwitchBool>; def warn_case_value_overflow : Warning< Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -538,6 +538,7 @@ def CoveredSwitchDefault : DiagGroup<"covered-switch-default">; def SwitchBool : DiagGroup<"switch-bool">; def SwitchEnum : DiagGroup<"switch-enum">; +def SwitchUnreachable : DiagGroup<"switch-unreachable">; def Switch : DiagGroup<"switch">; def EnumCompareSwitch : DiagGroup<"enum-compare-switch">; def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch]>; @@ -842,7 +843,7 @@ // Note that putting warnings in -Wall will not disable them by default. If a // warning should be active _only_ when -Wall is passed in, mark it as // DefaultIgnore in addition to putting it here. -def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>; +def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool, SwitchUnreachable]>; // Warnings that should be in clang-cl /w4. def : DiagGroup<"CL4", [All, Extra]>;
Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -861,6 +861,20 @@ typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy; CaseRangesTy CaseRanges; + if (CompoundStmt *CS = dyn_cast<CompoundStmt>(BodyStmt)) { + for (auto It = CS->body_begin(); It != CS->body_end(); ++It) { + auto *S = *It; + if (isa<LabelStmt>(S) || isa<CaseStmt>(S) || isa<DefaultStmt>(S)) + break; + Diag(S->getBeginLoc(), diag::warn_unreachable_stmt_in_switch); + } + } else if (isa<LabelStmt>(BodyStmt) || isa<CaseStmt>(BodyStmt) || + isa<DefaultStmt>(BodyStmt)) { + // No warning + } else { + Diag(BodyStmt->getBeginLoc(), diag::warn_unreachable_stmt_in_switch); + } + DefaultStmt *TheDefaultStmt = nullptr; bool CaseListIsErroneous = false; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8188,6 +8188,8 @@ def err_default_not_in_switch : Error< "'default' statement not in switch statement">; def err_case_not_in_switch : Error<"'case' statement not in switch statement">; +def warn_unreachable_stmt_in_switch : Warning< + "statement will be never executed">, InGroup<SwitchUnreachable>, DefaultIgnore; def warn_bool_switch_condition : Warning< "switch condition has boolean value">, InGroup<SwitchBool>; def warn_case_value_overflow : Warning< Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -538,6 +538,7 @@ def CoveredSwitchDefault : DiagGroup<"covered-switch-default">; def SwitchBool : DiagGroup<"switch-bool">; def SwitchEnum : DiagGroup<"switch-enum">; +def SwitchUnreachable : DiagGroup<"switch-unreachable">; def Switch : DiagGroup<"switch">; def EnumCompareSwitch : DiagGroup<"enum-compare-switch">; def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch]>; @@ -842,7 +843,7 @@ // Note that putting warnings in -Wall will not disable them by default. If a // warning should be active _only_ when -Wall is passed in, mark it as // DefaultIgnore in addition to putting it here. -def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>; +def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool, SwitchUnreachable]>; // Warnings that should be in clang-cl /w4. def : DiagGroup<"CL4", [All, Extra]>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits