Skip to content

Commit cbbb43f

Browse files
committed
Merge remote-tracking branch 'origin/main' into aballman-tentative-defn-cpp-compat
2 parents 8f0f665 + 75d1cce commit cbbb43f

File tree

18 files changed

+264
-163
lines changed

18 files changed

+264
-163
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ Improvements to clang-doc
8888
Improvements to clang-query
8989
---------------------------
9090

91+
Improvements to include-cleaner
92+
-------------------------------
93+
- Deprecated the ``-insert`` and ``-remove`` command line options, and added
94+
the ``-disable-remove`` and ``-disable-insert`` command line options as
95+
replacements. The previous command line options were confusing because they
96+
did not imply the default state of the option (which is inserts and removes
97+
being enabled). The new options are easier to understand the semantics of.
98+
9199
Improvements to clang-tidy
92100
--------------------------
93101

clang-tools-extra/include-cleaner/test/tool.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ int x = foo();
66
// CHANGE: - "foobar.h"
77
// CHANGE-NEXT: + "foo.h"
88

9-
// RUN: clang-include-cleaner -remove=0 -print=changes %s -- -I%S/Inputs/ | FileCheck --check-prefix=INSERT %s
9+
// RUN: clang-include-cleaner -disable-remove -print=changes %s -- -I%S/Inputs/ | FileCheck --check-prefix=INSERT %s
1010
// INSERT-NOT: - "foobar.h"
1111
// INSERT: + "foo.h"
1212

13-
// RUN: clang-include-cleaner -insert=0 -print=changes %s -- -I%S/Inputs/ | FileCheck --check-prefix=REMOVE %s
13+
// RUN: clang-include-cleaner -disable-insert -print=changes %s -- -I%S/Inputs/ | FileCheck --check-prefix=REMOVE %s
1414
// REMOVE: - "foobar.h"
1515
// REMOVE-NOT: + "foo.h"
1616

@@ -58,3 +58,16 @@ int x = foo();
5858
// RUN: FileCheck --match-full-lines --check-prefix=EDIT3 %s < %t.cpp
5959
// EDIT3: #include "foo.h"
6060
// EDIT3-NOT: {{^}}#include "foobar.h"{{$}}
61+
62+
// RUN: clang-include-cleaner -insert=false -print=changes %s -- -I%S/Inputs/ 2>&1 | \
63+
// RUN: FileCheck --check-prefix=DEPRECATED-INSERT %s
64+
// DEPRECATED-INSERT: warning: '-insert=0' is deprecated in favor of '-disable-insert'. The old flag was confusing since it suggested that inserts were disabled by default, when they were actually enabled.
65+
66+
// RUN: clang-include-cleaner -remove=false -print=changes %s -- -I%S/Inputs/ 2>&1 | \
67+
// RUN: FileCheck --check-prefix=DEPRECATED-REMOVE %s
68+
// DEPRECATED-REMOVE: warning: '-remove=0' is deprecated in favor of '-disable-remove'. The old flag was confusing since it suggested that removes were disabled by default, when they were actually enabled.
69+
70+
// RUN: clang-include-cleaner -insert=false -remove=false -print=changes %s -- -I%S/Inputs/ 2>&1 | \
71+
// RUN: FileCheck --check-prefix=DEPRECATED-BOTH %s
72+
// DEPRECATED-BOTH: warning: '-insert=0' is deprecated in favor of '-disable-insert'. The old flag was confusing since it suggested that inserts were disabled by default, when they were actually enabled.
73+
// DEPRECATED-BOTH: warning: '-remove=0' is deprecated in favor of '-disable-remove'. The old flag was confusing since it suggested that removes were disabled by default, when they were actually enabled.

clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,31 @@ cl::opt<bool> Edit{
9090
cl::desc("Apply edits to analyzed source files"),
9191
cl::cat(IncludeCleaner),
9292
};
93-
9493
cl::opt<bool> Insert{
9594
"insert",
96-
cl::desc("Allow header insertions"),
95+
cl::desc(
96+
"Allow header insertions (deprecated. Use -disable-insert instead)"),
9797
cl::init(true),
9898
cl::cat(IncludeCleaner),
9999
};
100100
cl::opt<bool> Remove{
101101
"remove",
102-
cl::desc("Allow header removals"),
102+
cl::desc("Allow header removals (deprecated. Use -disable-remove instead)"),
103103
cl::init(true),
104104
cl::cat(IncludeCleaner),
105105
};
106+
cl::opt<bool> DisableInsert{
107+
"disable-insert",
108+
cl::desc("Disable header insertions"),
109+
cl::init(false),
110+
cl::cat(IncludeCleaner),
111+
};
112+
cl::opt<bool> DisableRemove{
113+
"disable-remove",
114+
cl::desc("Disable header removals"),
115+
cl::init(false),
116+
cl::cat(IncludeCleaner),
117+
};
106118

