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