vabridgers created this revision.
vabridgers added reviewers: steakhal, martong.
Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, 
whisperity.
vabridgers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This simple change addresses a special case of structure/pointer
aliasing that produced different symbvals, leading to false positives
during analysis.

The reproducer is as simple as this.
struct s {

  int v;
  char y;

};

void foo(struct s *ps) {

  struct s ss = *ps;
  clang_analyzer_dump(ss.v); // reg_$1<int Element{SymRegion{reg_$0<struct s 
*ps>},0 S64b,struct s}.v>
  clang_analyzer_dump(ps->v);  //reg_$3<int SymRegion{reg_$0<struct s *ps>}.v>
  clang_analyzer_eval(ss.v == ps->v); // UNKNOWN

}

Acks: Many thanks to @steakhal and @martong for the group debug session.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110625

Files:
  clang/lib/StaticAnalyzer/Core/Store.cpp
  clang/test/Analysis/ptr-arith.c


Index: clang/test/Analysis/ptr-arith.c
===================================================================
--- clang/test/Analysis/ptr-arith.c
+++ clang/test/Analysis/ptr-arith.c
@@ -330,3 +330,17 @@
   simd_float2 x = {0, 1};
   return x[1]; // no-warning
 }
+
+struct s {
+  int v;
+  char y;
+};
+
+// These three expressions should produce the same sym vals.
+// TBD: add test verification here.
+void foo(struct s *ps) {
+  struct s ss = *ps;
+  clang_analyzer_dump((*ps).v); // reg_$1<int SymRegion{reg_$0<struct s * 
ps>}.v>
+  clang_analyzer_dump(ps[0].v); // reg_$1<int SymRegion{reg_$0<struct s * 
ps>}.v>
+  clang_analyzer_dump(ps->v);   // reg_$1<int SymRegion{reg_$0<struct s * 
ps>}.v>
+}
Index: clang/lib/StaticAnalyzer/Core/Store.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/Store.cpp
+++ clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -442,6 +442,15 @@
 
 SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
                                     SVal Base) {
+
+  // Special case, if index is 0, return the same type as if
+  // this was not an array dereference.
+  if (Offset.isZeroConstant()) {
+    QualType BT = Base.getType(this->Ctx);
+    if (!BT.isNull() && BT->getPointeeType() == elementType)
+      return Base;
+  }
+
   // If the base is an unknown or undefined value, just return it back.
   // FIXME: For absolute pointer addresses, we just return that value back as
   //  well, although in reality we should return the offset added to that


Index: clang/test/Analysis/ptr-arith.c
===================================================================
--- clang/test/Analysis/ptr-arith.c
+++ clang/test/Analysis/ptr-arith.c
@@ -330,3 +330,17 @@
   simd_float2 x = {0, 1};
   return x[1]; // no-warning
 }
+
+struct s {
+  int v;
+  char y;
+};
+
+// These three expressions should produce the same sym vals.
+// TBD: add test verification here.
+void foo(struct s *ps) {
+  struct s ss = *ps;
+  clang_analyzer_dump((*ps).v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v>
+  clang_analyzer_dump(ps[0].v); // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v>
+  clang_analyzer_dump(ps->v);   // reg_$1<int SymRegion{reg_$0<struct s * ps>}.v>
+}
Index: clang/lib/StaticAnalyzer/Core/Store.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/Store.cpp
+++ clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -442,6 +442,15 @@
 
 SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
                                     SVal Base) {
+
+  // Special case, if index is 0, return the same type as if
+  // this was not an array dereference.
+  if (Offset.isZeroConstant()) {
+    QualType BT = Base.getType(this->Ctx);
+    if (!BT.isNull() && BT->getPointeeType() == elementType)
+      return Base;
+  }
+
   // If the base is an unknown or undefined value, just return it back.
   // FIXME: For absolute pointer addresses, we just return that value back as
   //  well, although in reality we should return the offset added to that
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to