Skip to content

Commit 7538b35

Browse files
author
Erich Keane
committedJul 5, 2017
Address comments that escaped D33333
Patch By: Jen Yu Differential Revision:https://reviews.llvm.org/D34671 llvm-svn: 307172
1 parent 52f4f72 commit 7538b35

File tree

4 files changed

+62
-60
lines changed

4 files changed

+62
-60
lines changed
 

Diff for: ‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+7-9
Original file line numberDiff line numberDiff line change
@@ -6355,15 +6355,13 @@ def err_exceptions_disabled : Error<
63556355
"cannot use '%0' with exceptions disabled">;
63566356
def err_objc_exceptions_disabled : Error<
63576357
"cannot use '%0' with Objective-C exceptions disabled">;
6358-
def warn_throw_in_noexcept_func
6359-
: Warning<"%0 has a non-throwing exception specification but can still "
6360-
"throw, resulting in unexpected program termination">,
6361-
InGroup<Exceptions>;
6362-
def note_throw_in_dtor
6363-
: Note<"destructor or deallocator has a (possibly implicit) non-throwing "
6364-
"excepton specification">;
6365-
def note_throw_in_function
6366-
: Note<"non-throwing function declare here">;
6358+
def warn_throw_in_noexcept_func : Warning<
6359+
"%0 has a non-throwing exception specification but can still throw">,
6360+
InGroup<Exceptions>;
6361+
def note_throw_in_dtor : Note<
6362+
"%select{destructor|deallocator}0 has a %select{non-throwing|implicit "
6363+
"non-throwing}1 exception specification">;
6364+
def note_throw_in_function : Note<"function declared non-throwing here">;
63676365
def err_seh_try_outside_functions : Error<
63686366
"cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">;
63696367
def err_mixing_cxx_try_seh_try : Error<

Diff for: ‎clang/lib/Sema/AnalysisBasedWarnings.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -394,15 +394,21 @@ static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
394394

395395
static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,
396396
const FunctionDecl *FD) {
397-
if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
397+
if (!S.getSourceManager().isInSystemHeader(OpLoc) &&
398+
FD->getTypeSourceInfo()) {
398399
S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
399400
if (S.getLangOpts().CPlusPlus11 &&
400401
(isa<CXXDestructorDecl>(FD) ||
401402
FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
402-
FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
403-
S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
404-
else
405-
S.Diag(FD->getLocation(), diag::note_throw_in_function);
403+
FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete)) {
404+
if (const auto *Ty = FD->getTypeSourceInfo()->getType()->
405+
getAs<FunctionProtoType>())
406+
S.Diag(FD->getLocation(), diag::note_throw_in_dtor)
407+
<< !isa<CXXDestructorDecl>(FD) << !Ty->hasExceptionSpec()
408+
<< FD->getExceptionSpecSourceRange();
409+
} else
410+
S.Diag(FD->getLocation(), diag::note_throw_in_function)
411+
<< FD->getExceptionSpecSourceRange();
406412
}
407413
}
408414

@@ -420,8 +426,7 @@ static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
420426

421427
static bool isNoexcept(const FunctionDecl *FD) {
422428
const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
423-
if (FPT->getExceptionSpecType() != EST_None &&
424-
FPT->isNothrow(FD->getASTContext()))
429+
if (FPT->isNothrow(FD->getASTContext()))
425430
return true;
426431
return false;
427432
}

Diff for: ‎clang/test/CXX/except/except.spec/p11.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
22

33
// This is the "let the user shoot themselves in the foot" clause.
4-
void f() noexcept { // expected-note {{non-throwing function declare here}}
4+
void f() noexcept { // expected-note {{function declared non-throwing here}}
55
throw 0; // expected-warning {{has a non-throwing exception specification but}}
66
}
7-
void g() throw() { // expected-note {{non-throwing function declare here}}
7+
void g() throw() { // expected-note {{function declared non-throwing here}}
88
throw 0; // expected-warning {{has a non-throwing exception specification but}}
99
}
1010
void h() throw(int) {

Diff for: ‎clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp

+41-42
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
struct A_ShouldDiag {
33
~A_ShouldDiag(); // implicitly noexcept(true)
44
};
5-
A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor or deallocator has a (possibly implicit) non-throwing excepton specification}}
6-
throw 1; // expected-warning {{has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
5+
A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
6+
throw 1; // expected-warning {{has a non-throwing exception specification but can still throw}}
77
}
88
struct B_ShouldDiag {
99
int i;
1010
~B_ShouldDiag() noexcept(true) {} //no disg, no throw stmt
1111
};
1212
struct R_ShouldDiag : A_ShouldDiag {
1313
B_ShouldDiag b;
14-
~R_ShouldDiag() { // expected-note {{destructor or deallocator has a}}
14+
~R_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
1515
throw 1; // expected-warning {{has a non-throwing exception specification but}}
1616
}
1717
};
@@ -30,18 +30,18 @@ struct N_ShouldDiag {
3030
~N_ShouldDiag(); //implicitly noexcept(true)
3131
};
3232

