Author: T-Gruber
Date: 2025-03-31T08:44:28+02:00
New Revision: d63cc4c87689a79d25521c9aa2ce4a335e5984e3

URL: 
https://github.com/llvm/llvm-project/commit/d63cc4c87689a79d25521c9aa2ce4a335e5984e3
DIFF: 
https://github.com/llvm/llvm-project/commit/d63cc4c87689a79d25521c9aa2ce4a335e5984e3.diff

LOG: [analyzer] Unknown array lvalue element in Store (#133381)

Remove the early return for BaseRegions of type ElementRegion. Return
meaningful MemRegionVal for these cases as well.
Previous discussion:
https://discourse.llvm.org/t/lvalueelement-returns-unknownval-for-multi-dimensional-arrays/85476

Added: 
    clang/test/Analysis/lvalue_elements.c

Modified: 
    clang/lib/StaticAnalyzer/Core/Store.cpp
    clang/test/Analysis/ArrayBound/assumption-reporting.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/Store.cpp 
b/clang/lib/StaticAnalyzer/Core/Store.cpp
index 5f30fae4b7047..da6885ecd0ec5 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -511,13 +511,9 @@ SVal StoreManager::getLValueElement(QualType elementType, 
NonLoc Offset,
   // Only allow non-integer offsets if the base region has no offset itself.
   // FIXME: This is a somewhat arbitrary restriction. We should be using
   // SValBuilder here to add the two offsets without checking their types.
-  if (!isa<nonloc::ConcreteInt>(Offset)) {
-    if (isa<ElementRegion>(BaseRegion->StripCasts()))
-      return UnknownVal();
-
+  if (!isa<nonloc::ConcreteInt>(Offset))
     return loc::MemRegionVal(MRMgr.getElementRegion(
         elementType, Offset, cast<SubRegion>(ElemR->getSuperRegion()), Ctx));
-  }
 
   const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
   assert(BaseIdxI.isSigned());

diff  --git a/clang/test/Analysis/ArrayBound/assumption-reporting.c 
b/clang/test/Analysis/ArrayBound/assumption-reporting.c
index d687886ada1ae..535e623baa815 100644
--- a/clang/test/Analysis/ArrayBound/assumption-reporting.c
+++ b/clang/test/Analysis/ArrayBound/assumption-reporting.c
@@ -39,14 +39,9 @@ int assumingBothPointerToMiddle(int arg) {
   // will speak about the "byte offset" measured from the beginning of the 
TenElements.
   int *p = TenElements + 2;
   int a = p[arg];
-  // FIXME: The following note does not appear:
-  //  {{Assuming byte offset is non-negative and less than 40, the extent of 
'TenElements'}}
-  // It seems that the analyzer "gives up" modeling this pointer arithmetics
-  // and says that `p[arg]` is just an UnknownVal (instead of calculating that
-  // it's equivalent to `TenElements[2+arg]`).
+  // expected-note@-1 {{Assuming byte offset is non-negative and less than 40, 
the extent of 'TenElements'}}
 
   int b = TenElements[arg]; // This is normal access, and only the lower bound 
is new.
-  // expected-note@-1 {{Assuming index is non-negative}}
   int c = TenElements[arg + 10];
   // expected-warning@-1 {{Out of bound access to memory after the end of 
'TenElements'}}
   // expected-note@-2 {{Access of 'TenElements' at an overflowing index, while 
it holds only 10 'int' elements}}

diff  --git a/clang/test/Analysis/lvalue_elements.c 
b/clang/test/Analysis/lvalue_elements.c
new file mode 100644
index 0000000000000..73b9c037d80d2
--- /dev/null
+++ b/clang/test/Analysis/lvalue_elements.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=debug.ExprInspection 
-verify %s
+
+void clang_analyzer_dump(int*);
+
+const int const_index = 1;
+extern int unknown_index;
+extern int array[3];
+extern int matrix[3][3];
+
+int main(){
+
+    // expected-warning@+1 {{&Element{array,1 S64b,int}}}
+    clang_analyzer_dump(&array[const_index]);
+
+    // expected-warning@+1 {{&Element{array,reg_$1<int unknown_index>,int}}}
+    clang_analyzer_dump(&array[unknown_index]);
+    
+    // expected-warning@+1 {{&Element{Element{matrix,1 S64b,int[3]},1 
S64b,int}}}
+    clang_analyzer_dump(&matrix[const_index][const_index]);
+
+    // expected-warning@+1 {{&Element{Element{matrix,reg_$1<int 
unknown_index>,int[3]},1 S64b,int}}}
+    clang_analyzer_dump(&matrix[unknown_index][const_index]);
+
+    // expected-warning@+1 {{&Element{Element{matrix,1 S64b,int[3]},reg_$1<int 
unknown_index>,int}}}
+    clang_analyzer_dump(&matrix[const_index][unknown_index]);
+
+    // expected-warning@+1 {{&Element{Element{matrix,reg_$1<int 
unknown_index>,int[3]},reg_$1<int unknown_index>,int}}}
+    clang_analyzer_dump(&matrix[unknown_index][unknown_index]);
+
+    return 0;
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to