https://github.com/voyager-jhk created https://github.com/llvm/llvm-project/pull/225048
Preserve LocAsInteger values through identity operations on integers converted from pointers. This fixes a false positive leak report from unix.Malloc. Fixes #220972 >From 303cef80ee1260ce34e4c56e3da9276183b3b698 Mon Sep 17 00:00:00 2001 From: voyager-jhk <[email protected]> Date: Mon, 21 Sep 2026 17:06:58 +0800 Subject: [PATCH] [analyzer] Preserve LocAsInteger through identity operations Preserve LocAsInteger values through identity operations on integers converted from pointers. This fixes a false positive leak report from unix.Malloc. Fixes #220972 --- clang/docs/ReleaseNotes.md | 3 ++ .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 24 ++++++++++ clang/test/Analysis/malloc.c | 47 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index db710b64a6ae5..f0f1b7f65c35f 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -871,6 +871,9 @@ features cannot lower the translation-unit ABI level; #### Crash and bug fixes +- Fixed a false positive `unix.Malloc` leak report for identity operations on + integers converted from pointers. + % comment: % This is for the Static Analyzer. % Use `####` headings for subsections: diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 7d154cbc840ac..c742de27e7aaa 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -230,6 +230,25 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, return makeNonLoc(LHS, op, *ConvertedRHS, resultTy); } +// Returns whether X op RHS is equivalent to X. +static bool isIdentityOperation(BinaryOperator::Opcode op, + const llvm::APSInt &RHS) { + switch (op) { + case BO_Add: + case BO_Sub: + case BO_Or: + case BO_Xor: + case BO_Shl: + case BO_Shr: + return RHS == 0; + case BO_Mul: + case BO_Div: + return RHS == 1; + default: + return false; + } +} + // See if Sym is known to be a relation Rel with Bound. static bool isInRelation(BinaryOperator::Opcode Rel, SymbolRef Sym, llvm::APSInt Bound, ProgramStateRef State) { @@ -491,6 +510,11 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, rhs.castAs<nonloc::LocAsInteger>().getLoc(), resultTy); case nonloc::ConcreteIntKind: { + // Preserve the location for identity operations. + if (isIdentityOperation(op, + rhs.castAs<nonloc::ConcreteInt>().getValue())) + return evalCast(lhs, resultTy, QualType{}); + // FIXME: at the moment the implementation // of modeling "pointers as integers" is not complete. if (!BinaryOperator::isComparisonOp(op)) diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 6c3dadfd16021..791946164b6d1 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -1327,6 +1327,53 @@ void test_double_assign_ints_positive(void) void *ptr = malloc(16); (void*)(intptr_t)(uintptr_t)ptr; // expected-warning {{unused}} } // expected-warning {{leak}} + +// Regression test for GH#220972. +void test_identity_op_on_int_cast_pointer(void) +{ + void *ptr = malloc(16); + if (ptr == 0) + return; + + uintptr_t value = (uintptr_t)ptr; + value += 0; + clang_analyzer_eval(value == (uintptr_t)ptr); // expected-warning{{TRUE}} + + free((void *)value); // no-warning +} + +void test_identity_ops_on_int_cast_pointer(void) +{ + void *ptr = malloc(16); + if (ptr == 0) + return; + + uintptr_t value = (uintptr_t)ptr; + value -= 0; + value |= 0; + value ^= 0; + value <<= 0; + value >>= 0; + value *= 1; + value /= 1; + clang_analyzer_eval(value == (uintptr_t)ptr); // expected-warning{{TRUE}} + + free((void *)value); // no-warning +} + +// Test identity operations with a narrower result type. +void test_identity_op_with_narrower_result(void) +{ + void *ptr = malloc(16); + if (ptr == 0) + return; + + unsigned value = (unsigned)(uintptr_t)ptr; + value += 0; + clang_analyzer_eval(value == (unsigned)(uintptr_t)ptr); // expected-warning{{TRUE}} + + free(ptr); // no-warning +} #endif void testCGContextNoLeak(void) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
