[clang] 58936cb - [Clang] Diagnose require_explicit_initialization for C tentative definitions (#234210)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 22 08:06:48 PDT 2026
Author: Pathri Vidya Praveen
Date: 2026-10-22T15:06:40Z
New Revision: 58936cb3678b4b5b96177f24cac3940b9a389fe3
URL: https://github.com/llvm/llvm-project/commit/58936cb3678b4b5b96177f24cac3940b9a389fe3
DIFF: https://github.com/llvm/llvm-project/commit/58936cb3678b4b5b96177f24cac3940b9a389fe3.diff
LOG: [Clang] Diagnose require_explicit_initialization for C tentative definitions (#234210)
In C, a tentative definition that is never completed is zero-initialized
(C17 6.9.2p2). However, `-Wuninitialized-explicit-init` did not diagnose
such definitions when they contained fields marked
`require_explicit_initialization`.
This patch adds a check in `Sema::ActOnEndOfTranslationUnit()` for
tentative definitions that remain uncompleted. Definitions completed
later retain their existing initialization checks.
Added regression tests in
`clang/test/Sema/attr-require-explicit-init-tentative.c`.
Fixes #232483
AI assistance: Claude was used to understand parts of the existing code
and assist with regression-test development, including some
`expected-warning` annotations. I reviewed and verified the submitted
changes.
Added:
clang/test/Sema/attr-require-explicit-init-tentative.c
Modified:
clang/docs/ReleaseNotes.md
clang/lib/Sema/Sema.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 1620cef23970e..04a672f77c1a6 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -458,6 +458,10 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and
### Improvements to Clang's diagnostics
+- Fixed missing `-Wuninitialized-explicit-init` warnings for C file-scope
+ tentative definitions of structure types which contain a field marked with
+ the `require_explicit_initialization` attribute. (#GH232483)
+
- Fixed spurious `-Wimplicit-void-ptr-cast` warnings in C for parenthesized
null pointer macros such as `(NULL)`. (#GH171874)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 9abab22e3809f..b121f17b96a28 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1550,6 +1550,20 @@ void Sema::ActOnEndOfTranslationUnit() {
Diag(VD->getLocation(), DiagID) << Type << EmitCppCompat;
}
+ // Uninitialized tentative definitions are zero-initialized (C17 6.9.2p2) so
+ // diagnose fields requiring explicit initialization.
+ if (!VD->isInvalidDecl() && !getLangOpts().CPlusPlus &&
+ !VD->getAnyInitializer()) {
+ if (const RecordDecl *RD = Type->getAsRecordDecl();
+ RD && RD->hasUninitializedExplicitInitFields()) {
+ Diag(VD->getLocation(), diag::warn_field_requires_explicit_init)
+ << /*Var-in-Record=*/1 << RD;
+ for (const FieldDecl *FD : RD->fields())
+ if (FD->hasAttr<ExplicitInitAttr>())
+ Diag(FD->getLocation(), diag::note_entity_declared_at) << FD;
+ }
+ }
+
// Notify the consumer that we've completed a tentative definition.
if (!VD->isInvalidDecl())
Consumer.CompleteTentativeDefinition(VD);
diff --git a/clang/test/Sema/attr-require-explicit-init-tentative.c b/clang/test/Sema/attr-require-explicit-init-tentative.c
new file mode 100644
index 0000000000000..4f1ec95c2f350
--- /dev/null
+++ b/clang/test/Sema/attr-require-explicit-init-tentative.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized-explicit-init -verify %s
+
+struct ops {
+ int (*show)(void) __attribute__((require_explicit_initialization)); // #SHOW
+ int flags;
+};
+
+struct plain {
+ int a;
+};
+
+struct plain no_attribute; // no warning: no field requires explicit initialization
+
+struct ops never_initialized; // expected-warning {{field in 'ops' requires explicit initialization but is not explicitly initialized}} expected-note@#SHOW {{'show' declared here}}
+static struct ops never_initialized_static; // expected-warning {{field in 'ops' requires explicit initialization but is not explicitly initialized}} expected-note@#SHOW {{'show' declared here}}
+
+struct ops repeated;
+struct ops repeated; // expected-warning {{field in 'ops' requires explicit initialization but is not explicitly initialized}} expected-note@#SHOW {{'show' declared here}}
+
+struct ops initialized_later;
+struct ops initialized_later = { .flags=1}; // expected-warning {{field 'show' requires explicit initialization but is not explicitly initialized}} expected-note@#SHOW {{'show' declared here}}
+
+struct ops initialized_ok;
+struct ops initialized_ok = { .show=0};
+
+extern struct ops ext;
+
+struct late g_late; // expected-warning {{field in 'late' requires explicit initialization but is not explicitly initialized}} expected-note@#LATE_X {{'x' declared here}}
+struct late {
+ int x __attribute__((require_explicit_initialization)); // #LATE_X
+};
+
+void f(void){
+ static struct ops local_static; // expected-warning {{field in 'ops' requires explicit initialization but is not explicitly initialized}} expected-note@#SHOW {{'show' declared here}}
+ (void)&local_static;
+}
More information about the cfe-commits
mailing list