Skip to content

Commit 58d655f

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merge upstream LLVM into amd-gfx12
2 parents d1cb9b2 + bd2b7eb commit 58d655f

File tree

78 files changed

+3315
-781
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3315
-781
lines changed

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,15 @@ def CallAndMessageChecker : Checker<"CallAndMessage">,
206206
Documentation<HasDocumentation>,
207207
Dependencies<[CallAndMessageModeling]>;
208208

209-
def DereferenceModeling : Checker<"DereferenceModeling">,
210-
HelpText<"General support for dereference related checkers">,
211-
Documentation<NotDocumented>,
212-
Hidden;
213-
214209
def FixedAddressDereferenceChecker
215210
: Checker<"FixedAddressDereference">,
216211
HelpText<"Check for dereferences of fixed addresses">,
217-
Documentation<HasDocumentation>,
218-
Dependencies<[DereferenceModeling]>;
212+
Documentation<HasDocumentation>;
219213

220-
def NullDereferenceChecker : Checker<"NullDereference">,
221-
HelpText<"Check for dereferences of null pointers">,
222-
Documentation<HasDocumentation>,
223-
Dependencies<[DereferenceModeling]>;
214+
def NullDereferenceChecker
215+
: Checker<"NullDereference">,
216+
HelpText<"Check for dereferences of null pointers">,
217+
Documentation<HasDocumentation>;
224218

225219
def NonNullParamChecker : Checker<"NonNullParamChecker">,
226220
HelpText<"Check for null pointers passed as arguments to a function whose "

clang/lib/Serialization/ASTReader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8488,6 +8488,7 @@ bool ASTReader::LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
84888488
bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
84898489
assert(D);
84908490

8491+
CompleteRedeclChain(D);
84918492
bool NewSpecsFound =
84928493
LoadExternalSpecializationsImpl(PartialSpecializationsLookups, D);
84938494
if (OnlyPartial)

clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp

Lines changed: 76 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,22 @@ using namespace clang;
2525
using namespace ento;
2626

2727
namespace {
28+
29+
class DerefBugType : public BugType {
30+
StringRef ArrayMsg, FieldMsg;
31+
32+
public:
33+
DerefBugType(CheckerFrontend *FE, StringRef Desc, const char *AMsg,
34+
const char *FMsg = nullptr)
35+
: BugType(FE, Desc), ArrayMsg(AMsg), FieldMsg(FMsg ? FMsg : AMsg) {}
36+
StringRef getArrayMsg() const { return ArrayMsg; }
37+
StringRef getFieldMsg() const { return FieldMsg; }
38+
};
39+
2840
class DereferenceChecker
29-
: public Checker< check::Location,
30-
check::Bind,
31-
EventDispatcher<ImplicitNullDerefEvent> > {
32-
enum DerefKind {
33-
NullPointer,
34-
UndefinedPointerValue,
35-
AddressOfLabel,
36-
FixedAddress,
37-
};
38-
39-
void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
41+
: public CheckerFamily<check::Location, check::Bind,
42+
EventDispatcher<ImplicitNullDerefEvent>> {
43+
void reportBug(const DerefBugType &BT, ProgramStateRef State, const Stmt *S,
4044
CheckerContext &C) const;
4145

4246
bool suppressReport(CheckerContext &C, const Expr *E) const;
@@ -52,13 +56,23 @@ class DereferenceChecker
5256
const LocationContext *LCtx,
5357
bool loadedFrom = false);
5458

55-
bool CheckNullDereference = false;
56-
bool CheckFixedDereference = false;
57-
58-
std::unique_ptr<BugType> BT_Null;
59-
std::unique_ptr<BugType> BT_Undef;
60-
std::unique_ptr<BugType> BT_Label;
61-
std::unique_ptr<BugType> BT_FixedAddress;
59+
CheckerFrontend NullDerefChecker, FixedDerefChecker;
60+
const DerefBugType NullBug{&NullDerefChecker, "Dereference of null pointer",
61+
"a null pointer dereference",
62+
"a dereference of a null pointer"};
63+
const DerefBugType UndefBug{&NullDerefChecker,
64+
"Dereference of undefined pointer value",
65+
"an undefined pointer dereference",
66+
"a dereference of an undefined pointer value"};
67+
const DerefBugType LabelBug{&NullDerefChecker,
68+
"Dereference of the address of a label",
69+
"an undefined pointer dereference",
70+
"a dereference of an address of a label"};
71+
const DerefBugType FixedAddressBug{&FixedDerefChecker,
72+
"Dereference of a fixed address",
73+
"a dereference of a fixed address"};
74+
75+
StringRef getDebugTag() const override { return "DereferenceChecker"; }
6276
};
6377
} // end anonymous namespace
6478

