This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf4fc3f6ba319: [analyzer] Treat system globals as mutable if 
they are not const (authored by steakhal).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127306/new/

https://reviews.llvm.org/D127306

Files:
  clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/test/Analysis/Inputs/some_system_globals.h
  clang/test/Analysis/Inputs/some_user_globals.h
  clang/test/Analysis/globals-are-not-always-immutable.c

Index: clang/test/Analysis/globals-are-not-always-immutable.c
===================================================================
--- /dev/null
+++ clang/test/Analysis/globals-are-not-always-immutable.c
@@ -0,0 +1,71 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -analyzer-checker=core,debug.ExprInspection
+
+#include "Inputs/errno_var.h"
+#include "Inputs/some_system_globals.h"
+#include "Inputs/some_user_globals.h"
+
+extern void abort() __attribute__((__noreturn__));
+#define assert(expr) ((expr) ? (void)(0) : abort())
+
+void invalidate_globals(void);
+void clang_analyzer_eval(int x);
+
+/// Test the special system 'errno'
+void test_errno_constraint() {
+  assert(errno > 2);
+  clang_analyzer_eval(errno > 2); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(errno > 2); // expected-warning {{UNKNOWN}}
+}
+void test_errno_assign(int x) {
+  errno = x;
+  clang_analyzer_eval(errno == x); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(errno == x); // expected-warning {{UNKNOWN}}
+}
+
+/// Test user global variables
+void test_my_const_user_global_constraint() {
+  assert(my_const_user_global > 2);
+  clang_analyzer_eval(my_const_user_global > 2); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_const_user_global > 2); // expected-warning {{TRUE}}
+}
+void test_my_const_user_global_assign(int); // One cannot assign value to a const lvalue.
+
+void test_my_mutable_user_global_constraint() {
+  assert(my_mutable_user_global > 2);
+  clang_analyzer_eval(my_mutable_user_global > 2); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_mutable_user_global > 2); // expected-warning {{UNKNOWN}}
+}
+void test_my_mutable_user_global_assign(int x) {
+  my_mutable_user_global = x;
+  clang_analyzer_eval(my_mutable_user_global == x); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_mutable_user_global == x); // expected-warning {{UNKNOWN}}
+}
+
+/// Test system global variables
+void test_my_const_system_global_constraint() {
+  assert(my_const_system_global > 2);
+  clang_analyzer_eval(my_const_system_global > 2); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_const_system_global > 2); // expected-warning {{TRUE}}
+}
+void test_my_const_system_global_assign(int);// One cannot assign value to a const lvalue.
+
+void test_my_mutable_system_global_constraint() {
+  assert(my_mutable_system_global > 2);
+  clang_analyzer_eval(my_mutable_system_global > 2); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_mutable_system_global > 2); // expected-warning {{UNKNOWN}}
+}
+void test_my_mutable_system_global_assign(int x) {
+  my_mutable_system_global = x;
+  clang_analyzer_eval(my_mutable_system_global == x); // expected-warning {{TRUE}}
+  invalidate_globals();
+  clang_analyzer_eval(my_mutable_system_global == x); // expected-warning {{UNKNOWN}}
+}
Index: clang/test/Analysis/Inputs/some_user_globals.h
===================================================================
--- /dev/null
+++ clang/test/Analysis/Inputs/some_user_globals.h
@@ -0,0 +1,2 @@
+extern const int my_const_user_global;
+extern int my_mutable_user_global;
Index: clang/test/Analysis/Inputs/some_system_globals.h
===================================================================
--- /dev/null
+++ clang/test/Analysis/Inputs/some_system_globals.h
@@ -0,0 +1,4 @@
+#pragma clang system_header
+
+extern const int my_const_system_global;
+extern int my_mutable_system_global;
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -973,26 +973,16 @@
   const MemRegion *sReg = nullptr;
 
   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
-
-    // First handle the globals defined in system headers.
-    if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
-      //  Allow the system globals which often DO GET modified, assume the
-      // rest are immutable.
-      if (D->getName().contains("errno"))
-        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();
+    QualType Ty = D->getType();
+    assert(!Ty.isNull());
+    if (Ty.isConstQualified() && Ty->isArithmeticType()) {
       // 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();
+      sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
+    } else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
+      sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
+    } else {
+      sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
     }
 
   // Finally handle static locals.
Index: clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -92,10 +92,8 @@
     return false;
 
   // Get it's symbol and find the declaration region it's pointing to.
-  const auto *Sm = dyn_cast<SymbolRegionValue>(SymReg->getSymbol());
-  if (!Sm)
-    return false;
-  const auto *DeclReg = dyn_cast<DeclRegion>(Sm->getRegion());
+  const auto *DeclReg =
+      dyn_cast_or_null<DeclRegion>(SymReg->getSymbol()->getOriginRegion());
   if (!DeclReg)
     return false;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to