Skip to content

Commit 0cc838f

Browse files
committed
[clang-analyzer] Apply clang-format
1 parent 650b0f7 commit 0cc838f

File tree

1 file changed

+80
-66
lines changed

1 file changed

+80
-66
lines changed

clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@
5252
#include "clang/AST/DeclTemplate.h"
5353
#include "clang/AST/Expr.h"
5454
#include "clang/AST/ExprCXX.h"
55-
#include "clang/AST/Type.h"
5655
#include "clang/AST/TemplateBase.h"
57-
56+
#include "clang/AST/Type.h"
5857

5958
#include "clang/AST/ParentMap.h"
6059
#include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -1102,19 +1101,22 @@ class StopTrackingCallback final : public SymbolVisitor {
11021101
}
11031102
};
11041103

1105-
/// EscapeTrackedCallback - A SymbolVisitor that marks allocated symbols as escaped.
1104+
/// EscapeTrackedCallback - A SymbolVisitor that marks allocated symbols as
1105+
/// escaped.
11061106
///
1107-
/// This visitor is used to suppress false positive leak reports when smart pointers
1108-
/// are nested in temporary objects passed by value to functions. When the analyzer
1109-
/// can't see the destructor calls for temporary objects, it may incorrectly report
1110-
/// leaks for memory that will be properly freed by the smart pointer destructors.
1107+
/// This visitor is used to suppress false positive leak reports when smart
1108+
/// pointers are nested in temporary objects passed by value to functions. When
1109+
/// the analyzer can't see the destructor calls for temporary objects, it may
1110+
/// incorrectly report leaks for memory that will be properly freed by the smart
1111+
/// pointer destructors.
11111112
///
11121113
/// The visitor traverses reachable symbols from a given set of memory regions
11131114
/// (typically smart pointer field regions) and marks any allocated symbols as
11141115
/// escaped. Escaped symbols are not reported as leaks by checkDeadSymbols.
11151116
///
11161117
/// Usage:
1117-
/// auto Scan = State->scanReachableSymbols<EscapeTrackedCallback>(RootRegions);
1118+
/// auto Scan =
1119+
/// State->scanReachableSymbols<EscapeTrackedCallback>(RootRegions);
11181120
/// ProgramStateRef NewState = Scan.getState();
11191121
/// if (NewState != State) C.addTransition(NewState);
11201122
class EscapeTrackedCallback final : public SymbolVisitor {
@@ -3123,24 +3125,27 @@ static bool isInStdNamespace(const DeclContext *DC) {
31233125
// Start with unique_ptr and shared_ptr. (intentionally exclude weak_ptr)
31243126
static bool isSmartOwningPtrType(QualType QT) {
31253127
QT = canonicalStrip(QT);
3126-
3128+
31273129
// First try TemplateSpecializationType (for std smart pointers)
31283130
const auto *TST = QT->getAs<TemplateSpecializationType>();
31293131
if (TST) {
31303132
const TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
3131-
if (!TD) return false;
3132-
3133+
if (!TD)
3134+
return false;
3135+
31333136
const auto *ND = dyn_cast_or_null<NamedDecl>(TD->getTemplatedDecl());
3134-
if (!ND) return false;
3135-
3137+
if (!ND)
3138+
return false;
3139+
31363140
// Check if it's in std namespace
31373141
const DeclContext *DC = ND->getDeclContext();
3138-
if (!isInStdNamespace(DC)) return false;
3139-
3142+
if (!isInStdNamespace(DC))
3143+
return false;
3144+
31403145
StringRef Name = ND->getName();
31413146
return Name == "unique_ptr" || Name == "shared_ptr";
31423147
}
3143-
3148+
31443149
// Also try RecordType (for custom smart pointer implementations)
31453150
const auto *RT = QT->getAs<RecordType>();
31463151
if (RT) {
@@ -3153,17 +3158,18 @@ static bool isSmartOwningPtrType(QualType QT) {
31533158
}
31543159
}
31553160
}
3156-
3161+
31573162
return false;
31583163
}
31593164

3160-
static void collectDirectSmartOwningPtrFieldRegions(const MemRegion *Base,
3161-
QualType RecQT,
3162-
CheckerContext &C,
3163-
SmallVectorImpl<const MemRegion*> &Out) {
3164-
if (!Base) return;
3165+
static void collectDirectSmartOwningPtrFieldRegions(
3166+
const MemRegion *Base, QualType RecQT, CheckerContext &C,
3167+
SmallVectorImpl<const MemRegion *> &Out) {
3168+
if (!Base)
3169+
return;
31653170
const auto *CRD = RecQT->getAsCXXRecordDecl();
3166-
if (!CRD) return;
3171+
if (!CRD)
3172+
return;
31673173

31683174
for (const FieldDecl *FD : CRD->fields()) {
31693175
if (!isSmartOwningPtrType(FD->getType()))
@@ -3181,44 +3187,47 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
31813187
(*PostFN)(this, C.getState(), Call, C);
31823188
}
31833189

3184-
SmallVector<const MemRegion*, 8> SmartPtrFieldRoots;
3185-
3186-
3190+
SmallVector<const MemRegion *, 8> SmartPtrFieldRoots;
31873191

31883192
for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
31893193
const Expr *AE = Call.getArgExpr(I);
3190-
if (!AE) continue;
3194+
if (!AE)
3195+
continue;
31913196
AE = AE->IgnoreParenImpCasts();
31923197

31933198
QualType T = AE->getType();
31943199

3195-
// **Relaxation 1**: accept *any rvalue* by-value record (not only strict PRVALUE).
3196-
if (AE->isGLValue()) continue;
3200+
// **Relaxation 1**: accept *any rvalue* by-value record (not only strict
3201+
// PRVALUE).
3202+
if (AE->isGLValue())
3203+
continue;
31973204

31983205
// By-value record only (no refs).
3199-
if (!T->isRecordType() || T->isReferenceType()) continue;
3206+
if (!T->isRecordType() || T->isReferenceType())
3207+
continue;
32003208

32013209
// **Relaxation 2**: accept common temp/construct forms but don't overfit.
32023210
const bool LooksLikeTemp =
3203-
isa<CXXTemporaryObjectExpr>(AE) ||
3204-
isa<MaterializeTemporaryExpr>(AE) ||
3205-
isa<CXXConstructExpr>(AE) ||
3206-
isa<InitListExpr>(AE) ||
3207-
isa<ImplicitCastExpr>(AE) || // handle common rvalue materializations
3211+
isa<CXXTemporaryObjectExpr>(AE) || isa<MaterializeTemporaryExpr>(AE) ||
3212+
isa<CXXConstructExpr>(AE) || isa<InitListExpr>(AE) ||
3213+
isa<ImplicitCastExpr>(AE) || // handle common rvalue materializations
32083214
isa<CXXBindTemporaryExpr>(AE); // handle CXXBindTemporaryExpr
3209-
if (!LooksLikeTemp) continue;
3215+
if (!LooksLikeTemp)
3216+
continue;
32103217

32113218
// Require at least one direct smart owning pointer field by type.
32123219
const auto *CRD = T->getAsCXXRecordDecl();
3213-
if (!CRD) continue;
3220+
if (!CRD)
3221+
continue;
32143222
bool HasSmartPtrField = false;
32153223
for (const FieldDecl *FD : CRD->fields()) {
3216-
if (isSmartOwningPtrType(FD->getType())) {
3217-
HasSmartPtrField = true;
3218-
break;
3224+
if (isSmartOwningPtrType(FD->getType())) {
3225+
HasSmartPtrField = true;
3226+
break;
32193227
}
32203228
}
3221-
if (!HasSmartPtrField) continue;
3229+
if (!HasSmartPtrField)
3230+
continue;
32223231

32233232
// Find a region for the argument.
32243233
SVal VCall = Call.getArgSVal(I);
@@ -3227,20 +3236,21 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32273236
const MemRegion *RExpr = VExpr.getAsRegion();
32283237

32293238
const MemRegion *Base = RCall ? RCall : RExpr;
3230-
if (!Base) {
3231-
// Fallback: if we have a by-value record with unique_ptr fields but no region,
3232-
// mark all allocated symbols as escaped
3239+
if (!Base) {
3240+
// Fallback: if we have a by-value record with unique_ptr fields but no
3241+
// region, mark all allocated symbols as escaped
32333242
ProgramStateRef State = C.getState();
32343243
RegionStateTy RS = State->get<RegionState>();
32353244
ProgramStateRef NewState = State;
32363245
for (auto [Sym, RefSt] : RS) {
32373246
if (RefSt.isAllocated() || RefSt.isAllocatedOfSizeZero()) {
3238-
NewState = NewState->set<RegionState>(Sym, RefState::getEscaped(&RefSt));
3247+
NewState =
3248+
NewState->set<RegionState>(Sym, RefState::getEscaped(&RefSt));
32393249
}
32403250
}
32413251
if (NewState != State)
32423252
C.addTransition(NewState);
3243-
continue;
3253+
continue;
32443254
}
32453255

32463256
// Push direct smart owning pointer field regions only (precise root set).
@@ -3250,32 +3260,36 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32503260
// Escape only from those field roots; do nothing if empty.
32513261
if (!SmartPtrFieldRoots.empty()) {
32523262
ProgramStateRef State = C.getState();
3253-
auto Scan = State->scanReachableSymbols<EscapeTrackedCallback>(SmartPtrFieldRoots);
3263+
auto Scan =
3264+
State->scanReachableSymbols<EscapeTrackedCallback>(SmartPtrFieldRoots);
32543265
ProgramStateRef NewState = Scan.getState();
32553266
if (NewState != State) {
32563267
C.addTransition(NewState);
3257-
} else {
3258-
// Fallback: if we have by-value record arguments but no smart pointer fields detected,
3259-
// check if any of the arguments are by-value records with smart pointer fields
3268+
} else {
3269+
// Fallback: if we have by-value record arguments but no smart pointer
3270+
// fields detected, check if any of the arguments are by-value records
3271+
// with smart pointer fields
32603272
bool hasByValueRecordWithSmartPtr = false;
32613273
for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
32623274
const Expr *AE = Call.getArgExpr(I);
3263-
if (!AE) continue;
3275+
if (!AE)
3276+
continue;
32643277
AE = AE->IgnoreParenImpCasts();
3265-
3266-
if (AE->isGLValue()) continue;
3278+
3279+
if (AE->isGLValue())
3280+
continue;
32673281
QualType T = AE->getType();
3268-
if (!T->isRecordType() || T->isReferenceType()) continue;
3269-
3282+
if (!T->isRecordType() || T->isReferenceType())
3283+
continue;
3284+
32703285
const bool LooksLikeTemp =
32713286
isa<CXXTemporaryObjectExpr>(AE) ||
3272-
isa<MaterializeTemporaryExpr>(AE) ||
3273-
isa<CXXConstructExpr>(AE) ||
3274-
isa<InitListExpr>(AE) ||
3275-
isa<ImplicitCastExpr>(AE) ||
3287+
isa<MaterializeTemporaryExpr>(AE) || isa<CXXConstructExpr>(AE) ||
3288+
isa<InitListExpr>(AE) || isa<ImplicitCastExpr>(AE) ||
32763289
isa<CXXBindTemporaryExpr>(AE);
3277-
if (!LooksLikeTemp) continue;
3278-
3290+
if (!LooksLikeTemp)
3291+
continue;
3292+
32793293
// Check if this record type has smart pointer fields
32803294
const auto *CRD = T->getAsCXXRecordDecl();
32813295
if (CRD) {
@@ -3286,16 +3300,18 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32863300
}
32873301
}
32883302
}
3289-
if (hasByValueRecordWithSmartPtr) break;
3303+
if (hasByValueRecordWithSmartPtr)
3304+
break;
32903305
}
3291-
3306+
32923307
if (hasByValueRecordWithSmartPtr) {
32933308
ProgramStateRef State = C.getState();
32943309
RegionStateTy RS = State->get<RegionState>();
32953310
ProgramStateRef NewState = State;
32963311
for (auto [Sym, RefSt] : RS) {
32973312
if (RefSt.isAllocated() || RefSt.isAllocatedOfSizeZero()) {
3298-
NewState = NewState->set<RegionState>(Sym, RefState::getEscaped(&RefSt));
3313+
NewState =
3314+
NewState->set<RegionState>(Sym, RefState::getEscaped(&RefSt));
32993315
}
33003316
}
33013317
if (NewState != State)
@@ -3367,8 +3383,6 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
33673383
if (!FD)
33683384
return;
33693385

3370-
3371-
33723386
// FIXME: I suspect we should remove `MallocChecker.isEnabled() &&` because
33733387
// it's fishy that the enabled/disabled state of one frontend may influence
33743388
// reports produced by other frontends.

0 commit comments

Comments
 (0)