https://github.com/jimmy2683 updated 
https://github.com/llvm/llvm-project/pull/166991

>From 593fc1b368be26538fe65f650d0074139a683a85 Mon Sep 17 00:00:00 2001
From: jimmy2683 <[email protected]>
Date: Fri, 7 Nov 2025 23:58:13 +0530
Subject: [PATCH] =?UTF-8?q?Fix:=20Issue=20#165239=20=E2=80=94=20resolve=20?=
 =?UTF-8?q?-Wuninitialized=20warnings?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 clang/docs/ReleaseNotes.rst                |  7 ++
 clang/lib/Analysis/UninitializedValues.cpp | 75 ++++++++++++++++++++--
 clang/test/Sema/uninit-arrays.c            | 17 +++++
 3 files changed, 94 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Sema/uninit-arrays.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3a4e1fce2511e..931d01ef97ebc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -414,6 +414,13 @@ Improvements to Clang's diagnostics
 - Clang now emits a diagnostic in case `vector_size` or `ext_vector_type`
   attributes are used with a negative size (#GH165463).
 
+- Fixed: ``-Wuninitialized`` now emits a warning for uninitialized fixed-size 
local arrays. For example:
+
+  .. code-block:: c
+
+     int arr[4];
+     int x = arr[2]; // warning: variable 'arr' is uninitialized when used 
here (#GH165239)
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/lib/Analysis/UninitializedValues.cpp 
b/clang/lib/Analysis/UninitializedValues.cpp
index f6b1c67ab20c3..1d14a64e48ef5 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/lib/Analysis/UninitializedValues.cpp
@@ -61,8 +61,8 @@ static bool isTrackedVar(const VarDecl *vd, const DeclContext 
*dc) {
       vd->getDeclContext() == dc) {
     QualType ty = vd->getType();
     if (const auto *RD = ty->getAsRecordDecl())
-      return recordIsNotEmpty(RD);
-    return ty->isScalarType() || ty->isVectorType() || 
ty->isRVVSizelessBuiltinType();
+      return recordIsNotEmpty(RD);    
+    return ty->isScalarType() || ty->isVectorType() || 
ty->isRVVSizelessBuiltinType() || ty->isArrayType();
   }
   return false;
 }
@@ -291,6 +291,7 @@ class ClassifyRefs : public StmtVisitor<ClassifyRefs> {
 public:
   ClassifyRefs(AnalysisDeclContext &AC) : DC(cast<DeclContext>(AC.getDecl())) 
{}
 
+  void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE);
   void VisitDeclStmt(DeclStmt *DS);
   void VisitUnaryOperator(UnaryOperator *UO);
   void VisitBinaryOperator(BinaryOperator *BO);
@@ -310,6 +311,10 @@ class ClassifyRefs : public StmtVisitor<ClassifyRefs> {
     if (!VD || !isTrackedVar(VD))
       return Ignore;
 
+    // Default to Use instead of Init for arrays - CRITICAL FIX
+    if (VD->getType()->isArrayType())
+      return Use;
+
     return Init;
   }
 };
@@ -331,6 +336,26 @@ static const DeclRefExpr *getSelfInitExpr(VarDecl *VD) {
 void ClassifyRefs::classify(const Expr *E, Class C) {
   // The result of a ?: could also be an lvalue.
   E = E->IgnoreParens();
+  
+  // Handle array subscripts - THE KEY FIX
+  if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
+    // For ANY array subscript expression, the base array is being USED
+    // This is the critical fix - don't check C, just mark as Use
+    FindVarResult Var = findVar(ASE->getBase(), DC);
+    if (const VarDecl *VD = Var.getDecl()) {
+      if (VD->getType()->isArrayType()) {
+        // Directly mark the array DeclRefExpr as Use
+        if (const DeclRefExpr *DRE = Var.getDeclRefExpr())
+          Classification[DRE] = Use;
+      }
+    }
+    
+    // Process base and index normally
+    classify(ASE->getBase(), C);
+    Visit(const_cast<Expr*>(ASE->getIdx()));
+    return;
+  }
+  
   if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
     classify(CO->getTrueExpr(), C);
     classify(CO->getFalseExpr(), C);
@@ -376,6 +401,13 @@ void ClassifyRefs::classify(const Expr *E, Class C) {
   }
 }
 
