Sinitax created this revision.
Sinitax added a project: clang.
Herald added a project: All.
Sinitax requested review of this revision.
Herald added a subscriber: cfe-commits.

This patch implements a warning for uninitialized elements in fixed-size arrays.

Without warnings a 'gap' in an array can go unnoticed when the size increases. 
Consider what happens with the array `const char *err_msg[ERR_TYPE_COUNT]` when 
a new `ERR_..` enum value is added.

Note: There is most likely a better way of doing this (first encounter with 
llvm internals), but I hope it will get some eyes on the problem such that it 
can be merged soon-ish.

Related: https://github.com/llvm/llvm-project/issues/22692


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152083

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaInit.cpp


Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -980,6 +980,22 @@
     if (RequiresSecondPass && !hadError)
       FillInEmptyInitializations(Entity, FullyStructuredList,
                                  RequiresSecondPass, nullptr, 0);
+
+    if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(T)) {
+      if (FullyStructuredList->getNumInits() < 
CAType->getSize().getZExtValue()) {
+        S.Diag(IL->getBeginLoc(), diag::warn_uninit_fixed_size_array)
+          << IL->getSourceRange();
+      } else {
+        Expr **inits = FullyStructuredList->getInits();
+        for (unsigned i = 0, e = FullyStructuredList->getNumInits(); i != e; 
++i) {
+          if (inits[i] == nullptr) {
+            S.Diag(IL->getBeginLoc(), diag::warn_uninit_fixed_size_array)
+              << IL->getSourceRange();
+            break;
+          }
+        }
+      }
+    }
   }
   if (hadError && FullyStructuredList)
     FullyStructuredList->markError();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2214,6 +2214,9 @@
   "reference %0 is not yet bound to a value when used within its own"
   " initialization">,
   InGroup<Uninitialized>;
+def warn_uninit_fixed_size_array : Warning<
+  "fixed-size array contains uninitialized elements">,
+  InGroup<Uninitialized>, DefaultIgnore;
 def warn_uninit_var : Warning<
   "variable %0 is uninitialized when %select{used here|captured by block}1">,
   InGroup<Uninitialized>, DefaultIgnore;


Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -980,6 +980,22 @@
     if (RequiresSecondPass && !hadError)
       FillInEmptyInitializations(Entity, FullyStructuredList,
                                  RequiresSecondPass, nullptr, 0);
+
+    if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(T)) {
+      if (FullyStructuredList->getNumInits() < CAType->getSize().getZExtValue()) {
+        S.Diag(IL->getBeginLoc(), diag::warn_uninit_fixed_size_array)
+          << IL->getSourceRange();
+      } else {
+        Expr **inits = FullyStructuredList->getInits();
+        for (unsigned i = 0, e = FullyStructuredList->getNumInits(); i != e; ++i) {
+          if (inits[i] == nullptr) {
+            S.Diag(IL->getBeginLoc(), diag::warn_uninit_fixed_size_array)
+              << IL->getSourceRange();
+            break;
+          }
+        }
+      }
+    }
   }
   if (hadError && FullyStructuredList)
     FullyStructuredList->markError();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2214,6 +2214,9 @@
   "reference %0 is not yet bound to a value when used within its own"
   " initialization">,
   InGroup<Uninitialized>;
+def warn_uninit_fixed_size_array : Warning<
+  "fixed-size array contains uninitialized elements">,
+  InGroup<Uninitialized>, DefaultIgnore;
 def warn_uninit_var : Warning<
   "variable %0 is uninitialized when %select{used here|captured by block}1">,
   InGroup<Uninitialized>, DefaultIgnore;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to