Skip to content

Commit 96ec9b6

Browse files
author
Gabor Marton
committed
[Analyzer] ConversionChecker: track back the cast expression
Adding trackExpressionValue to the checker so it tracks the value of the implicit cast's DeclRefExpression up to initialization/assignment. This way the report becomes cleaner. Differential Revision: https://reviews.llvm.org/D109836
1 parent bd590a5 commit 96ec9b6

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class ConversionChecker : public Checker<check::PreStmt<ImplicitCastExpr>> {
4949

5050
bool isLossOfSign(const ImplicitCastExpr *Cast, CheckerContext &C) const;
5151

52-
void reportBug(ExplodedNode *N, CheckerContext &C, const char Msg[]) const;
52+
void reportBug(ExplodedNode *N, const Expr *E, CheckerContext &C,
53+
const char Msg[]) const;
5354
};
5455
}
5556

@@ -108,20 +109,21 @@ void ConversionChecker::checkPreStmt(const ImplicitCastExpr *Cast,
108109
if (!N)
109110
return;
110111
if (LossOfSign)
111-
reportBug(N, C, "Loss of sign in implicit conversion");
112+
reportBug(N, Cast, C, "Loss of sign in implicit conversion");
112113
if (LossOfPrecision)
113-
reportBug(N, C, "Loss of precision in implicit conversion");
114+
reportBug(N, Cast, C, "Loss of precision in implicit conversion");
114115
}
115116
}
116117

117-
void ConversionChecker::reportBug(ExplodedNode *N, CheckerContext &C,
118-
const char Msg[]) const {
118+
void ConversionChecker::reportBug(ExplodedNode *N, const Expr *E,
119+
CheckerContext &C, const char Msg[]) const {
119120
if (!BT)
120121
BT.reset(
121122
new BuiltinBug(this, "Conversion", "Possible loss of sign/precision."));
122123

123124
// Generate a report for this bug.
124125
auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
126+
bugreporter::trackExpressionValue(N, E, *R);
125127
C.emitReport(std::move(R));
126128
}
127129

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_analyze_cc1 %s \
2+
// RUN: -Wno-conversion -Wno-tautological-constant-compare \
3+
// RUN: -analyzer-checker=core,apiModeling,alpha.core.Conversion \
4+
// RUN: -analyzer-output=text \
5+
// RUN: -verify
6+
7+
unsigned char U8;
8+
signed char S8;
9+
10+
void track_assign() {
11+
unsigned long L = 1000; // expected-note {{'L' initialized to 1000}}
12+
int I = -1; // expected-note {{'I' initialized to -1}}
13+
U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}
14+
// expected-note@-1 {{Loss of precision in implicit conversion}}
15+
L *= I; // expected-warning {{Loss of sign in implicit conversion}}
16+
// expected-note@-1 {{Loss of sign in implicit conversion}}
17+
}
18+
19+
void track_relational(unsigned U, signed S) {
20+
if (S < -10) { // expected-note {{Taking true branch}}
21+
// expected-note@-1 {{Assuming the condition is true}}
22+
if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
23+
// expected-note@-1 {{Loss of sign in implicit conversion}}
24+
}
25+
}
26+
}

clang/test/Analysis/conversion.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,apiModeling,alpha.core.Conversion -verify %s
1+
// RUN: %clang_analyze_cc1 %s \
2+
// RUN: -Wno-conversion -Wno-tautological-constant-compare \
3+
// RUN: -analyzer-checker=core,apiModeling,alpha.core.Conversion \
4+
// RUN: -verify
25

36
unsigned char U8;
47
signed char S8;

0 commit comments

Comments
 (0)