xref: /llvm-project/clang-tools-extra/clang-tidy/bugprone/SwitchMissingDefaultCaseCheck.cpp (revision 42179bbf6bcc9f90256b443c30f5e99f862bc2f6)
1 //===--- SwitchMissingDefaultCaseCheck.cpp - clang-tidy -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SwitchMissingDefaultCaseCheck.h"
10 #include "clang/AST/ASTContext.h"
11 
12 using namespace clang::ast_matchers;
13 
14 namespace clang::tidy::bugprone {
15 
16 namespace {
17 
AST_MATCHER(SwitchStmt,hasDefaultCase)18 AST_MATCHER(SwitchStmt, hasDefaultCase) {
19   const SwitchCase *Case = Node.getSwitchCaseList();
20   while (Case) {
21     if (DefaultStmt::classof(Case))
22       return true;
23 
24     Case = Case->getNextSwitchCase();
25   }
26   return false;
27 }
28 } // namespace
29 
registerMatchers(MatchFinder * Finder)30 void SwitchMissingDefaultCaseCheck::registerMatchers(MatchFinder *Finder) {
31   Finder->addMatcher(
32       switchStmt(hasCondition(expr(unless(isInstantiationDependent()),
33                                    hasType(qualType(hasCanonicalType(
34                                        unless(hasDeclaration(enumDecl()))))))),
35                  unless(hasDefaultCase()))
36           .bind("switch"),
37       this);
38 }
39 
check(const ast_matchers::MatchFinder::MatchResult & Result)40 void SwitchMissingDefaultCaseCheck::check(
41     const ast_matchers::MatchFinder::MatchResult &Result) {
42   const auto *Switch = Result.Nodes.getNodeAs<SwitchStmt>("switch");
43 
44   diag(Switch->getSwitchLoc(), "switching on non-enum value without "
45                                "default case may not cover all cases");
46 }
47 } // namespace clang::tidy::bugprone
48