@@ -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) {
187198static 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> {
291302public:
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) {
331349void 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+
379430void 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+
400468void 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+
664764void 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
670783void TransferFunctions::reportConstRefUse (const Expr *ex, const VarDecl *vd) {
0 commit comments