https://github.com/voyager-jhk updated https://github.com/llvm/llvm-project/pull/225048
>From 02be70874b6dfd389c9281d6ef38306748499f56 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 ++++++++ .../Analysis/identity-ops-on-LocAsInteger.c | 57 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 clang/test/Analysis/identity-ops-on-LocAsInteger.c diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index db710b64a6ae53..f0f1b7f65c35f7 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 7d154cbc840aca..c742de27e7aaa8 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/identity-ops-on-LocAsInteger.c b/clang/test/Analysis/identity-ops-on-LocAsInteger.c new file mode 100644 index 00000000000000..39f655724f329d --- /dev/null +++ b/clang/test/Analysis/identity-ops-on-LocAsInteger.c @@ -0,0 +1,57 @@ +// RUN: %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core,unix.Malloc,debug.ExprInspection + +// Identity operations on a LocAsInteger must preserve the original location. +// GH#220972. + +typedef unsigned __INTPTR_TYPE__ uintptr_t; +typedef __SIZE_TYPE__ size_t; + +void *malloc(size_t); +void free(void *); +void clang_analyzer_eval(int); + +void test_add_zero(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_other_identity_ops(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 +} + +void test_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 +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
