[clang] [clang][analyzer] Check for label location bindings in `DereferenceChecker` (PR #91119)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Mon May 13 00:19:24 PDT 2024
https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/91119
>From 78a2afab67eef9a8a05ced89df0aadb56a2ec2b8 Mon Sep 17 00:00:00 2001
From: Rajveer <rajveer.developer at icloud.com>
Date: Sun, 5 May 2024 18:05:00 +0530
Subject: [PATCH 1/2] [clang][analyzer] Check for label location bindings in
`DereferenceChecker`
Resolves #89264
---
.../Checkers/DereferenceChecker.cpp | 15 ++++++++++++++-
clang/test/Analysis/gh-issue-89185.c | 7 +++----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index 1cebfbbee77da..0355eede75eae 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -31,11 +31,13 @@ class DereferenceChecker
: public Checker< check::Location,
check::Bind,
EventDispatcher<ImplicitNullDerefEvent> > {
- enum DerefKind { NullPointer, UndefinedPointerValue };
+ enum DerefKind { NullPointer, UndefinedPointerValue, AddressOfLabel };
BugType BT_Null{this, "Dereference of null pointer", categories::LogicError};
BugType BT_Undef{this, "Dereference of undefined pointer value",
categories::LogicError};
+ BugType BT_Label{this, "Dereference of the address of a label",
+ categories::LogicError};
void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
CheckerContext &C) const;
@@ -167,6 +169,11 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State,
DerefStr1 = " results in an undefined pointer dereference";
DerefStr2 = " results in a dereference of an undefined pointer value";
break;
+ case DerefKind::AddressOfLabel:
+ BT = &BT_Label;
+ DerefStr1 = " results in an undefined pointer dereference";
+ DerefStr2 = " results in a dereference of an address of a label";
+ break;
};
// Generate an error node.
@@ -287,6 +294,12 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
if (V.isUndef())
return;
+ // One should never write to label addresses.
+ if (auto Label = L.getAs<loc::GotoLabel>()) {
+ reportBug(DerefKind::AddressOfLabel, C.getState(), S, C);
+ return;
+ }
+
const MemRegion *MR = L.getAsRegion();
const TypedValueRegion *TVR = dyn_cast_or_null<TypedValueRegion>(MR);
if (!TVR)
diff --git a/clang/test/Analysis/gh-issue-89185.c b/clang/test/Analysis/gh-issue-89185.c
index 8a907f198a5fd..27456e7efe885 100644
--- a/clang/test/Analysis/gh-issue-89185.c
+++ b/clang/test/Analysis/gh-issue-89185.c
@@ -7,8 +7,7 @@ void clang_analyzer_dump_ptr(char*);
void binding_to_label_loc() {
char *b = &&MyLabel;
MyLabel:
- *b = 0; // no-crash
- clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}}
- clang_analyzer_dump(*b); // expected-warning {{Unknown}}
- // FIXME: We should never reach here, as storing to a label is invalid.
+ *b = 0; // expected-warning {{Dereference of the address of a label}}
+ clang_analyzer_dump_ptr(b);
+ clang_analyzer_dump(*b);
}
>From 68b541906c5238b9165702c5623a00c877b53cbf Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Mon, 13 May 2024 09:17:13 +0200
Subject: [PATCH 2/2] Track the LHS of assignments for deref bugs
This adds notes for the "definition" lines for the dereferenced
variables that are raised for assignment expressions.
---
.../StaticAnalyzer/Core/BugReporterVisitors.cpp | 3 +++
clang/test/Analysis/gh-issue-89185.c | 14 +++++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 984755fa7e502..487a3bd16b674 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -113,6 +113,9 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
// Pointer arithmetic: '*(x + 2)' -> 'x') etc.
if (const Expr *Inner = peelOffPointerArithmetic(B)) {
E = Inner;
+ } else if (B->isAssignmentOp()) {
+ // Follow LHS of assignments: '*p = 404' -> 'p'.
+ E = B->getLHS();
} else {
// Probably more arithmetic can be pattern-matched here,
// but for now give up.
diff --git a/clang/test/Analysis/gh-issue-89185.c b/clang/test/Analysis/gh-issue-89185.c
index 27456e7efe885..49526d2daa866 100644
--- a/clang/test/Analysis/gh-issue-89185.c
+++ b/clang/test/Analysis/gh-issue-89185.c
@@ -1,13 +1,13 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-output text -verify %s
-void clang_analyzer_dump(char);
-void clang_analyzer_dump_ptr(char*);
+void clang_analyzer_warnIfReached(void);
// https://github.com/llvm/llvm-project/issues/89185
void binding_to_label_loc() {
- char *b = &&MyLabel;
+ char *b = &&MyLabel; // expected-note {{'b' initialized here}}
MyLabel:
- *b = 0; // expected-warning {{Dereference of the address of a label}}
- clang_analyzer_dump_ptr(b);
- clang_analyzer_dump(*b);
+ *b = 0;
+ // expected-warning at -1 {{Dereference of the address of a label}}
+ // expected-note at -2 {{Dereference of the address of a label}}
+ clang_analyzer_warnIfReached(); // no-warning: Unreachable due to fatal error.
}
More information about the cfe-commits
mailing list