@@ -158,115 +172,87 @@ static bool isDeclRefExprToReference(const Expr *E) {
158172
return false;
159173
}
160174

161-
void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State,
162-
const Stmt *S, CheckerContext &C) const {
163-
const BugType *BT = nullptr;
164-
llvm::StringRef DerefStr1;
165-
llvm::StringRef DerefStr2;
166-
switch (K) {
167-
case DerefKind::NullPointer:
168-
if (!CheckNullDereference) {
169-
C.addSink();
170-
return;
171-
}
172-
BT = BT_Null.get();
173-
DerefStr1 = " results in a null pointer dereference";
174-
DerefStr2 = " results in a dereference of a null pointer";
175-
break;
176-
case DerefKind::UndefinedPointerValue:
177-
if (!CheckNullDereference) {
178-
C.addSink();
175+
void DereferenceChecker::reportBug(const DerefBugType &BT,
176+
ProgramStateRef State, const Stmt *S,
177+
CheckerContext &C) const {
178+
if (&BT == &FixedAddressBug) {
179+
if (!FixedDerefChecker.isEnabled())
180+
// Deliberately don't add a sink node if check is disabled.
181+
// This situation may be valid in special cases.
179182
return;
180-
}
181-
BT = BT_Undef.get();
182-
DerefStr1 = " results in an undefined pointer dereference";
183-
DerefStr2 = " results in a dereference of an undefined pointer value";
184-
break;
185-
case DerefKind::AddressOfLabel:
186-
if (!CheckNullDereference) {
183+
} else {
184+
if (!NullDerefChecker.isEnabled()) {
187185
C.addSink();
188186
return;
189187
}
190-
BT = BT_Label.get();
191-
DerefStr1 = " results in an undefined pointer dereference";
192-
DerefStr2 = " results in a dereference of an address of a label";
193-
break;
194-
case DerefKind::FixedAddress:
195-
// Deliberately don't add a sink node if check is disabled.
196-
// This situation may be valid in special cases.
197-
if (!CheckFixedDereference)
198-
return;
199-
200-
BT = BT_FixedAddress.get();
201-
DerefStr1 = " results in a dereference of a fixed address";
202-
DerefStr2 = " results in a dereference of a fixed address";
203-
break;
204-
};
188+
}
205189

206190
// Generate an error node.
207191
ExplodedNode *N = C.generateErrorNode(State);
208192
if (!N)
209193
return;
210194

211-
SmallString<100> buf;
212-
llvm::raw_svector_ostream os(buf);
195+
SmallString<100> Buf;
196+
llvm::raw_svector_ostream Out(Buf);
213197

214198
SmallVector<SourceRange, 2> Ranges;
215199

216200
switch (S->getStmtClass()) {
217201
case Stmt::ArraySubscriptExprClass: {
218-
os << "Array access";
202+
Out << "Array access";
219203
const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
220-
AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
221-
State.get(), N->getLocationContext());
222-
os << DerefStr1;
204+
AddDerefSource(Out, Ranges, AE->getBase()->IgnoreParenCasts(), State.get(),
205+
N->getLocationContext());
206+
Out << " results in " << BT.getArrayMsg();
223207
break;
224208
}
225209
case Stmt::ArraySectionExprClass: {
226-
os << "Array access";
210+
Out << "Array access";
227211
const ArraySectionExpr *AE = cast<ArraySectionExpr>(S);
228-
AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
229-
State.get(), N->getLocationContext());
230-
os << DerefStr1;
212+
AddDerefSource(Out, Ranges, AE->getBase()->IgnoreParenCasts(), State.get(),
213+
N->getLocationContext());
214+
Out << " results in " << BT.getArrayMsg();
231215
break;
232216
}
233217
case Stmt::UnaryOperatorClass: {
234-
os << BT->getDescription();
218+
Out << BT.getDescription();
235219
const UnaryOperator *U = cast<UnaryOperator>(S);
236-
AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
237-
State.get(), N->getLocationContext(), true);
220+
AddDerefSource(Out, Ranges, U->getSubExpr()->IgnoreParens(), State.get(),
221+
N->getLocationContext(), true);
238222
break;
239223
}
240224
case Stmt::MemberExprClass: {
241225
const MemberExpr *M = cast<MemberExpr>(S);
242226
if (M->isArrow() || isDeclRefExprToReference(M->getBase())) {
243-
os << "Access to field '" << M->getMemberNameInfo() << "'" << DerefStr2;
244-
AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
245-
State.get(), N->getLocationContext(), true);
227+
Out << "Access to field '" << M->getMemberNameInfo() << "' results in "
228+
<< BT.getFieldMsg();
229+
AddDerefSource(Out, Ranges, M->getBase()->IgnoreParenCasts(), State.get(),
230+
N->getLocationContext(), true);
246231
}
247232
break;
248233
}
249234
case Stmt::ObjCIvarRefExprClass: {
250235
const ObjCIvarRefExpr *IV = cast<ObjCIvarRefExpr>(S);
251-
os << "Access to instance variable '" << *IV->getDecl() << "'" << DerefStr2;
252-
AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(),
253-
State.get(), N->getLocationContext(), true);
236+
Out << "Access to instance variable '" << *IV->getDecl() << "' results in "
237+
<< BT.getFieldMsg();
238+
AddDerefSource(Out, Ranges, IV->getBase()->IgnoreParenCasts(), State.get(),
239+
N->getLocationContext(), true);
254240
break;
255241
}
256242
default:
257243
break;
258244
}
259245

