Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -95,6 +95,26 @@ if (B->getOpcode() == BO_PtrMemD) state = createTemporaryRegionIfNeeded(state, LCtx, LHS); + // If we have a bitwise operation (e.g. checking low-bits) of a pointer + // we would like to escape that pointer as we do not model this operation. + if (B->isBitwiseOp()) { + bool IsLhsPtr = false, IsRhsPtr = false; + if (const MemRegion *LeftMR = LeftV.getAsRegion()) + IsLhsPtr = LeftMR->getSymbolicBase(); + if (const MemRegion *RightMR = RightV.getAsRegion()) + IsRhsPtr = RightMR->getSymbolicBase(); + + if (IsLhsPtr) + state = escapeValue(state, LeftV, PSK_EscapeOther); + if (IsRhsPtr) + state = escapeValue(state, RightV, PSK_EscapeOther); + + if (IsLhsPtr || IsRhsPtr) { + Bldr.generateNode(B, *it, state); + continue; + } + } + // Process non-assignments except commas or short-circuited // logical expressions (LAnd and LOr). SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); Index: clang/test/Analysis/symbol-escape.cpp =================================================================== --- clang/test/Analysis/symbol-escape.cpp +++ clang/test/Analysis/symbol-escape.cpp @@ -2,6 +2,8 @@ // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \ // RUN: -verify %s +// expected-no-diagnostics + #include class C {}; @@ -12,7 +14,8 @@ ~static_cast(0x1)) | (reinterpret_cast(Bar) & 0x1)); (void)Bar; - // expected-warning@-1 {{Potential leak of memory pointed to by 'Bar'}} + // no-warning: "Potential leak of memory pointed to by 'Bar'" was here because + // the pointers are got lost inside the bitwise operations. delete Bar; }