vabridgers updated this revision to Diff 421521.
vabridgers edited the summary of this revision.
vabridgers added a comment.

clean up a few debug edits


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122841

Files:
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/cast-value-notes.cpp

Index: clang/test/Analysis/cast-value-notes.cpp
===================================================================
--- clang/test/Analysis/cast-value-notes.cpp
+++ clang/test/Analysis/cast-value-notes.cpp
@@ -6,6 +6,12 @@
 // RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
 // RUN: -analyzer-output=text -verify -DAMDGCN_TRIPLE %s 2>&1 | FileCheck %s -check-prefix=AMDGCN-CHECK
 
+// RUN: %clang_analyze_cc1 -std=c++14 -triple amdgcn-unknown-unknown \
+// RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
+// RUN: -analyzer-config core.NullDereference:DetectAllNullDereferences=true -analyzer-output=text\
+// RUN: -verify -DDETECT_ALL_NULL_DEREFERENCES  -DAMDGCN_TRIPLE %s 2>&1 | FileCheck %s\
+// RUN: -check-prefix=AMDGCN-CHECK-WARNADDRSPACE
+
 #include "Inputs/llvm.h"
 
 // The amggcn triple case uses an intentionally different address space.
@@ -48,6 +54,18 @@
   (void)C;
 }
 #elif defined(AMDGCN_TRIPLE)
+#if defined(DETECT_ALL_NULL_DEREFERENCES)
+void evalReferences(const Shape &S) {
+  const auto &C = dyn_cast<DEVICE Circle>(S);
+  // expected-note@-1 {{Assuming 'S' is not a 'Circle'}}
+  // expected-note@-2 {{Dereference of null pointer}}
+  // expected-warning@-3 {{Dereference of null pointer}}
+  clang_analyzer_printState();
+  // AMDGCN-CHECK-WARNADDRSPACE: "dynamic_types": [
+  // AMDGCN-CHECK-WARNADDRSPACE-NEXT: { "region": "SymRegion{reg_$0<const struct clang::Shape & S>}", "dyn_type": "const __attribute__((address_space(3))) class clang::Circle &", "sub_classable": true }
+  (void)C;
+}
+#else
 void evalReferences(const Shape &S) {
   const auto &C = dyn_cast<DEVICE Circle>(S);
   clang_analyzer_printState();
@@ -55,6 +73,7 @@
   // AMDGCN-CHECK-NEXT: { "region": "SymRegion{reg_$0<const struct clang::Shape & S>}", "dyn_type": "const __attribute__((address_space(3))) class clang::Circle &", "sub_classable": true }
   (void)C;
 }
+#endif
 #else
 #error Target must be specified, and must be pinned
 #endif
Index: clang/test/Analysis/analyzer-config.c
===================================================================
--- clang/test/Analysis/analyzer-config.c
+++ clang/test/Analysis/analyzer-config.c
@@ -41,6 +41,7 @@
 // CHECK-NEXT: core.CallAndMessage:NilReceiver = true
 // CHECK-NEXT: core.CallAndMessage:ParameterCount = true
 // CHECK-NEXT: core.CallAndMessage:UndefReceiver = true
+// CHECK-NEXT: core.NullDereference:DetectAllNullDereferences = false
 // CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals
 // CHECK-NEXT: cplusplus.SmartPtrModeling:ModelSmartPtrDereference = false
 // CHECK-NEXT: crosscheck-with-z3 = false
Index: clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -39,6 +39,8 @@
   void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
                  CheckerContext &C) const;
 
+  bool suppressReport(const Expr *E) const;
+
 public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
                      CheckerContext &C) const;
@@ -49,6 +51,8 @@
                              const Expr *Ex, const ProgramState *state,
                              const LocationContext *LCtx,
                              bool loadedFrom = false);
+
+  bool DetectAllNullDereferences = false;
 };
 } // end anonymous namespace
 
@@ -109,9 +113,24 @@
   return E;
 }
 
-static bool suppressReport(const Expr *E) {
-  // Do not report dereferences on memory in non-default address spaces.
-  return E->getType().hasAddressSpace();
+bool DereferenceChecker::suppressReport(const Expr *E) const {
+  // Do not report dereferences on memory that use address space #256, #257,
+  // and #258. Those address spaces are used when dereferencing address spaces
+  // relative to the GS, FS, and SS segments on x86/x86-64 targets.
+  // Dereferencing a null pointer in these address spaces is not defined
+  // as an error. All other null dereferences in other address spaces
+  // are defined as an error unless explicitly defined.
+  // See https://clang.llvm.org/docs/LanguageExtensions.html, the section
+  // "X86/X86-64 Language Extensions"
+  if (isTargetAddressSpace(E->getType().getAddressSpace())) {
+    switch (toTargetAddressSpace(E->getType().getAddressSpace())) {
+    case 256:
+    case 257:
+    case 258:
+      return true;
+    }
+  }
+  return (E->getType().hasAddressSpace() && !DetectAllNullDereferences);
 }
 
 static bool isDeclRefExprToReference(const Expr *E) {
@@ -308,7 +327,11 @@
 }
 
 void ento::registerDereferenceChecker(CheckerManager &mgr) {
-  mgr.registerChecker<DereferenceChecker>();
+  auto *Chk = mgr.registerChecker<DereferenceChecker>();
+  // auto *Chk = mgr.getChecker<DereferenceChecker>();
+  Chk->DetectAllNullDereferences =
+      mgr.getAnalyzerOptions().getCheckerBooleanOption(
+          mgr.getCurrentCheckerName(), "DetectAllNullDereferences");
 }
 
 bool ento::shouldRegisterDereferenceChecker(const CheckerManager &mgr) {
Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -191,6 +191,13 @@
 
 def DereferenceChecker : Checker<"NullDereference">,
   HelpText<"Check for dereferences of null pointers">,
+  CheckerOptions<[
+    CmdLineOption<Boolean,
+                  "DetectAllNullDereferences",
+                  "Enables detection of all dereferences, regardless of address space",
+                  "false",
+                  Released>
+  ]>,
   Documentation<HasDocumentation>;
 
 def NonNullParamChecker : Checker<"NonNullParamChecker">,
Index: clang/docs/analyzer/checkers.rst
===================================================================
--- clang/docs/analyzer/checkers.rst
+++ clang/docs/analyzer/checkers.rst
@@ -66,7 +66,17 @@
 
 core.NullDereference (C, C++, ObjC)
 """""""""""""""""""""""""""""""""""
-Check for dereferences of null pointers.
+Check for dereferences of null pointers. This checker specifically does
+not report null pointer dereferences for x86 and x86-64 targets when the
+address space is 256 (x86 GS Segment), 257 (x86 FS Segment), or 258 (x86 SS
+segment). See `X86/X86-64 Language Extensions
+<https://clang.llvm.org/docs/LanguageExtensions.html#memory-references-to-specified-segments>`__
+for reference.
+
+The ``DetectAllNullDereferences`` option enables the checker to emit
+warnings for null dereferences of all pointers. You can enable with the
+``-analyzer-config core.NullDereference:DetectAllNullDereferences=true``.
+*Defaults to false*.
 
 .. code-block:: objc
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to