From f74f568b29885c3fa63c44e33f91f3bb7281138e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= Date: Fri, 11 Oct 2024 11:58:14 +0200 Subject: [PATCH] [clang][analyzer] PointerSubChecker should not warn on pointers converted to numerical type (#111846) Pointer values casted to integer (non-pointer) type should be able to be subtracted as usual. --- .../StaticAnalyzer/Checkers/PointerSubChecker.cpp | 4 ++++ clang/test/Analysis/pointer-sub.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index f0dc5efd75f7d6..7a85d9e2073068 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -61,6 +61,10 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B, if (LR->getSymbolicBase() || RR->getSymbolicBase()) return; + if (!B->getLHS()->getType()->isPointerType() || + !B->getRHS()->getType()->isPointerType()) + return; + const auto *ElemLR = dyn_cast(LR); const auto *ElemRR = dyn_cast(RR); diff --git a/clang/test/Analysis/pointer-sub.c b/clang/test/Analysis/pointer-sub.c index 1c9d676ebb8f24..25fb7f043d468c 100644 --- a/clang/test/Analysis/pointer-sub.c +++ b/clang/test/Analysis/pointer-sub.c @@ -1,5 +1,7 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=security.PointerSub -analyzer-output=text-minimal -verify %s +typedef int * Ptr; + void f1(void) { int x, y, z[10]; int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}} @@ -10,6 +12,12 @@ void f1(void) { d = &x - (&x + 1); // no-warning d = (&x + 0) - &x; // no-warning d = (z + 10) - z; // no-warning + d = (long long)&y - (long long)&x; // no-warning + long long l = 1; + d = l - (long long)&y; // no-warning + Ptr p1 = &x; + Ptr p2 = &y; + d = p1 - p2; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}} } void f2(void) { @@ -28,6 +36,10 @@ void f2(void) { d = (int *)((char *)(&a[4]) + sizeof(int)) - &a[4]; // no-warning (pointers into the same array data) d = (int *)((char *)(&a[4]) + 1) - &a[4]; // expected-warning{{Subtraction of two pointers that}} + + long long a1 = (long long)&a[1]; + long long b1 = (long long)&b[1]; + d = a1 - b1; } void f3(void) {