260-
auto report = std::make_unique<PathSensitiveBugReport>(
261-
*BT, buf.empty() ? BT->getDescription() : buf.str(), N);
246+
auto BR = std::make_unique<PathSensitiveBugReport>(
247+
BT, Buf.empty() ? BT.getDescription() : Buf.str(), N);
262248

263-
bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *report);
249+
bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *BR);
264250

265251
for (SmallVectorImpl<SourceRange>::iterator
266252
I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
267-
report->addRange(*I);
253+
BR->addRange(*I);
268254

269-
C.emitReport(std::move(report));
255+
C.emitReport(std::move(BR));
270256
}
271257

272258
void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
@@ -275,7 +261,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
275261
if (l.isUndef()) {
276262
const Expr *DerefExpr = getDereferenceExpr(S);
277263
if (!suppressReport(C, DerefExpr))
278-
reportBug(DerefKind::UndefinedPointerValue, C.getState(), DerefExpr, C);
264+
reportBug(UndefBug, C.getState(), DerefExpr, C);
279265
return;
280266
}
281267

@@ -296,7 +282,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
296282
// we call an "explicit" null dereference.
297283
const Expr *expr = getDereferenceExpr(S);
298284
if (!suppressReport(C, expr)) {
299-
reportBug(DerefKind::NullPointer, nullState, expr, C);
285+
reportBug(NullBug, nullState, expr, C);
300286
return;
301287
}
302288
}
@@ -314,7 +300,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
314300
if (location.isConstant()) {
315301
const Expr *DerefExpr = getDereferenceExpr(S, isLoad);
316302
if (!suppressReport(C, DerefExpr))
317-
reportBug(DerefKind::FixedAddress, notNullState, DerefExpr, C);
303+
reportBug(FixedAddressBug, notNullState, DerefExpr, C);
318304
return;
319305
}
320306

