Skip to content

Commit efe91cf

Browse files
Rajveer100steakhal
andauthored
[clang][analyzer] Check for label location bindings in DereferenceChecker (llvm#91119)
Resolves llvm#89264 Values should not be stored in addresses of labels, this throws a fatal error when this happens. --------- Co-authored-by: Balazs Benics <[email protected]>
1 parent 99934da commit efe91cf

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ class DereferenceChecker
3131
: public Checker< check::Location,
3232
check::Bind,
3333
EventDispatcher<ImplicitNullDerefEvent> > {
34-
enum DerefKind { NullPointer, UndefinedPointerValue };
34+
enum DerefKind { NullPointer, UndefinedPointerValue, AddressOfLabel };
3535

3636
BugType BT_Null{this, "Dereference of null pointer", categories::LogicError};
3737
BugType BT_Undef{this, "Dereference of undefined pointer value",
3838
categories::LogicError};
39+
BugType BT_Label{this, "Dereference of the address of a label",
40+
categories::LogicError};
3941

4042
void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
4143
CheckerContext &C) const;
@@ -167,6 +169,11 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State,
167169
DerefStr1 = " results in an undefined pointer dereference";
168170
DerefStr2 = " results in a dereference of an undefined pointer value";
169171
break;
172+
case DerefKind::AddressOfLabel:
173+
BT = &BT_Label;
174+
DerefStr1 = " results in an undefined pointer dereference";
175+
DerefStr2 = " results in a dereference of an address of a label";
176+
break;
170177
};
171178

172179
// Generate an error node.
@@ -287,6 +294,12 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
287294
if (V.isUndef())
288295
return;
289296

297+
// One should never write to label addresses.
298+
if (auto Label = L.getAs<loc::GotoLabel>()) {
299+
reportBug(DerefKind::AddressOfLabel, C.getState(), S, C);
300+
return;
301+
}
302+
290303
const MemRegion *MR = L.getAsRegion();
291304
const TypedValueRegion *TVR = dyn_cast_or_null<TypedValueRegion>(MR);
292305
if (!TVR)

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
113113
// Pointer arithmetic: '*(x + 2)' -> 'x') etc.
114114
if (const Expr *Inner = peelOffPointerArithmetic(B)) {
115115
E = Inner;
116+
} else if (B->isAssignmentOp()) {
117+
// Follow LHS of assignments: '*p = 404' -> 'p'.
118+
E = B->getLHS();
116119
} else {
117120
// Probably more arithmetic can be pattern-matched here,
118121
// but for now give up.

clang/test/Analysis/gh-issue-89185.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-output text -verify %s
22

3-
void clang_analyzer_dump(char);
4-
void clang_analyzer_dump_ptr(char*);
3+
void clang_analyzer_warnIfReached(void);
54

65
// https://github.com/llvm/llvm-project/issues/89185
76
void binding_to_label_loc() {
8-
char *b = &&MyLabel;
7+
char *b = &&MyLabel; // expected-note {{'b' initialized here}}
98
MyLabel:
10-
*b = 0; // no-crash
11-
clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}}
12-
clang_analyzer_dump(*b); // expected-warning {{Unknown}}
13-
// FIXME: We should never reach here, as storing to a label is invalid.
9+
*b = 0;
10+
// expected-warning@-1 {{Dereference of the address of a label}}
11+
// expected-note@-2 {{Dereference of the address of a label}}
12+
clang_analyzer_warnIfReached(); // no-warning: Unreachable due to fatal error.
1413
}

0 commit comments

Comments
 (0)