Skip to content

[C] Update the -Wdefault-const-init-unsafe wording #138266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 difference 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<
Expand Down Expand Up @@ -8234,11 +8244,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"
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14367,7 +14367,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
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Sema/sizeless-1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/typedef-retain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]')}}
}

Expand Down
21 changes: 14 additions & 7 deletions clang/test/Sema/warn-default-const-init.c
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 } };
}
Expand All @@ -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 };
Expand All @@ -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'}}
}

2 changes: 1 addition & 1 deletion clang/test/SemaOpenCL/invalid-block.cl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down