Szelethus created this revision.
Szelethus added reviewers: george.karpenkov, NoQ, xazax.hun, rnkovacs.
Herald added subscribers: cfe-commits, mikhail.ramalho, a.sidorin, szepet, 
whisperity.

Now that it has it's own file, it makes little sense for 
`isPointerOrReferenceUninit` to be this large, so I moved dereferencing to a 
separate function.

Note that this is part 6, but only relies on https://reviews.llvm.org/D50504, 
not part https://reviews.llvm.org/D50508.


Repository:
  rC Clang

https://reviews.llvm.org/D50509

Files:
  lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp

Index: lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp
+++ lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp
@@ -69,6 +69,14 @@
 /// known, and thus FD can not be analyzed.
 static bool isVoidPointer(QualType T);
 
+/// Dereferences V, and stores the dereferences value in it, the dynamic type
+/// of V in DynT, and whether it needs to be casted back in NeedsCastBack.
+///
+/// V must be loc::MemRegionVal.
+///
+/// If for whatever reason dereferencing fails, returns with false.
+static bool dereference(ProgramStateRef State, SVal &V, QualType &DynT);
+
 //===----------------------------------------------------------------------===//
 //                   Methods for FindUninitializedFields.
 //===----------------------------------------------------------------------===//
@@ -101,61 +109,19 @@
 
   assert(V.getAs<loc::MemRegionVal>() &&
          "At this point V must be loc::MemRegionVal!");
-  auto L = V.castAs<loc::MemRegionVal>();
-
-  // We can't reason about symbolic regions, assume its initialized.
-  // Note that this also avoids a potential infinite recursion, because
-  // constructors for list-like classes are checked without being called, and
-  // the Static Analyzer will construct a symbolic region for Node *next; or
-  // similar code snippets.
-  if (L.getRegion()->getSymbolicBase()) {
-    IsAnyFieldInitialized = true;
-    return false;
-  }
-
-  DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, L.getRegion());
-  if (!DynTInfo.isValid()) {
-    IsAnyFieldInitialized = true;
-    return false;
-  }
-
-  QualType DynT = DynTInfo.getType();
 
-  if (isVoidPointer(DynT)) {
-    IsAnyFieldInitialized = true;
-    return false;
-  }
+  QualType DynT;
 
   // At this point the pointer itself is initialized and points to a valid
   // location, we'll now check the pointee.
-  SVal DerefdV = State->getSVal(V.castAs<Loc>(), DynT);
-
-  // If DerefdV is still a pointer value, we'll dereference it again (e.g.:
-  // int** -> int*).
-  while (auto Tmp = DerefdV.getAs<loc::MemRegionVal>()) {
-    if (Tmp->getRegion()->getSymbolicBase()) {
-      IsAnyFieldInitialized = true;
-      return false;
-    }
-
-    DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion());
-    if (!DynTInfo.isValid()) {
-      IsAnyFieldInitialized = true;
-      return false;
-    }
-
-    DynT = DynTInfo.getType();
-    if (isVoidPointer(DynT)) {
-      IsAnyFieldInitialized = true;
-      return false;
-    }
-
-    DerefdV = State->getSVal(*Tmp, DynT);
+  if (!dereference(State, V, DynT)) {
+    IsAnyFieldInitialized = true;
+    return false;
   }
 
   // If FR is a pointer pointing to a non-primitive type.
   if (Optional<nonloc::LazyCompoundVal> RecordV =
-          DerefdV.getAs<nonloc::LazyCompoundVal>()) {
+          V.getAs<nonloc::LazyCompoundVal>()) {
 
     const TypedValueRegion *R = RecordV->getRegion();
 
@@ -184,7 +150,7 @@
          "At this point FR must either have a primitive dynamic type, or it "
          "must be a null, undefined, unknown or concrete pointer!");
 
-  if (isPrimitiveUninit(DerefdV))
+  if (isPrimitiveUninit(V))
     return addFieldToUninits(LocalChain.add(LocField(FR)));
 
   IsAnyFieldInitialized = true;
@@ -203,3 +169,32 @@
   }
   return false;
 }
+
+static bool dereference(ProgramStateRef State, SVal &V, QualType &DynT) {
+  // If V is multiple pointer value, we'll dereference it again (e.g.: int** ->
+  // int*).
+  while (auto Tmp = V.getAs<loc::MemRegionVal>()) {
+    // We can't reason about symbolic regions, assume its initialized.
+    // Note that this also avoids a potential infinite recursion, because
+    // constructors for list-like classes are checked without being called, and
+    // the Static Analyzer will construct a symbolic region for Node *next; or
+    // similar code snippets.
+    if (Tmp->getRegion()->getSymbolicBase()) {
+      return false;
+    }
+
+    DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion());
+    if (!DynTInfo.isValid()) {
+      return false;
+    }
+
+    DynT = DynTInfo.getType();
+
+    if (isVoidPointer(DynT)) {
+      return false;
+    }
+
+    V = State->getSVal(*Tmp, DynT);
+  }
+  return true;
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to