Skip to content

Commit 1b43220

Browse files
AaronBallmanIanWood1
authored andcommitted
[C] Update the -Wdefault-const-init-unsafe wording (llvm#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
1 parent 7c02f8c commit 1b43220

File tree

8 files changed

+47
-16
lines changed

8 files changed

+47
-16
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6541,6 +6541,16 @@ def warn_missing_braces : Warning<
65416541
"suggest braces around initialization of subobject">,
65426542
InGroup<MissingBraces>, DefaultIgnore;
65436543

6544+
// This diagnostic exists only to determine whether -Wc++-compat was explicitly
6545+
// enabled. This allows us to tell the difference between when a diagnostic was
6546+
// enabled by default, was enabled because its subgroup was enabled, or enabled
6547+
// because the -Wc++-compat superset was enabled, generally for purposes of
6548+
// deciding whether to emit "and is incompatible with C++" on diagnostics which
6549+
// are useful in C alone as well as for compatibility checks.
6550+
def warn_cxx_compat_hack_fake_diagnostic_do_not_emit : Warning<
6551+
"if you see this diagnostic, a Clang developer has made a mistake">,
6552+
InGroup<CXXCompat>, DefaultIgnore;
6553+
65446554
def err_redefinition_of_label : Error<"redefinition of label %0">;
65456555
def err_undeclared_label_use : Error<"use of undeclared label %0">;
65466556
def err_goto_ms_asm_label : Error<
@@ -8244,11 +8254,11 @@ def warn_default_init_const : Warning<
82448254
InGroup<DefaultConstInitVar>, DefaultIgnore;
82458255
def warn_default_init_const_field_unsafe : Warning<
82468256
"default initialization of an object of type %0 with const member leaves the "
8247-
"object uninitialized and is incompatible with C++">,
8257+
"object uninitialized%select{| and is incompatible with C++}1">,
82488258
InGroup<DefaultConstInitFieldUnsafe>;
82498259
def warn_default_init_const_unsafe : Warning<
82508260
"default initialization of an object of type %0 leaves the object "
8251-
"uninitialized and is incompatible with C++">,
8261+
"uninitialized%select{| and is incompatible with C++}1">,
82528262
InGroup<DefaultConstInitVarUnsafe>;
82538263
def err_default_init_const : Error<
82548264
"default initialization of an object of const type %0"

clang/lib/Sema/Sema.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,12 @@ void Sema::ActOnEndOfTranslationUnit() {
14571457
if (VD->getStorageDuration() == SD_Static ||
14581458
VD->getStorageDuration() == SD_Thread)
14591459
DiagID = diag::warn_default_init_const;
1460-
Diag(VD->getLocation(), DiagID) << Type;
1460+
1461+
bool EmitCppCompat = !Diags.isIgnored(
1462+
diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
1463+
VD->getLocation());
1464+
1465+
Diag(VD->getLocation(), DiagID) << Type << EmitCppCompat;
14611466
}
14621467

14631468
// Notify the consumer that we've completed a tentative definition.

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14369,7 +14369,12 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1436914369
if (Var->getStorageDuration() == SD_Static ||
1437014370
Var->getStorageDuration() == SD_Thread)
1437114371
DiagID = diag::warn_default_init_const;
14372-
Diag(Var->getLocation(), DiagID) << Type;
14372+
14373+
bool EmitCppCompat = !Diags.isIgnored(
14374+
diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
14375+
Var->getLocation());
14376+
14377+
Diag(Var->getLocation(), DiagID) << Type << EmitCppCompat;
1437314378
}
1437414379

1437514380
// Check for jumps past the implicit initializer. C++0x

clang/lib/Sema/SemaInit.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6627,7 +6627,11 @@ void InitializationSequence::InitializeFrom(Sema &S,
66276627
Var->getStorageDuration() == SD_Thread)
66286628
DiagID = diag::warn_default_init_const_field;
66296629

6630-
S.Diag(Var->getLocation(), DiagID) << Var->getType();
6630+
bool EmitCppCompat = !S.Diags.isIgnored(
6631+
diag::warn_cxx_compat_hack_fake_diagnostic_do_not_emit,
6632+
Var->getLocation());
6633+
6634+
S.Diag(Var->getLocation(), DiagID) << Var->getType() << EmitCppCompat;
66316635
S.Diag(FD->getLocation(), diag::note_default_init_const_member) << FD;
66326636
}
66336637
}

clang/test/Sema/sizeless-1.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ void func(int sel) {
9494
svint8_t bad_brace_init_int8_6 = {{local_int8, 0}}; // expected-warning {{too many braces around initializer}}
9595

9696
const svint8_t const_int8 = local_int8; // expected-note {{declared const here}}
97-
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++}};
97+
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}};
9898

9999
volatile svint8_t volatile_int8;
100100

101101
const volatile svint8_t const_volatile_int8 = local_int8; // expected-note {{declared const here}}
102-
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++}}
102+
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}}
103103

104104
_Atomic svint8_t atomic_int8; // expected-error {{_Atomic cannot be applied to sizeless type 'svint8_t'}}
105105
__restrict svint8_t restrict_int8; // expected-error {{requires a pointer or reference}}

