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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits