[clang] a635bbf - [C] Update the -Wdefault-const-init-unsafe wording (#138266)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 2 09:23:43 PDT 2025
Author: Aaron Ballman
Date: 2025-05-02T12:23:40-04:00
New Revision: a635bbf1418e351651ed86230eab3d13f871f971
URL: https://github.com/llvm/llvm-project/commit/a635bbf1418e351651ed86230eab3d13f871f971
DIFF: https://github.com/llvm/llvm-project/commit/a635bbf1418e351651ed86230eab3d13f871f971.diff
LOG: [C] Update the -Wdefault-const-init-unsafe wording (#138266)
This drops the "and is incompatible with C++" phrasing from the
diagnostic unless -Wc++-compat is explicitly passed. This makes the
diagnostic less confusing when it is on by default rather than enabled
because of C++ compatibility concerns
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaInit.cpp
clang/test/Sema/sizeless-1.c
clang/test/Sema/typedef-retain.c
clang/test/Sema/warn-default-const-init.c
clang/test/SemaOpenCL/invalid-block.cl
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ccb14e9927adf..060ad6085e510 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6541,6 +6541,16 @@ def warn_missing_braces : Warning<
"suggest braces around initialization of subobject">,
InGroup<MissingBraces>, DefaultIgnore;
+// This diagnostic exists only to determine whether -Wc++-compat was explicitly
+// enabled. This allows us to tell the
diff erence between when a diagnostic was
+// enabled by default, was enabled because its subgroup was enabled, or enabled
+// because the -Wc++-compat superset was enabled, generally for purposes of
+// deciding whether to emit "and is incompatible with C++" on diagnostics which
+// are useful in C alone as well as for compatibility checks.
+def warn_cxx_compat_hack_fake_diagnostic_do_not_emit : Warning<
+ "if you see this diagnostic, a Clang developer has made a mistake">,
+ InGroup<CXXCompat>, DefaultIgnore;
+
def err_redefinition_of_label : Error<"redefinition of label %0">;
def err_undeclared_label_use : Error<"use of undeclared label %0">;
def err_goto_ms_asm_label : Error<
@@ -8244,11 +8254,11 @@ def warn_default_init_const : Warning<
InGroup<DefaultConstInitVar>, DefaultIgnore;
def warn_default_init_const_field_unsafe : Warning<
"default initialization of an object of type %0 with const member leaves the "
- "object uninitialized and is incompatible with C++">,
+ "object uninitialized%select{| and is incompatible with C++}1">,
InGroup<DefaultConstInitFieldUnsafe>;
def warn_default_init_const_unsafe : Warning<
"default initialization of an object of type %0 leaves the object "
- "uninitialized and is incompatible with C++">,
+ "uninitialized%select{| and is incompatible with C++}1">,
InGroup<DefaultConstInitVarUnsafe>;
def err_default_init_const : Error<
"default initialization of an object of const type %0"
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index b9d33d67ca7e4..1901d19b14dfc 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1457,7 +1457,12 @@ void Sema::ActOnEndOfTranslationUnit() {
if (VD->getStorageDuration() == SD_Static ||
VD->getStorageDuration() == SD_Thread)
DiagID = diag::warn_default_init_const;
- Diag(VD->getLocation(), DiagID) << Type;
+
+ bool EmitCppCompat = !Diags.isIgnored(
+ diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
+ VD->getLocation());
+
+ Diag(VD->getLocation(), DiagID) << Type << EmitCppCompat;
}
// Notify the consumer that we've completed a tentative definition.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 50139625b7897..67ff3f055ca5a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14369,7 +14369,12 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
if (Var->getStorageDuration() == SD_Static ||
Var->getStorageDuration() == SD_Thread)
DiagID = diag::warn_default_init_const;
- Diag(Var->getLocation(), DiagID) << Type;
+
+ bool EmitCppCompat = !Diags.isIgnored(
+ diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
+ Var->getLocation());
+
+ Diag(Var->getLocation(), DiagID) << Type << EmitCppCompat;
}
// Check for jumps past the implicit initializer. C++0x
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 3e29a5bf96a0c..160fbddbdff15 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6627,7 +6627,11 @@ void InitializationSequence::InitializeFrom(Sema &S,
Var->getStorageDuration() == SD_Thread)
DiagID = diag::warn_default_init_const_field;
- S.Diag(Var->getLocation(), DiagID) << Var->getType();
+ bool EmitCppCompat = !S.Diags.isIgnored(
+ diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
+ Var->getLocation());
+
+ S.Diag(Var->getLocation(), DiagID) << Var->getType() << EmitCppCompat;
S.Diag(FD->getLocation(), diag::note_default_init_const_member) << FD;
}
}
diff --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c
index af96023f4bff5..b6b92e7a68c19 100644
--- a/clang/test/Sema/sizeless-1.c
+++ b/clang/test/Sema/sizeless-1.c
@@ -94,12 +94,12 @@ void func(int sel) {
svint8_t bad_brace_init_int8_6 = {{local_int8, 0}}; // expected-warning {{too many braces around initializer}}
const svint8_t const_int8 = local_int8; // expected-note {{declared const here}}
- const svint8_t uninit_const_int8; // expected-warning {{default initialization of an object of type 'const svint8_t' (aka 'const __SVInt8_t') leaves the object uninitialized and is incompatible with C++}};
+ const svint8_t uninit_const_int8; // expected-warning {{default initialization of an object of type 'const svint8_t' (aka 'const __SVInt8_t') leaves the object uninitialized}};
volatile svint8_t volatile_int8;
const volatile svint8_t const_volatile_int8 = local_int8; // expected-note {{declared const here}}
- const volatile svint8_t uninit_const_volatile_int8; // expected-warning {{default initialization of an object of type 'const volatile svint8_t' (aka 'const volatile __SVInt8_t') leaves the object uninitialized and is incompatible with C++}}
+ const volatile svint8_t uninit_const_volatile_int8; // expected-warning {{default initialization of an object of type 'const volatile svint8_t' (aka 'const volatile __SVInt8_t') leaves the object uninitialized}}
_Atomic svint8_t atomic_int8; // expected-error {{_Atomic cannot be applied to sizeless type 'svint8_t'}}
__restrict svint8_t restrict_int8; // expected-error {{requires a pointer or reference}}
diff --git a/clang/test/Sema/typedef-retain.c b/clang/test/Sema/typedef-retain.c
index 76715ca360cbe..71375ad7a8127 100644
--- a/clang/test/Sema/typedef-retain.c
+++ b/clang/test/Sema/typedef-retain.c
@@ -17,7 +17,7 @@ typedef int a[5];
void test3(void) {
typedef const a b;
b r; // expected-note {{variable 'r' declared const here}} \
- expected-warning {{default initialization of an object of type 'b' (aka 'const int[5]') leaves the object uninitialized and is incompatible with C++}}
+ expected-warning {{default initialization of an object of type 'b' (aka 'const int[5]') leaves the object uninitialized}}
r[0] = 10; // expected-error {{cannot assign to variable 'r' with const-qualified type 'b' (aka 'const int[5]')}}
}
diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c
index ddd4aba2b5de3..e788d72899685 100644
--- a/clang/test/Sema/warn-default-const-init.c
+++ b/clang/test/Sema/warn-default-const-init.c
@@ -1,5 +1,5 @@
// Both of these should enable everything.
-// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field,zero-init-var,zero-init-field -Wc++-compat -Wno-tentative-definition-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var-compat,unsafe-field-compat,zero-init-var,zero-init-field -Wc++-compat -Wno-tentative-definition-compat %s
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field,zero-init-var,zero-init-field -Wdefault-const-init %s
// This should enable nothing.
@@ -25,21 +25,26 @@
struct A { int i; };
struct S{ const int i; }; // unsafe-field-note 2 {{member 'i' declared 'const' here}} \
+ unsafe-field-compat-note 2 {{member 'i' declared 'const' here}} \
cxx-note 3 {{default constructor of 'S' is implicitly deleted because field 'i' of const-qualified type 'const int' would not be initialized}}
struct T { struct S s; }; // cxx-note {{default constructor of 'T' is implicitly deleted because field 's' has a deleted default constructor}}
struct U { struct S s; const int j; };
struct V { int i; const struct A a; }; // unsafe-field-note {{member 'a' declared 'const' here}} \
+ unsafe-field-compat-note {{member 'a' declared 'const' here}} \
cxx-note {{default constructor of 'V' is implicitly deleted because field 'a' of const-qualified type 'const struct A' would not be initialized}}
struct W { struct A a; const int j; }; // unsafe-field-note {{member 'j' declared 'const' here}} \
+ unsafe-field-compat-note {{member 'j' declared 'const' here}} \
cxx-note {{default constructor of 'W' is implicitly deleted because field 'j' of const-qualified type 'const int' would not be initialized}}
void f() {
- struct S s1; // unsafe-field-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized and is incompatible with C++}} \
+ struct S s1; // unsafe-field-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized}} \
+ unsafe-field-compat-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized and is incompatible with C++}} \
cxx-error {{call to implicitly-deleted default constructor of 'struct S'}}
struct S s2 = { 0 };
}
void g() {
- struct T t1; // unsafe-field-warning {{default initialization of an object of type 'struct T' with const member leaves the object uninitialized and is incompatible with C++}} \
+ struct T t1; // unsafe-field-warning {{default initialization of an object of type 'struct T' with const member leaves the object uninitialized}} \
+ unsafe-field-compat-warning {{default initialization of an object of type 'struct T' with const member leaves the object uninitialized and is incompatible with C++}} \
cxx-error {{call to implicitly-deleted default constructor of 'struct T'}}
struct T t2 = { { 0 } };
}
@@ -48,13 +53,15 @@ void h() {
struct U u2 = { { 0 }, 0 };
}
void x() {
- struct V v1; // unsafe-field-warning {{default initialization of an object of type 'struct V' with const member leaves the object uninitialized and is incompatible with C++}} \
+ struct V v1; // unsafe-field-warning {{default initialization of an object of type 'struct V' with const member leaves the object uninitialized}} \
+ unsafe-field-compat-warning {{default initialization of an object of type 'struct V' with const member leaves the object uninitialized and is incompatible with C++}} \
cxx-error {{call to implicitly-deleted default constructor of 'struct V'}}
struct V v2 = { 0 };
struct V v3 = { 0, { 0 } };
}
void y() {
- struct W w1; // unsafe-field-warning {{default initialization of an object of type 'struct W' with const member leaves the object uninitialized and is incompatible with C++}} \
+ struct W w1; // unsafe-field-warning {{default initialization of an object of type 'struct W' with const member leaves the object uninitialized}} \
+ unsafe-field-compat-warning {{default initialization of an object of type 'struct W' with const member leaves the object uninitialized and is incompatible with C++}} \
cxx-error {{call to implicitly-deleted default constructor of 'struct W'}}
struct W w2 = { 0 };
struct W w3 = { { 0 }, 0 };
@@ -72,9 +79,9 @@ const struct S s; // zero-init-var-warning {{default initialization of an obje
cxx-error {{call to implicitly-deleted default constructor of 'const struct S'}}
void func() {
- const int a; // unsafe-var-warning {{default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++}} \
+ const int a; // unsafe-var-warning {{default initialization of an object of type 'const int' leaves the object uninitialized}} \
+ unsafe-var-compat-warning {{default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++}} \
cxx-error {{default initialization of an object of const type 'const int'}}
static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
cxx-error {{default initialization of an object of const type 'const int'}}
}
-
diff --git a/clang/test/SemaOpenCL/invalid-block.cl b/clang/test/SemaOpenCL/invalid-block.cl
index 2214908f800a4..985b0447d036f 100644
--- a/clang/test/SemaOpenCL/invalid-block.cl
+++ b/clang/test/SemaOpenCL/invalid-block.cl
@@ -14,7 +14,7 @@ void f1(void) {
f0(bl2);
bl1 = bl2; // expected-error{{invalid operands to binary expression ('int (__generic ^const __private)(void)' and 'int (__generic ^const __private)(void)')}}
int (^const bl3)(void); // expected-error{{invalid block variable declaration - must be initialized}} \
- expected-warning {{default initialization of an object of type 'int (__generic ^const __private)(void)' leaves the object uninitialized and is incompatible with C++}}
+ expected-warning {{default initialization of an object of type 'int (__generic ^const __private)(void)' leaves the object uninitialized}}
}
// A block with extern storage class is not allowed.
More information about the cfe-commits
mailing list