ariccio updated this revision to Diff 47289.

http://reviews.llvm.org/D16873

Files:
  llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp

Index: llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1180,6 +1180,17 @@
   ///  a specified VarDecl and LocationContext.
   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
 
+private:
+  /// Retrieve or create the memory region
+  ///  associated with a VarDecl for a global variable.
+  const MemRegion *getMemSpaceForGlobalVariable(const VarDecl *D);
+
+  /// Retrieve or create the memory region
+  ///  associated with a specified VarDecl and LocationContext.
+  const MemRegion *getMemSpaceForLocalVariable(const VarDecl *D,
+                                               const StackFrameContext *STC);
+
+public:
   /// getVarRegion - Retrieve or create the memory region associated with
   ///  a specified VarDecl and super region.
   const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
Index: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -766,34 +766,77 @@
   return (const StackFrameContext *)nullptr;
 }
 
+const MemRegion* MemRegionManager::getMemSpaceForGlobalVariable(const VarDecl *D) {
+  assert(D->hasGlobalStorage());
+  assert(!D->isStaticLocal());
+  // First handle the globals defined in system headers.
+  if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
+    // Whitelist the system globals which often DO GET modified, assume the
+    // rest are immutable.
+    if (D->getName().find("errno") != StringRef::npos)
+      return getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
+
+    return getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
+  }
+  // Treat other globals as GlobalInternal unless they are constants.
+  QualType GQT = D->getType();
+  const Type *GT = GQT.getTypePtrOrNull();
+  // TODO: We could walk the complex types here and see if everything is
+  // constified.
+  if (GT && GQT.isConstQualified() && GT->isArithmeticType())
+    return getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
+
+  return getGlobalsRegion();
+}
+
+const MemRegion*
+MemRegionManager::getMemSpaceForLocalVariable(const VarDecl *D,
+                                              const StackFrameContext *STC) {
+
+  if (!STC)
+    return getUnknownRegion();
+
+  if (D->hasLocalStorage()) {
+    return (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+           ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+           : static_cast<const MemRegion*>(getStackLocalsRegion(STC)));
+  }
+  assert(D->isStaticLocal());
+  const Decl *STCD = STC->getDecl();
+  if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
+    return getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
+                            getFunctionCodeRegion(cast<NamedDecl>(STCD)));
+
+  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
+    // FIXME: The fallback type here is totally bogus -- though it should
+    // never be queried, it will prevent uniquing with the real
+    // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
+    // signature.
+    QualType T;
+    if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
+      T = TSI->getType();
+    if (T.isNull())
+      T = getContext().VoidTy;
+    if (!T->getAs<FunctionType>())
+      T = getContext().getFunctionNoProtoType(T);
+    T = getContext().getBlockPointerType(T);
+
+    const BlockCodeRegion *BTR =
+      getBlockCodeRegion(BD, C.getCanonicalType(T),
+                         STC->getAnalysisDeclContext());
+    return getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
+                            BTR);
+  }
+  return getGlobalsRegion();
+}
+
 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
                                                 const LocationContext *LC) {
   const MemRegion *sReg = nullptr;
 
   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
+    sReg = getMemSpaceForGlobalVariable(D);
 
-    // First handle the globals defined in system headers.
-    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
-      // Whitelist the system globals which often DO GET modified, assume the
-      // rest are immutable.
-      if (D->getName().find("errno") != StringRef::npos)
-        sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
-      else
-        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-
-    // Treat other globals as GlobalInternal unless they are constants.
-    } else {
-      QualType GQT = D->getType();
-      const Type *GT = GQT.getTypePtrOrNull();
-      // TODO: We could walk the complex types here and see if everything is
-      // constified.
-      if (GT && GQT.isConstQualified() && GT->isArithmeticType())
-        sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-      else
-        sReg = getGlobalsRegion();
-    }
-
-  // Finally handle static locals.
   } else {
     // FIXME: Once we implement scope handling, we will need to properly lookup
     // 'D' to the proper LocationContext.
@@ -805,48 +848,8 @@
       return V.get<const VarRegion*>();
 
     const StackFrameContext *STC = V.get<const StackFrameContext*>();
-
-    if (!STC)
-      sReg = getUnknownRegion();
-    else {
-      if (D->hasLocalStorage()) {
-        sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
-               ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
-               : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
-      }
-      else {
-        assert(D->isStaticLocal());
-        const Decl *STCD = STC->getDecl();
-        if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
-          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
-                                  getFunctionCodeRegion(cast<NamedDecl>(STCD)));
-        else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
-          // FIXME: The fallback type here is totally bogus -- though it should
-          // never be queried, it will prevent uniquing with the real
-          // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
-          // signature.
-          QualType T;
-          if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
-            T = TSI->getType();
-          if (T.isNull())
-            T = getContext().VoidTy;
-          if (!T->getAs<FunctionType>())
-            T = getContext().getFunctionNoProtoType(T);
-          T = getContext().getBlockPointerType(T);
-
-          const BlockCodeRegion *BTR =
-            getBlockCodeRegion(BD, C.getCanonicalType(T),
-                               STC->getAnalysisDeclContext());
-          sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
-                                  BTR);
-        }
-        else {
-          sReg = getGlobalsRegion();
-        }
-      }
-    }
+    sReg = getMemSpaceForLocalVariable(D, STC);
   }
-
   return getSubRegion<VarRegion>(D, sReg);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to