33-
N_ShouldDiag::~N_ShouldDiag() { // expected-note {{destructor or deallocator has a}}
33+
N_ShouldDiag::~N_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
3434
throw 1; // expected-warning {{has a non-throwing exception specification but}}
3535
}
3636
struct X_ShouldDiag {
3737
B_ShouldDiag b;
38-
~X_ShouldDiag() noexcept { // expected-note {{destructor or deallocator has a}}
39-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
38+
~X_ShouldDiag() noexcept { // expected-note {{destructor has a non-throwing exception}}
39+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
4040
}
4141
};
4242
struct Y_ShouldDiag : A_ShouldDiag {
43-
~Y_ShouldDiag() noexcept(true) { // expected-note {{destructor or deallocator has a}}
44-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
43+
~Y_ShouldDiag() noexcept(true) { // expected-note {{destructor has a non-throwing exception specification}}
44+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
4545
}
4646
};
4747
struct C_ShouldNotDiag {
@@ -54,7 +54,7 @@ struct D_ShouldNotDiag {
5454
throw 1;
5555
}
5656
};
57-
struct E_ShouldNotDiag {
57+
struct E_ShouldNotDiag {
5858
C_ShouldNotDiag c;
5959
~E_ShouldNotDiag(); //implicitly noexcept(false)
6060
};
@@ -68,7 +68,7 @@ class A1_ShouldDiag {
6868
T b;
6969

7070
public:
71-
~A1_ShouldDiag() { // expected-note {{destructor or deallocator has a}}
71+
~A1_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
7272
throw 1; // expected-warning {{has a non-throwing exception specification but}}
7373
}
7474
};
@@ -81,19 +81,19 @@ template <typename T>
8181
struct R1_ShouldDiag : A1_ShouldDiag<T> //expected-note {{in instantiation of member function}}
8282
{
8383
B1_ShouldDiag<T> b;
84-
~R1_ShouldDiag() { // expected-note {{destructor or deallocator has a}}
84+
~R1_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
8585
throw 1; // expected-warning {{has a non-throwing exception specification but}}
8686
}
8787
};
8888
template <typename T>
8989
struct S1_ShouldDiag : A1_ShouldDiag<T> {
9090
B1_ShouldDiag<T> b;
91-
~S1_ShouldDiag() noexcept { // expected-note {{destructor or deallocator has a}}
92-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
91+
~S1_ShouldDiag() noexcept { // expected-note {{destructor has a non-throwing exception specification}}
92+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
9393
}
9494
};
95-
void operator delete(void *ptr) noexcept { // expected-note {{destructor or deallocator has a}}
96-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
95+
void operator delete(void *ptr) noexcept { // expected-note {{deallocator has a non-throwing exception specification}}
96+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
9797
}
9898
struct except_fun {
9999
static const bool i = false;
@@ -109,33 +109,33 @@ struct dependent_warn {
109109
};
110110
template <typename T>
111111
struct dependent_warn_noexcept {
112-
~dependent_warn_noexcept() noexcept(T::i) { // expected-note {{destructor or deallocator has a}}
113-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
112+
~dependent_warn_noexcept() noexcept(T::i) { // expected-note {{destructor has a non-throwing exception specification}}
113+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
114114
}
115115
};
116116
template <typename T>
117117
struct dependent_warn_both {
118-
~dependent_warn_both() noexcept(T::i) { // expected-note {{destructor or deallocator has a}}
119-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
118+
~dependent_warn_both() noexcept(T::i) { // expected-note {{destructor has a non-throwing exception specification}}
119+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
120120
}
121121
};
122-
void foo() noexcept { //expected-note {{non-throwing function declare here}}
123-
throw 1; // expected-warning {{has a non-throwing exception specification but}}
122+
void foo() noexcept { //expected-note {{function declared non-throwing here}}
123+
throw 1; // expected-warning {{has a non-throwing exception specification but}}
124124
}
125125
struct Throws {
126126
~Throws() noexcept(false);
127127
};
128128

129129
struct ShouldDiagnose {
130130
Throws T;
131-
~ShouldDiagnose() noexcept { //expected-note {{destructor or deallocator has a}}
131+
~ShouldDiagnose() noexcept { //expected-note {{destructor has a non-throwing exception specification}}
132132
throw; // expected-warning {{has a non-throwing exception specification but}}
133133
}
134134
};
135135
struct ShouldNotDiagnose {
136136
Throws T;
137-
~ShouldNotDiagnose() {
138-
throw;
137+
~ShouldNotDiagnose() {
138+
throw;
139139
}
140140
};
141141

@@ -158,37 +158,37 @@ void g_ShouldNotDiag() noexcept {
158158
}
159159
}
160160

161-
void h_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
161+
void h_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
162162
try {
163163
throw 12; // expected-warning {{has a non-throwing exception specification but}}
164164
} catch (const char *) {
165165
}
166166
}
167167

168-
void i_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
168+
void i_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
169169
try {
170170
throw 12;
171171
} catch (int) {
172172
throw; // expected-warning {{has a non-throwing exception specification but}}
173173
}
174174
}
175-
void j_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
175+
void j_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
176176
try {
177177
throw 12;
178178
} catch (int) {
179179
throw "haha"; // expected-warning {{has a non-throwing exception specification but}}
180180
}
181181
}
182182

183-
void k_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
183+
void k_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
184184
try {
185185
throw 12;
186186
} catch (...) {
187187
throw; // expected-warning {{has a non-throwing exception specification but}}
188188
}
189189
}
190190

191-
void loo_ShouldDiag(int i) noexcept { //expected-note {{non-throwing function declare here}}
191+
void loo_ShouldDiag(int i) noexcept { //expected-note {{function declared non-throwing here}}
192192
if (i)
193193
try {
194194
throw 12;
@@ -203,13 +203,13 @@ void loo1_ShouldNotDiag() noexcept {
203203
throw 12;
204204
}
205205

206-
void loo2_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
206+
void loo2_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
207207
if (1)
208208
throw 12; // expected-warning {{has a non-throwing exception specification but}}
209209
}
210210
struct S {};
211211

212-
void l_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
212+
void l_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
213213
try {
214214
throw S{}; //expected-warning {{has a non-throwing exception specification but}}
215215
} catch (S *s) {
@@ -222,7 +222,6 @@ void m_ShouldNotDiag() noexcept {
222222
throw s;
223223
} catch (S s) {
224224
}
225-
226225
}
227226
void n_ShouldNotDiag() noexcept {
228227
try {
@@ -231,15 +230,15 @@ void n_ShouldNotDiag() noexcept {
231230
} catch (const S &s) {
232231
}
233232
}
234-
void o_ShouldDiag() noexcept { //expected-note {{non-throwing function declare here}}
233+
void o_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}
235234
try {
236235
throw; //expected-warning {{has a non-throwing exception specification but}}
237236
} catch (...) {
238237
}
239238
}
240239

241240
#define NOEXCEPT noexcept
242-
void with_macro() NOEXCEPT { //expected-note {{non-throwing function declare here}}
241+
void with_macro() NOEXCEPT { //expected-note {{function declared non-throwing here}}
243242
throw 1; // expected-warning {{has a non-throwing exception specification but}}
244243
}
245244

@@ -248,8 +247,8 @@ void with_try_block() try {
248247
} catch (...) {
249248
}
250249

251-
void with_try_block1() noexcept try { //expected-note {{non-throwing function declare here}}
252-
throw 2; // expected-warning {{has a non-throwing exception specification but}}
250+
void with_try_block1() noexcept try { //expected-note {{function declared non-throwing here}}
251+
throw 2; // expected-warning {{has a non-throwing exception specification but}}
253252
} catch (char *) {
254253
}
255254

@@ -272,20 +271,20 @@ void goodPointer() noexcept {
272271
throw &d;
273272
} catch (B *) {}
274273
}
275-
void badPlain() noexcept { // expected-note {{non-throwing function declare here}}
274+
void badPlain() noexcept { //expected-note {{function declared non-throwing here}}
276275
try {
277-
throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
276+
throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw}}
278277
} catch (D) {}
279278
}
280-
void badReference() noexcept { // expected-note {{non-throwing function declare here}}
279+
void badReference() noexcept { //expected-note {{function declared non-throwing here}}
281280
try {
282-
throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
281+
throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw}}
283282
} catch (D &) {}
284283
}
285-
void badPointer() noexcept { // expected-note {{non-throwing function declare here}}
284+
void badPointer() noexcept { //expected-note {{function declared non-throwing here}}
286285
B b;
287286
try {
288-
throw &b; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw, resulting in unexpected program termination}}
287+
throw &b; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw}}
289288
} catch (D *) {}
290289
}
291290
}

0 commit comments

Comments
 (0)
Please sign in to comment.