[clang] [clang][analyzer] Improved PointerSubChecker (PR #93676)

Balázs Kéri via cfe-commits cfe-commits at lists.llvm.org
Thu May 30 02:54:31 PDT 2024


================
@@ -44,24 +44,30 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
 
   const MemRegion *LR = LV.getAsRegion();
   const MemRegion *RR = RV.getAsRegion();
-
-  if (!(LR && RR))
-    return;
-
-  const MemRegion *BaseLR = LR->getBaseRegion();
-  const MemRegion *BaseRR = RR->getBaseRegion();
-
-  if (BaseLR == BaseRR)
+  if (!LR || !RR)
     return;
 
-  // Allow arithmetic on different symbolic regions.
-  if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR))
-    return;
+  const auto *ElemLR = dyn_cast<ElementRegion>(LR);
+  const auto *ElemRR = dyn_cast<ElementRegion>(RR);
+  // FIXME: We want to verify that these are elements of an array.
+  // Because behavior of ElementRegion it may be confused with a cast.
+  // There is not a simple way to distinguish it from array element (check the
+  // types?). Because this missing check a warning is missing in the rare case
+  // when two casted pointers to the same region (variable) are subtracted.
----------------
balazske wrote:

For me it is not clear what rules to apply.
```c
int a[3][3];
int *b = a;
int d = &(a[2][2]) - &(b[3]);
```
```c
long long l;
char *a = &l;
short *b = &l;
int d = &a[3] - (char *)&l;
d = (char *)&b[1] - &a[1];
```
```c
int a[3][3];
int d = &a[2][2] - &a[1][1];
```
I only found that the operands must point into the same "array object" but not what exactly an "array object" is. Are the sub-arrays of a multidimensional array separate "array objects"? If an address (of a variable) is converted to a `char *` is this the same array object as the original variable (for example `l`)? Invalid indexing like `int a[3][3]; int x = a[0][4];` is undefined behavior, but why should then be allowed to use pointers to such an object and index it like an one-dimensional array, or convert an array pointer into an array with different type and index it? 

We should allow anything that points into the same memory block (that is a variable or any array), or only allow pointers to the same array with same type and same size.

https://github.com/llvm/llvm-project/pull/93676


More information about the cfe-commits mailing list