Skip to content

Commit 56bc0ba

Browse files
committed
Fix: Issue #165239 — resolve -Wuninitialized warnings
1 parent b838084 commit 56bc0ba

File tree

1 file changed

+120
-7
lines changed

1 file changed

+120
-7
lines changed

clang/lib/Analysis/UninitializedValues.cpp

Lines changed: 120 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,18 @@ static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
6262
QualType ty = vd->getType();
6363
if (const auto *RD = ty->getAsRecordDecl())
6464
return recordIsNotEmpty(RD);
65-
return ty->isScalarType() || ty->isVectorType() || ty->isRVVSizelessBuiltinType();
65+
66+
bool isArray = ty->isArrayType();
67+
bool result = ty->isScalarType() || ty->isVectorType() || ty->isRVVSizelessBuiltinType() || isArray;
68+
69+
// Debug output
70+
#if DEBUG_LOGGING
71+
llvm::errs() << "DEBUG isTrackedVar: " << vd->getNameAsString()
72+
<< " isArray=" << isArray
73+
<< " result=" << result << "\n";
74+
#endif
75+
76+
return result;
6677
}
6778
return false;
6879
}
@@ -187,8 +198,8 @@ void CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) {
187198
static void printVector(const CFGBlock *block, ValueVector &bv,
188199
unsigned num) {
189200
llvm::errs() << block->getBlockID() << " :";
190-
for (const auto &i : bv)
191-
llvm::errs() << ' ' << i;
201+
for (unsigned i = 0, e = bv.size(); i != e; ++i)
202+
llvm::errs() << ' ' << bv[i];
192203
llvm::errs() << " : " << num << '\n';
193204
}
194205
#endif
@@ -291,6 +302,7 @@ class ClassifyRefs : public StmtVisitor<ClassifyRefs> {
291302
public:
292303
ClassifyRefs(AnalysisDeclContext &AC) : DC(cast<DeclContext>(AC.getDecl())) {}
293304

305+
void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE);
294306
void VisitDeclStmt(DeclStmt *DS);
295307
void VisitUnaryOperator(UnaryOperator *UO);
296308
void VisitBinaryOperator(BinaryOperator *BO);
@@ -303,13 +315,19 @@ class ClassifyRefs : public StmtVisitor<ClassifyRefs> {
303315
Class get(const DeclRefExpr *DRE) const {
304316
llvm::DenseMap<const DeclRefExpr*, Class>::const_iterator I
305317
= Classification.find(DRE);
306-
if (I != Classification.end())
318+
if (I != Classification.end()) {
307319
return I->second;
320+
}
308321

309322
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
310323
if (!VD || !isTrackedVar(VD))
311324
return Ignore;
312325

326+
// Default to Use instead of Init for arrays - CRITICAL FIX
327+
if (VD->getType()->isArrayType()) {
328+
return Use;
329+
}
330+
313331
return Init;
314332
}
315333
};
@@ -331,6 +349,27 @@ static const DeclRefExpr *getSelfInitExpr(VarDecl *VD) {
331349
void ClassifyRefs::classify(const Expr *E, Class C) {
332350
// The result of a ?: could also be an lvalue.
333351
E = E->IgnoreParens();
352+
353+
// Handle array subscripts - THE KEY FIX
354+
if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
355+
// For ANY array subscript expression, the base array is being USED
356+
// This is the critical fix - don't check C, just mark as Use
357+
FindVarResult Var = findVar(ASE->getBase(), DC);
358+
if (const VarDecl *VD = Var.getDecl()) {
359+
if (VD->getType()->isArrayType()) {
360+
// Directly mark the array DeclRefExpr as Use
361+
if (const DeclRefExpr *DRE = Var.getDeclRefExpr()) {
362+
Classification[DRE] = Use;
363+
}
364+
}
365+
}
366+
367+
// Process base and index normally
368+
classify(ASE->getBase(), C);
369+
Visit(const_cast<Expr*>(ASE->getIdx()));
370+
return;
371+
}
372+
334373
if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
335374
classify(CO->getTrueExpr(), C);
336375
classify(CO->getFalseExpr(), C);
@@ -376,6 +415,18 @@ void ClassifyRefs::classify(const Expr *E, Class C) {
376415
}
377416
}
378417

418+
void ClassifyRefs::VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) {
419+
// Debug output
420+
#if DEBUG_LOGGING
421+
llvm::errs() << "DEBUG ClassifyRefs::VisitArraySubscriptExpr called\n";
422+
#endif
423+
424+
// For array subscript expressions, classify the base as a use
425+
classify(ASE->getBase(), Use);
426+
// Also visit the index expression
427+
Visit(ASE->getIdx());
428+
}
429+
379430
void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) {
380431
for (auto *DI : DS->decls()) {
381432
auto *VD = dyn_cast<VarDecl>(DI);
@@ -393,10 +444,27 @@ void ClassifyRefs::VisitBinaryOperator(BinaryOperator *BO) {
393444
// use.
394445
if (BO->isCompoundAssignmentOp())
395446
classify(BO->getLHS(), Use);
396-
else if (BO->getOpcode() == BO_Assign || BO->getOpcode() == BO_Comma)
397-
classify(BO->getLHS(), Ignore);
447+
else if (BO->getOpcode() == BO_Assign || BO->getOpcode() == BO_Comma) {
448+
// For array subscript expressions on LHS of assignment, don't classify as use
449+
if (isa<ArraySubscriptExpr>(BO->getLHS())) {
450+
// Don't classify array base as use when it's being assigned to
451+
// But we still need to visit the index expression
452+
if (auto *ASE = dyn_cast<ArraySubscriptExpr>(BO->getLHS())) {
453+
Visit(ASE->getIdx());
454+
}
455+
} else {
456+
classify(BO->getLHS(), Ignore);
457+
}
458+
// ALWAYS visit the right-hand side - this is crucial for array subscripts
459+
Visit(BO->getRHS());
460+
} else {
461+
// For all other binary operators, visit both operands normally
462+
Visit(BO->getLHS());
463+
Visit(BO->getRHS());
464+
}
398465
}
399466

467+
400468
void ClassifyRefs::VisitUnaryOperator(UnaryOperator *UO) {
401469
// Increment and decrement are uses despite there being no lvalue-to-rvalue
402470
// conversion.
@@ -491,6 +559,7 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
491559
void reportConstRefUse(const Expr *ex, const VarDecl *vd);
492560
void reportConstPtrUse(const Expr *ex, const VarDecl *vd);
493561

562+
void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE);
494563
void VisitBinaryOperator(BinaryOperator *bo);
495564
void VisitBlockExpr(BlockExpr *be);
496565
void VisitCallExpr(CallExpr *ce);
@@ -661,10 +730,54 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
661730

662731
} // namespace
663732

733+
void TransferFunctions::VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) {
734+
// Debug output
735+
#if DEBUG_LOGGING
736+
llvm::errs() << "DEBUG TransferFunctions::VisitArraySubscriptExpr called\n";
737+
#endif
738+
739+
// Handle array subscript expressions like arr[i]
740+
// Check if the base array variable is uninitialized
741+
FindVarResult Var = findVar(ASE->getBase());
742+
743+
#if DEBUG_LOGGING
744+
llvm::errs() << "DEBUG: FindVar result: " << (Var.getDecl() ? "found" : "not found") << "\n";
745+
if (Var.getDecl()) {
746+
llvm::errs() << "DEBUG: Variable name: " << Var.getDecl()->getNameAsString() << "\n";
747+
llvm::errs() << "DEBUG: Is array type: " << Var.getDecl()->getType()->isArrayType() << "\n";
748+
}
749+
#endif
750+
751+
if (const VarDecl *VD = Var.getDecl()) {
752+
if (VD->getType()->isArrayType()) {
753+
#if DEBUG_LOGGING
754+
llvm::errs() << "DEBUG: Reporting array use for " << VD->getNameAsString() << "\n";
755+
#endif
756+
reportUse(ASE, VD);
757+
}
758+
}
759+
760+
// Also visit index expression
761+
Visit(ASE->getIdx());
762+
}
763+
664764
void TransferFunctions::reportUse(const Expr *ex, const VarDecl *vd) {
765+
#if DEBUG_LOGGING
766+
llvm::errs() << "DEBUG TransferFunctions::reportUse for " << vd->getNameAsString() << "\n";
767+
#endif
768+
665769
Value v = vals[vd];
666-
if (isUninitialized(v))
770+
771+
#if DEBUG_LOGGING
772+
llvm::errs() << "DEBUG: Variable " << vd->getNameAsString() << " has value " << v << "\n";
773+
#endif
774+
775+
if (isUninitialized(v)) {
776+
#if DEBUG_LOGGING
777+
llvm::errs() << "DEBUG: Reporting uninitialized use of " << vd->getNameAsString() << "\n";
778+
#endif
667779
handler.handleUseOfUninitVariable(vd, getUninitUse(ex, vd, v));
780+
}
668781
}
669782

670783
void TransferFunctions::reportConstRefUse(const Expr *ex, const VarDecl *vd) {

0 commit comments

Comments
 (0)