107119
std::atomic<unsigned> Errors = ATOMIC_VAR_INIT(0);
108120

@@ -183,9 +195,26 @@ class Action : public clang::ASTFrontendAction {
183195
auto Results =
184196
analyze(AST.Roots, PP.MacroReferences, PP.Includes, &PI,
185197
getCompilerInstance().getPreprocessor(), HeaderFilter);
186-
if (!Insert)
198+
199+
if (!Insert) {
200+
llvm::errs()
201+
<< "warning: '-insert=0' is deprecated in favor of "
202+
"'-disable-insert'. "
203+
"The old flag was confusing since it suggested that inserts "
204+
"were disabled by default, when they were actually enabled.\n";
205+
}
206+
207+
if (!Remove) {
208+
llvm::errs()
209+
<< "warning: '-remove=0' is deprecated in favor of "
210+
"'-disable-remove'. "
211+
"The old flag was confusing since it suggested that removes "
212+
"were disabled by default, when they were actually enabled.\n";
213+
}
214+
215+
if (!Insert || DisableInsert)
187216
Results.Missing.clear();
188-
if (!Remove)
217+
if (!Remove || DisableRemove)
189218
Results.Unused.clear();
190219
std::string Final = fixIncludes(Results, AbsPath, Code, getStyle(AbsPath));
191220

clang/docs/ReleaseNotes.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,16 @@ C Language Changes
141141
function type in Microsoft compatibility mode. #GH124869
142142
- Clang now allows ``restrict`` qualifier for array types with pointer elements (#GH92847).
143143
- Clang now diagnoses ``const``-qualified object definitions without an
144-
initializer. If the object is zero-initialized, it will be diagnosed under
145-
the new warning ``-Wdefault-const-init`` (which is grouped under
146-
``-Wc++-compat`` because this construct is not compatible with C++). If the
147-
object is left uninitialized, it will be diagnosed unsed the new warning
148-
``-Wdefault-const-init-unsafe`` (which is grouped under
149-
``-Wdefault-const-init``). #GH19297
144+
initializer. If the object is a variable or field which is zero-initialized,
145+
it will be diagnosed under the new warning ``-Wdefault-const-init-var`` or
146+
``-Wdefault-const-init-field``, respectively. Similarly, if the variable or
147+
field is not zero-initialized, it will be diagnosed under the new diagnostic
148+
``-Wdefault-const-init-var-unsafe`` or ``-Wdefault-const-init-field-unsafe``,
149+
respectively. The unsafe diagnostic variants are grouped under a new
150+
diagnostic ``-Wdefault-const-init-unsafe``, which itself is grouped under the
151+
new diagnostic ``-Wdefault-const-init``. Finally, ``-Wdefault-const-init`` is
152+
grouped under ``-Wc++-compat`` because these constructs are not compatible
153+
with C++. #GH19297
150154
- Added ``-Wimplicit-void-ptr-cast``, grouped under ``-Wc++-compat``, which
151155
diagnoses implicit conversion from ``void *`` to another pointer type as
152156
being incompatible with C++. (#GH17792)

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,16 @@ def InitStringTooLongMissingNonString :
163163
def InitStringTooLongForCpp :
164164
DiagGroup<"c++-unterminated-string-initialization">;
165165
def HiddenCppDecl : DiagGroup<"c++-hidden-decl">;
166-
def DefaultConstInitUnsafe : DiagGroup<"default-const-init-unsafe">;
167-
def DefaultConstInit : DiagGroup<"default-const-init", [DefaultConstInitUnsafe]>;
166+
def DefaultConstInitFieldUnsafe : DiagGroup<"default-const-init-field-unsafe">;
167+
def DefaultConstInitVarUnsafe : DiagGroup<"default-const-init-var-unsafe">;
168+
def DefaultConstInitUnsafe : DiagGroup<"default-const-init-unsafe",
169+
[DefaultConstInitFieldUnsafe,
170+
DefaultConstInitVarUnsafe]>;
171+
def DefaultConstInitField : DiagGroup<"default-const-init-field">;
172+
def DefaultConstInitVar : DiagGroup<"default-const-init-var">;
173+
def DefaultConstInit : DiagGroup<"default-const-init",
174+
[DefaultConstInitField, DefaultConstInitVar,
175+
DefaultConstInitUnsafe]>;
168176
def ImplicitVoidPtrCast : DiagGroup<"implicit-void-ptr-cast">;
169177
def ImplicitIntToEnumCast : DiagGroup<"implicit-int-enum-cast",
170178
[ImplicitEnumEnumCast]>;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8221,14 +8221,20 @@ def err_address_space_qualified_delete : Error<
82218221

82228222
def note_default_init_const_member : Note<
82238223
"member %0 declared 'const' here">;
8224+
def warn_default_init_const_field : Warning<
8225+
"default initialization of an object of type %0 with const member is "
8226+
"incompatible with C++">, InGroup<DefaultConstInitField>, DefaultIgnore;
82248227
def warn_default_init_const : Warning<
8225-
"default initialization of an object of type %0%select{| with const member}1 "
8226-
"is incompatible with C++">,
8227-
InGroup<DefaultConstInit>, DefaultIgnore;
8228+
"default initialization of an object of type %0 is incompatible with C++">,
8229+
InGroup<DefaultConstInitVar>, DefaultIgnore;
8230+
def warn_default_init_const_field_unsafe : Warning<
8231+
"default initialization of an object of type %0 with const member leaves the "
8232+
"object uninitialized and is incompatible with C++">,
8233+
InGroup<DefaultConstInitFieldUnsafe>;
82288234
def warn_default_init_const_unsafe : Warning<
8229-
"default initialization of an object of type %0%select{| with const member}1 "
8230-
"leaves the object uninitialized and is incompatible with C++">,
8231-
InGroup<DefaultConstInitUnsafe>;
8235+
"default initialization of an object of type %0 leaves the object "
8236+
"uninitialized and is incompatible with C++">,
8237+
InGroup<DefaultConstInitVarUnsafe>;
82328238
def err_default_init_const : Error<
82338239
"default initialization of an object of const type %0"
82348240
"%select{| without a user-provided default constructor}1">;

clang/lib/Sema/Sema.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ 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 << /*not a field*/ 0;
1460+
Diag(VD->getLocation(), DiagID) << Type;
14611461
}
14621462

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

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14351,7 +14351,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
1435114351
if (Var->getStorageDuration() == SD_Static ||
1435214352
Var->getStorageDuration() == SD_Thread)
1435314353
DiagID = diag::warn_default_init_const;
14354-
Diag(Var->getLocation(), DiagID) << Type << /*not a field*/ 0;
14354+
Diag(Var->getLocation(), DiagID) << Type;
1435514355
}
1435614356

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

clang/lib/Sema/SemaInit.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6607,12 +6607,12 @@ void InitializationSequence::InitializeFrom(Sema &S,
66076607
// initializer present.
66086608
if (!Initializer) {
66096609
if (const FieldDecl *FD = getConstField(Rec)) {
6610-
unsigned DiagID = diag::warn_default_init_const_unsafe;
6610+
unsigned DiagID = diag::warn_default_init_const_field_unsafe;
66116611
if (Var->getStorageDuration() == SD_Static ||
66126612
Var->getStorageDuration() == SD_Thread)
6613-
DiagID = diag::warn_default_init_const;
6613+
DiagID = diag::warn_default_init_const_field;
66146614

6615-
S.Diag(Var->getLocation(), DiagID) << Var->getType() << /*member*/ 1;
6615+
S.Diag(Var->getLocation(), DiagID) << Var->getType();
66166616
S.Diag(FD->getLocation(), diag::note_default_init_const_member) << FD;
66176617
}
66186618
}
Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,45 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wdefault-const-init %s
2-
// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wc++-compat -Wno-tentative-definition-compat %s
3-
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe %s
4-
// RUN: %clang_cc1 -fsyntax-only -verify=c -Wdefault-const-init -Wno-default-const-init-unsafe %s
1+
// 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
3+
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field,zero-init-var,zero-init-field -Wdefault-const-init %s
4+
5+
// This should enable nothing.
56
// RUN: %clang_cc1 -fsyntax-only -verify=good -Wno-default-const-init-unsafe %s
7+
8+
// Only unsafe field and variable diagnostics
9+
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field %s
10+
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe-var,unsafe-field -Wdefault-const-init-unsafe %s
11+
12+
// Only zero init field and variable diagnostics
13+
// RUN: %clang_cc1 -fsyntax-only -verify=zero-init-var,zero-init-field -Wdefault-const-init -Wno-default-const-init-unsafe %s
14+
15+
// Only zero init and unsafe field diagnostics
16+
// RUN: %clang_cc1 -fsyntax-only -verify=zero-init-field,unsafe-field -Wno-default-const-init-var-unsafe -Wdefault-const-init-field %s
17+
18+
// Only zero init and unsafe variable diagnostics
19+
// RUN: %clang_cc1 -fsyntax-only -verify=zero-init-var,unsafe-var -Wno-default-const-init-field-unsafe -Wdefault-const-init-var %s
20+
21+
// C++ tests
622
// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ %s
23+
724
// good-no-diagnostics
825

926
struct A { int i; };
10-
struct S{ const int i; }; // unsafe-note 2 {{member 'i' declared 'const' here}} \
27+
struct S{ const int i; }; // unsafe-field-note 2 {{member 'i' declared 'const' here}} \
1128
cxx-note 3 {{default constructor of 'S' is implicitly deleted because field 'i' of const-qualified type 'const int' would not be initialized}}
1229
struct T { struct S s; }; // cxx-note {{default constructor of 'T' is implicitly deleted because field 's' has a deleted default constructor}}
1330
struct U { struct S s; const int j; };
14-
struct V { int i; const struct A a; }; // unsafe-note {{member 'a' declared 'const' here}} \
31+
struct V { int i; const struct A a; }; // unsafe-field-note {{member 'a' declared 'const' here}} \
1532
cxx-note {{default constructor of 'V' is implicitly deleted because field 'a' of const-qualified type 'const struct A' would not be initialized}}
16-
struct W { struct A a; const int j; }; // unsafe-note {{member 'j' declared 'const' here}} \
33+
struct W { struct A a; const int j; }; // unsafe-field-note {{member 'j' declared 'const' here}} \
1734
cxx-note {{default constructor of 'W' is implicitly deleted because field 'j' of const-qualified type 'const int' would not be initialized}}
1835

1936
void f() {
20-
struct S s1; // unsafe-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized and is incompatible with C++}} \
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++}} \
2138
cxx-error {{call to implicitly-deleted default constructor of 'struct S'}}
2239
struct S s2 = { 0 };
2340
}
2441
void g() {
25-
struct T t1; // unsafe-warning {{default initialization of an object of type 'struct T' with const member leaves the object uninitialized and is incompatible with C++}} \
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++}} \
2643
cxx-error {{call to implicitly-deleted default constructor of 'struct T'}}
2744
struct T t2 = { { 0 } };
2845
}
@@ -31,13 +48,13 @@ void h() {
3148
struct U u2 = { { 0 }, 0 };
3249
}
3350
void x() {
34-
struct V v1; // unsafe-warning {{default initialization of an object of type 'struct V' with const member leaves the object uninitialized and is incompatible with C++}} \
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++}} \
3552
cxx-error {{call to implicitly-deleted default constructor of 'struct V'}}
3653
struct V v2 = { 0 };
3754
struct V v3 = { 0, { 0 } };
3855
}
3956
void y() {
40-
struct W w1; // unsafe-warning {{default initialization of an object of type 'struct W' with const member leaves the object uninitialized and is incompatible with C++}} \
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++}} \
4158
cxx-error {{call to implicitly-deleted default constructor of 'struct W'}}
4259
struct W w2 = { 0 };
4360
struct W w3 = { { 0 }, 0 };
@@ -47,17 +64,17 @@ void y() {
4764
extern const int i;
4865
const int i = 12;
4966

50-
static const int j; // c-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
67+
static const int j; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
5168
cxx-error {{default initialization of an object of const type 'const int'}}
52-
const int k; // c-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
69+
const int k; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
5370
cxx-error {{default initialization of an object of const type 'const int'}}
54-
const struct S s; // c-warning {{default initialization of an object of type 'const struct S' is incompatible with C++}} \
71+
const struct S s; // zero-init-var-warning {{default initialization of an object of type 'const struct S' is incompatible with C++}} \
5572
cxx-error {{call to implicitly-deleted default constructor of 'const struct S'}}
5673

5774
void func() {
58-
const int a; // unsafe-warning {{default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++}} \
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++}} \
5976
cxx-error {{default initialization of an object of const type 'const int'}}
60-
static const int b; // c-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
77+
static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
6178
cxx-error {{default initialization of an object of const type 'const int'}}
6279
}
6380

0 commit comments

Comments
 (0)