Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -3485,6 +3485,11 @@ static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; } bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); } + static bool isBitwiseOrShiftOp(Opcode Opc) { + return isBitwiseOp(Opc) || isShiftOp(Opc); + } + bool isBitwiseOrShiftOp() const { return isBitwiseOrShiftOp(getOpcode()); } + static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; } bool isRelationalOp() const { return isRelationalOp(getOpcode()); } Index: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def =================================================================== --- clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -300,6 +300,14 @@ "Whether to place an event at each tracked condition.", false) +ANALYZER_OPTION(bool, CheckBitwise, "check-bitwise", + "Whether the bitwise (and shift) operations should be checked.", + true) + +//===----------------------------------------------------------------------===// +// Unsinged analyzer options. +//===----------------------------------------------------------------------===// + ANALYZER_OPTION(unsigned, CTUImportThreshold, "ctu-import-threshold", "The maximal amount of translation units that is considered " "for import when inlining functions during CTU analysis. " @@ -308,10 +316,6 @@ "various translation units.", 100u) -//===----------------------------------------------------------------------===// -// Unsinged analyzer options. -//===----------------------------------------------------------------------===// - ANALYZER_OPTION( unsigned, AlwaysInlineSize, "ipa-always-inline-size", "The size of the functions (in basic blocks), which should be considered " Index: clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp @@ -60,6 +60,11 @@ CheckerContext &Ctx) const { SVal X = Ctx.getSVal(Condition); if (X.isUndef()) { + AnalyzerOptions &Opts = Ctx.getAnalysisManager().getAnalyzerOptions(); + if (const auto *BO = dyn_cast(Condition)) + if (BO->isBitwiseOrShiftOp() && !Opts.CheckBitwise) + Opts.SilencedCheckersAndPackages.push_back("core.uninitialized.Branch"); + // Generate a sink node, which implicitly marks both outgoing branches as // infeasible. ExplodedNode *N = Ctx.generateErrorNode(); Index: clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -75,6 +75,10 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, CheckerContext &C) const { if (C.getSVal(B).isUndef()) { + AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions(); + if (B->isBitwiseOrShiftOp() && !Opts.CheckBitwise) + Opts.SilencedCheckersAndPackages.push_back( + "core.UndefinedBinaryOperatorResult"); // Do not report assignments of uninitialized values inside swap functions. // This should allow to swap partially uninitialized structs Index: clang/test/Analysis/analyzer-config.c =================================================================== --- clang/test/Analysis/analyzer-config.c +++ clang/test/Analysis/analyzer-config.c @@ -25,6 +25,7 @@ // CHECK-NEXT: cfg-rich-constructors = true // CHECK-NEXT: cfg-scopes = false // CHECK-NEXT: cfg-temporary-dtors = true +// CHECK-NEXT: check-bitwise = true // CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals // CHECK-NEXT: crosscheck-with-z3 = false // CHECK-NEXT: ctu-dir = "" @@ -93,4 +94,4 @@ // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 90 +// CHECK-NEXT: num-entries = 91