+void ClassifyRefs::VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) {
+  // For array subscript expressions, classify the base as a use
+  classify(ASE->getBase(), Use);
+  // Also visit the index expression
+  Visit(ASE->getIdx());
+}
+
 void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) {
   for (auto *DI : DS->decls()) {
     auto *VD = dyn_cast<VarDecl>(DI);
@@ -393,10 +425,27 @@ void ClassifyRefs::VisitBinaryOperator(BinaryOperator 
*BO) {
   // use.
   if (BO->isCompoundAssignmentOp())
     classify(BO->getLHS(), Use);
-  else if (BO->getOpcode() == BO_Assign || BO->getOpcode() == BO_Comma)
-    classify(BO->getLHS(), Ignore);
+  else if (BO->getOpcode() == BO_Assign || BO->getOpcode() == BO_Comma) {
+    // For array subscript expressions on LHS of assignment, don't classify as 
use
+    if (isa<ArraySubscriptExpr>(BO->getLHS())) {
+      // Don't classify array base as use when it's being assigned to
+      // But we still need to visit the index expression
+      if (auto *ASE = dyn_cast<ArraySubscriptExpr>(BO->getLHS())) {
+        Visit(ASE->getIdx());
+      }
+    } else {
+      classify(BO->getLHS(), Ignore);
+    }
+    // ALWAYS visit the right-hand side - this is crucial for array subscripts
+    Visit(BO->getRHS());
+  } else {
+    // For all other binary operators, visit both operands normally
+    Visit(BO->getLHS());
+    Visit(BO->getRHS());
+  }
 }
 
+
 void ClassifyRefs::VisitUnaryOperator(UnaryOperator *UO) {
   // Increment and decrement are uses despite there being no lvalue-to-rvalue
   // conversion.
@@ -491,6 +540,7 @@ class TransferFunctions : public 
StmtVisitor<TransferFunctions> {
   void reportConstRefUse(const Expr *ex, const VarDecl *vd);
   void reportConstPtrUse(const Expr *ex, const VarDecl *vd);
 
+  void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE);
   void VisitBinaryOperator(BinaryOperator *bo);
   void VisitBlockExpr(BlockExpr *be);
   void VisitCallExpr(CallExpr *ce);
@@ -661,8 +711,23 @@ class TransferFunctions : public 
StmtVisitor<TransferFunctions> {
 
 } // namespace
 
-void TransferFunctions::reportUse(const Expr *ex, const VarDecl *vd) {
+void TransferFunctions::VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) {  
+  // Handle array subscript expressions like arr[i]
+  // Check if the base array variable is uninitialized
+  FindVarResult Var = findVar(ASE->getBase());
+  
+  if (const VarDecl *VD = Var.getDecl()) {
+    if (VD->getType()->isArrayType())
+      reportUse(ASE, VD);
+  }
+  
+  // Also visit index expression
+  Visit(ASE->getIdx());
+}
+
+void TransferFunctions::reportUse(const Expr *ex, const VarDecl *vd) {  
   Value v = vals[vd];
+  
   if (isUninitialized(v))
     handler.handleUseOfUninitVariable(vd, getUninitUse(ex, vd, v));
 }
diff --git a/clang/test/Sema/uninit-arrays.c b/clang/test/Sema/uninit-arrays.c
new file mode 100644
index 0000000000000..fb3a31c225a5b
--- /dev/null
+++ b/clang/test/Sema/uninit-arrays.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -Wall -Wextra -Wuninitialized -fsyntax-only %s 2>&1 | 
FileCheck %s
+
+void test1() {
+  int arr[5];
+  int x = arr[0]; // expected-warning{{variable 'arr' is uninitialized when 
used here}}
+}
+
+void test2() {
+  int a[3][3];
+  int y = a[1][1]; // expected-warning{{variable 'a' is uninitialized when 
used here}}
+}
+
+void test3() {
+  int n;
+  int vla[n]; // expected-note{{declared here}}
+  int z = vla[2]; // expected-warning{{variable 'vla' is uninitialized when 
used here}}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to