clang/test/Sema/typedef-retain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef int a[5];
1717
void test3(void) {
1818
typedef const a b;
1919
b r; // expected-note {{variable 'r' declared const here}} \
20-
expected-warning {{default initialization of an object of type 'b' (aka 'const int[5]') leaves the object uninitialized and is incompatible with C++}}
20+
expected-warning {{default initialization of an object of type 'b' (aka 'const int[5]') leaves the object uninitialized}}
2121
r[0] = 10; // expected-error {{cannot assign to variable 'r' with const-qualified type 'b' (aka 'const int[5]')}}
2222
}
2323

clang/test/Sema/warn-default-const-init.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Both of these should enable everything.
2-
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field,zero-init-var,zero-init-field -Wc++-compat -Wno-tentative-definition-compat %s
2+
// 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
33
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field,zero-init-var,zero-init-field -Wdefault-const-init %s
44

55
// This should enable nothing.
@@ -25,21 +25,26 @@
2525

2626
struct A { int i; };
2727
struct S{ const int i; }; // unsafe-field-note 2 {{member 'i' declared 'const' here}} \
28+
unsafe-field-compat-note 2 {{member 'i' declared 'const' here}} \
2829
cxx-note 3 {{default constructor of 'S' is implicitly deleted because field 'i' of const-qualified type 'const int' would not be initialized}}
2930
struct T { struct S s; }; // cxx-note {{default constructor of 'T' is implicitly deleted because field 's' has a deleted default constructor}}
3031
struct U { struct S s; const int j; };
3132
struct V { int i; const struct A a; }; // unsafe-field-note {{member 'a' declared 'const' here}} \
33+
unsafe-field-compat-note {{member 'a' declared 'const' here}} \
3234
cxx-note {{default constructor of 'V' is implicitly deleted because field 'a' of const-qualified type 'const struct A' would not be initialized}}
3335
struct W { struct A a; const int j; }; // unsafe-field-note {{member 'j' declared 'const' here}} \
36+
unsafe-field-compat-note {{member 'j' declared 'const' here}} \
3437
cxx-note {{default constructor of 'W' is implicitly deleted because field 'j' of const-qualified type 'const int' would not be initialized}}
3538

3639
void f() {
37-
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++}} \
40+
struct S s1; // unsafe-field-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized}} \
41+
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++}} \
3842
cxx-error {{call to implicitly-deleted default constructor of 'struct S'}}
3943
struct S s2 = { 0 };
4044
}
4145
void g() {
42-
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++}} \
46+
struct T t1; // unsafe-field-warning {{default initialization of an object of type 'struct T' with const member leaves the object uninitialized}} \
47+
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++}} \
4348
cxx-error {{call to implicitly-deleted default constructor of 'struct T'}}
4449
struct T t2 = { { 0 } };
4550
}
@@ -48,13 +53,15 @@ void h() {
4853
struct U u2 = { { 0 }, 0 };
4954
}
5055
void x() {
51-
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++}} \
56+
struct V v1; // unsafe-field-warning {{default initialization of an object of type 'struct V' with const member leaves the object uninitialized}} \
57+
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++}} \
5258
cxx-error {{call to implicitly-deleted default constructor of 'struct V'}}
5359
struct V v2 = { 0 };
5460
struct V v3 = { 0, { 0 } };
5561
}
5662
void y() {
57-
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++}} \
63+
struct W w1; // unsafe-field-warning {{default initialization of an object of type 'struct W' with const member leaves the object uninitialized}} \
64+
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++}} \
5865
cxx-error {{call to implicitly-deleted default constructor of 'struct W'}}
5966
struct W w2 = { 0 };
6067
struct W w3 = { { 0 }, 0 };
@@ -72,9 +79,9 @@ const struct S s; // zero-init-var-warning {{default initialization of an obje
7279
cxx-error {{call to implicitly-deleted default constructor of 'const struct S'}}
7380

7481
void func() {
75-
const int a; // unsafe-var-warning {{default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++}} \
82+
const int a; // unsafe-var-warning {{default initialization of an object of type 'const int' leaves the object uninitialized}} \
83+
unsafe-var-compat-warning {{default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++}} \
7684
cxx-error {{default initialization of an object of const type 'const int'}}
7785
static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
7886
cxx-error {{default initialization of an object of const type 'const int'}}
7987
}
80-

clang/test/SemaOpenCL/invalid-block.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ void f1(void) {
1414
f0(bl2);
1515
bl1 = bl2; // expected-error{{invalid operands to binary expression ('int (__generic ^const __private)(void)' and 'int (__generic ^const __private)(void)')}}
1616
int (^const bl3)(void); // expected-error{{invalid block variable declaration - must be initialized}} \
17-
expected-warning {{default initialization of an object of type 'int (__generic ^const __private)(void)' leaves the object uninitialized and is incompatible with C++}}
17+
expected-warning {{default initialization of an object of type 'int (__generic ^const __private)(void)' leaves the object uninitialized}}
1818
}
1919

2020
// A block with extern storage class is not allowed.

0 commit comments

Comments
 (0)