Skip to content

Commit 8ca78a1

Browse files
committed
Add -Wdeprecated warnings and fixits for things deprecated in C++11:
- 'register' storage class - dynamic exception specifications Only the former check is enabled by default for now (the latter might be quite noisy). llvm-svn: 183881
1 parent 2eabf78 commit 8ca78a1

File tree

10 files changed

+66
-4
lines changed

10 files changed

+66
-4
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ def err_expected_class_name_not_template :
309309
Error<"'typename' is redundant; base classes are implicitly types">;
310310
def err_unspecified_vla_size_with_static : Error<
311311
"'static' may not be used with an unspecified variable length array size">;
312+
def warn_deprecated_register : Warning<
313+
"'register' storage class specifier is deprecated">, InGroup<Deprecated>;
312314

313315
def err_expected_case_before_expression: Error<
314316
"expected 'case' keyword before expression">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ def note_using_decl : Note<"%select{|previous }0using declaration">;
287287
def warn_access_decl_deprecated : Warning<
288288
"access declarations are deprecated; use using declarations instead">,
289289
InGroup<Deprecated>;
290+
def warn_exception_spec_deprecated : Warning<
291+
"dynamic exception specifications are deprecated">,
292+
InGroup<Deprecated>, DefaultIgnore;
293+
def note_exception_spec_deprecated : Note<"use '%0' instead">;
290294

291295
def warn_global_constructor : Warning<
292296
"declaration requires a global constructor">,

clang/lib/Parse/ParseDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,6 +2771,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
27712771
PrevSpec, DiagID);
27722772
break;
27732773
case tok::kw_register:
2774+
if (getLangOpts().CPlusPlus11)
2775+
Diag(Tok, diag::warn_deprecated_register)
2776+
<< FixItHint::CreateRemoval(Tok.getLocation());
27742777
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
27752778
PrevSpec, DiagID);
27762779
break;

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2893,6 +2893,16 @@ Parser::tryParseExceptionSpecification(
28932893
return Result;
28942894
}
28952895

2896+
static void diagnoseDynamicExceptionSpecification(
2897+
Parser &P, const SourceRange &Range, bool IsNoexcept) {
2898+
if (P.getLangOpts().CPlusPlus11) {
2899+
const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
2900+
P.Diag(Range.getBegin(), diag::warn_exception_spec_deprecated) << Range;
2901+
P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
2902+
<< Replacement << FixItHint::CreateReplacement(Range, Replacement);
2903+
}
2904+
}
2905+
28962906
/// ParseDynamicExceptionSpecification - Parse a C++
28972907
/// dynamic-exception-specification (C++ [except.spec]).
28982908
///
@@ -2926,6 +2936,7 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
29262936
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
29272937
T.consumeClose();
29282938
SpecificationRange.setEnd(T.getCloseLocation());
2939+
diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);
29292940
return EST_MSAny;
29302941
}
29312942

@@ -2957,6 +2968,8 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
29572968

29582969
T.consumeClose();
29592970
SpecificationRange.setEnd(T.getCloseLocation());
2971+
diagnoseDynamicExceptionSpecification(*this, SpecificationRange,
2972+
Exceptions.empty());
29602973
return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
29612974
}
29622975

clang/test/CXX/class/class.friend/p6.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
class A {
55
friend static class B; // expected-error {{'static' is invalid in friend declarations}}
66
friend extern class C; // expected-error {{'extern' is invalid in friend declarations}}
7+
#if __cplusplus < 201103L
78
friend register class E; // expected-error {{'register' is invalid in friend declarations}}
9+
#else
10+
friend register class E; // expected-error {{'register' is invalid in friend declarations}} expected-warning {{deprecated}}
11+
#endif
812
friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}}
913
friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}}
1014
friend __thread class G; // expected-error {{'__thread' is invalid in friend declarations}}

clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void g() {
117117

118118
for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}
119119
for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}
120-
for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}}
120+
for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} expected-warning {{deprecated}}
121121
for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}}
122122

123123
for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}

clang/test/FixIt/fixit-cxx0x.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,8 @@ namespace NonStaticConstexpr {
132132
}
133133
};
134134
}
135+
136+
int RegisterVariable() {
137+
register int n; // expected-warning {{'register' storage class specifier is deprecated}}
138+
return n;
139+
}

clang/test/Sema/thread-specifier.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU
33
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DC11 -D__thread=_Thread_local
44
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local
5-
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DCXX11 -D__thread=thread_local -std=c++11
6-
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11
5+
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DCXX11 -D__thread=thread_local -std=c++11 -Wno-deprecated
6+
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11 -Wno-deprecated
77

88
#ifdef __cplusplus
99
// In C++, we define __private_extern__ to extern.

clang/test/SemaCXX/attr-cxx0x.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct align_member {
1212
};
1313

1414
void f(alignas(1) char c) { // expected-error {{'alignas' attribute cannot be applied to a function parameter}}
15-
alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}}
15+
alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}} expected-warning {{deprecated}}
1616
try {
1717
} catch (alignas(4) int n) { // expected-error {{'alignas' attribute cannot be applied to a 'catch' variable}}
1818
}

clang/test/SemaCXX/deprecated.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -std=c++98 %s -Wdeprecated -verify
2+
// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify
3+
// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify
4+
5+
void f() throw();
6+
void g() throw(int);
7+
void h() throw(...);
8+
#if __cplusplus >= 201103L
9+
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}}
10+
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
11+
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
12+
#endif
13+
14+
void stuff() {
15+
register int n;
16+
#if __cplusplus >= 201103L
17+
// expected-warning@-2 {{'register' storage class specifier is deprecated}}
18+
#endif
19+
20+
bool b;
21+
++b; // expected-warning {{incrementing expression of type bool is deprecated}}
22+
23+
// FIXME: This is ill-formed in C++11.
24+
char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
25+
}
26+
27+
struct S { int n; };
28+
struct T : private S {
29+
// FIXME: This is ill-formed in C++11.
30+
S::n; // expected-warning {{access declarations are deprecated; use using declarations instead}}
31+
};

0 commit comments

Comments
 (0)