@@ -330,7 +316,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
330316

331317
// One should never write to label addresses.
332318
if (auto Label = L.getAs<loc::GotoLabel>()) {
333-
reportBug(DerefKind::AddressOfLabel, C.getState(), S, C);
319+
reportBug(LabelBug, C.getState(), S, C);
334320
return;
335321
}
336322

@@ -351,7 +337,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
351337
if (!StNonNull) {
352338
const Expr *expr = getDereferenceExpr(S, /*IsBind=*/true);
353339
if (!suppressReport(C, expr)) {
354-
reportBug(DerefKind::NullPointer, StNull, expr, C);
340+
reportBug(NullBug, StNull, expr, C);
355341
return;
356342
}
357343
}
@@ -369,7 +355,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
369355
if (V.isConstant()) {
370356
const Expr *DerefExpr = getDereferenceExpr(S, true);
371357
if (!suppressReport(C, DerefExpr))
372-
reportBug(DerefKind::FixedAddress, State, DerefExpr, C);
358+
reportBug(FixedAddressBug, State, DerefExpr, C);
373359
return;
374360
}
375361

@@ -392,38 +378,16 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
392378
C.addTransition(State, this);
393379
}
394380

395-
void ento::registerDereferenceModeling(CheckerManager &Mgr) {
396-
Mgr.registerChecker<DereferenceChecker>();
397-
}
398-
399-
bool ento::shouldRegisterDereferenceModeling(const CheckerManager &) {
400-
return true;
401-
}
402-
403381
void ento::registerNullDereferenceChecker(CheckerManager &Mgr) {
404-
auto *Chk = Mgr.getChecker<DereferenceChecker>();
405-
Chk->CheckNullDereference = true;
406-
Chk->BT_Null.reset(new BugType(Mgr.getCurrentCheckerName(),
407-
"Dereference of null pointer",
408-
categories::LogicError));
409-
Chk->BT_Undef.reset(new BugType(Mgr.getCurrentCheckerName(),
410-
"Dereference of undefined pointer value",
411-
categories::LogicError));
412-
Chk->BT_Label.reset(new BugType(Mgr.getCurrentCheckerName(),
413-
"Dereference of the address of a label",
414-
categories::LogicError));
382+
Mgr.getChecker<DereferenceChecker>()->NullDerefChecker.enable(Mgr);
415383
}
416384

417385
bool ento::shouldRegisterNullDereferenceChecker(const CheckerManager &) {
418386
return true;
419387
}
420388

421389
void ento::registerFixedAddressDereferenceChecker(CheckerManager &Mgr) {
422-
auto *Chk = Mgr.getChecker<DereferenceChecker>();
423-
Chk->CheckFixedDereference = true;
424-
Chk->BT_FixedAddress.reset(new BugType(Mgr.getCurrentCheckerName(),
425-
"Dereference of a fixed address",
426-
categories::LogicError));
390+
Mgr.getChecker<DereferenceChecker>()->FixedDerefChecker.enable(Mgr);
427391
}
428392

429393
bool ento::shouldRegisterFixedAddressDereferenceChecker(

clang/test/Analysis/analyzer-enabled-checkers.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// CHECK-NEXT: core.BitwiseShift
1515
// CHECK-NEXT: core.CallAndMessageModeling
1616
// CHECK-NEXT: core.CallAndMessage
17-
// CHECK-NEXT: core.DereferenceModeling
1817
// CHECK-NEXT: core.DivideZero
1918
// CHECK-NEXT: core.DynamicTypePropagation
2019
// CHECK-NEXT: core.FixedAddressDereference

clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
// CHECK-NEXT: core.BitwiseShift
2323
// CHECK-NEXT: core.CallAndMessageModeling
2424
// CHECK-NEXT: core.CallAndMessage
25-
// CHECK-NEXT: core.DereferenceModeling
2625
// CHECK-NEXT: core.DivideZero
2726
// CHECK-NEXT: core.DynamicTypePropagation
2827
// CHECK-NEXT: core.FixedAddressDereference

0 commit comments

Comments
 (0)