Skip to content

Commit fd41f1b

Browse files
authored
[clang][analyzer] Add BugReporterVisitor messages for non-null fixed pointer (#129557)
1 parent 6b47bba commit fd41f1b

File tree

2 files changed

+102
-9
lines changed

2 files changed

+102
-9
lines changed

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,27 @@ static bool isObjCPointer(const ValueDecl *D) {
12231223
return D->getType()->isObjCObjectPointerType();
12241224
}
12251225

1226+
namespace {
1227+
using DestTypeValue = std::pair<const StoreInfo &, loc::ConcreteInt>;
1228+
1229+
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DestTypeValue &Val) {
1230+
if (auto *TyR = Val.first.Dest->getAs<TypedRegion>()) {
1231+
QualType LocTy = TyR->getLocationType();
1232+
if (!LocTy.isNull()) {
1233+
if (auto *PtrTy = LocTy->getAs<PointerType>()) {
1234+
std::string PStr = PtrTy->getPointeeType().getAsString();
1235+
if (!PStr.empty())
1236+
OS << "(" << PStr << ")";
1237+
}
1238+
}
1239+
}
1240+
SmallString<16> ValStr;
1241+
Val.second.getValue()->toString(ValStr, 10, true);
1242+
OS << ValStr;
1243+
return OS;
1244+
}
1245+
} // namespace
1246+
12261247
/// Show diagnostics for initializing or declaring a region \p R with a bad value.
12271248
static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) {
12281249
const bool HasPrefix = SI.Dest->canPrintPretty();
@@ -1245,8 +1266,11 @@ static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) {
12451266
llvm_unreachable("Unexpected store kind");
12461267
}
12471268

1248-
if (isa<loc::ConcreteInt>(SI.Value)) {
1249-
OS << Action << (isObjCPointer(SI.Dest) ? "nil" : "a null pointer value");
1269+
if (auto CVal = SI.Value.getAs<loc::ConcreteInt>()) {
1270+
if (!*CVal->getValue())
1271+
OS << Action << (isObjCPointer(SI.Dest) ? "nil" : "a null pointer value");
1272+
else
1273+
OS << Action << DestTypeValue(SI, *CVal);
12501274

12511275
} else if (auto CVal = SI.Value.getAs<nonloc::ConcreteInt>()) {
12521276
OS << Action << CVal->getValue();
@@ -1288,8 +1312,12 @@ static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
12881312

12891313
OS << "Passing ";
12901314

1291-
if (isa<loc::ConcreteInt>(SI.Value)) {
1292-
OS << (isObjCPointer(D) ? "nil object reference" : "null pointer value");
1315+
if (auto CI = SI.Value.getAs<loc::ConcreteInt>()) {
1316+
if (!*CI->getValue())
1317+
OS << (isObjCPointer(D) ? "nil object reference" : "null pointer value");
1318+
else
1319+
OS << (isObjCPointer(D) ? "object reference of value " : "pointer value ")
1320+
<< DestTypeValue(SI, *CI);
12931321

12941322
} else if (SI.Value.isUndef()) {
12951323
OS << "uninitialized value";
@@ -1324,11 +1352,24 @@ static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS,
13241352
StoreInfo SI) {
13251353
const bool HasSuffix = SI.Dest->canPrintPretty();
13261354

1327-
if (isa<loc::ConcreteInt>(SI.Value)) {
1328-
OS << (isObjCPointer(SI.Dest) ? "nil object reference stored"
1329-
: (HasSuffix ? "Null pointer value stored"
1330-
: "Storing null pointer value"));
1331-
1355+
if (auto CV = SI.Value.getAs<loc::ConcreteInt>()) {
1356+
APSIntPtr V = CV->getValue();
1357+
if (!*V)
1358+
OS << (isObjCPointer(SI.Dest)
1359+
? "nil object reference stored"
1360+
: (HasSuffix ? "Null pointer value stored"
1361+
: "Storing null pointer value"));
1362+
else {
1363+
if (isObjCPointer(SI.Dest)) {
1364+
OS << "object reference of value " << DestTypeValue(SI, *CV)
1365+
<< " stored";
1366+
} else {
1367+
if (HasSuffix)
1368+
OS << "Pointer value of " << DestTypeValue(SI, *CV) << " stored";
1369+
else
1370+
OS << "Storing pointer value of " << DestTypeValue(SI, *CV);
1371+
}
1372+
}
13321373
} else if (SI.Value.isUndef()) {
13331374
OS << (HasSuffix ? "Uninitialized value stored"
13341375
: "Storing uninitialized value");
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.FixedAddressDereference -analyzer-output=text -verify %s
2+
3+
extern char *something();
4+
5+
void test1() {
6+
int *p;
7+
p = (int *)22; // expected-note{{Pointer value of (int *)22 stored to 'p'}}
8+
*p = 2; // expected-warning{{Dereference of a fixed address (loaded from variable 'p')}} \
9+
// expected-note{{Dereference of a fixed address (loaded from variable 'p')}}
10+
}
11+
12+
void test2_1(int *p) {
13+
*p = 1; // expected-warning{{Dereference of a fixed address (loaded from variable 'p')}} \
14+
// expected-note{{Dereference of a fixed address (loaded from variable 'p')}}
15+
}
16+
17+
void test2() {
18+
int *p = (int *)11; // expected-note{{'p' initialized to (int *)11}}
19+
test2_1(p); // expected-note{{Passing pointer value (int *)11 via 1st parameter 'p'}} \
20+
// expected-note{{Calling 'test2_1'}}
21+
}
22+
23+
struct test3_s {
24+
int a;
25+
};
26+
27+
28+
void test3() {
29+
struct test3_s *x;
30+
unsigned long long val = 1111111; // expected-note{{'val' initialized to 1111111}}
31+
x = (struct test3_s *)val; // expected-note{{Pointer value of (struct test3_s *)1111111 stored to 'x'}}
32+
x->a = 3; // expected-warning{{Access to field 'a' results in a dereference of a fixed address (loaded from variable 'x')}} \
33+
// expected-note{{Access to field 'a' results in a dereference of a fixed address (loaded from variable 'x')}}
34+
}
35+
36+
char *test4_1() {
37+
char *ret;
38+
ret = something(); // expected-note{{Value assigned to 'ret'}}
39+
if (ret == (char *)-1) // expected-note{{Assuming the condition is true}} \
40+
// expected-note{{Taking true branch}}
41+
return ret; // expected-note{{Returning pointer (loaded from 'ret')}}
42+
return 0;
43+
}
44+
45+
void test4() {
46+
char *x;
47+
x = test4_1(); // expected-note{{Calling 'test4_1'}} \
48+
// expected-note{{Returning from 'test4_1'}} \
49+
// expected-note{{Pointer value of (char *)-1 stored to 'x'}}
50+
*x = 3; // expected-warning{{Dereference of a fixed address (loaded from variable 'x')}} \
51+
// expected-note{{Dereference of a fixed address (loaded from variable 'x')}}
52+
}

0 commit comments

Comments
 (0)