Skip to content

Commit

Permalink
Add -Wdeprecated warnings and fixits for things deprecated in C++11:
Browse files Browse the repository at this point in the history
 - '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
  • Loading branch information
zygoloid committed Jun 13, 2013
1 parent 2eabf78 commit 8ca78a1
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 4 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ def err_expected_class_name_not_template :
Error<"'typename' is redundant; base classes are implicitly types">;
def err_unspecified_vla_size_with_static : Error<
"'static' may not be used with an unspecified variable length array size">;
def warn_deprecated_register : Warning<
"'register' storage class specifier is deprecated">, InGroup<Deprecated>;

def err_expected_case_before_expression: Error<
"expected 'case' keyword before expression">;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ def note_using_decl : Note<"%select{|previous }0using declaration">;
def warn_access_decl_deprecated : Warning<
"access declarations are deprecated; use using declarations instead">,
InGroup<Deprecated>;
def warn_exception_spec_deprecated : Warning<
"dynamic exception specifications are deprecated">,
InGroup<Deprecated>, DefaultIgnore;
def note_exception_spec_deprecated : Note<"use '%0' instead">;

def warn_global_constructor : Warning<
"declaration requires a global constructor">,
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
PrevSpec, DiagID);
break;
case tok::kw_register:
if (getLangOpts().CPlusPlus11)
Diag(Tok, diag::warn_deprecated_register)
<< FixItHint::CreateRemoval(Tok.getLocation());
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
PrevSpec, DiagID);
break;
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,16 @@ Parser::tryParseExceptionSpecification(
return Result;
}

static void diagnoseDynamicExceptionSpecification(
Parser &P, const SourceRange &Range, bool IsNoexcept) {
if (P.getLangOpts().CPlusPlus11) {
const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
P.Diag(Range.getBegin(), diag::warn_exception_spec_deprecated) << Range;
P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
<< Replacement << FixItHint::CreateReplacement(Range, Replacement);
}
}

/// ParseDynamicExceptionSpecification - Parse a C++
/// dynamic-exception-specification (C++ [except.spec]).
///
Expand Down Expand Up @@ -2926,6 +2936,7 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
T.consumeClose();
SpecificationRange.setEnd(T.getCloseLocation());
diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);
return EST_MSAny;
}

Expand Down Expand Up @@ -2957,6 +2968,8 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(

T.consumeClose();
SpecificationRange.setEnd(T.getCloseLocation());
diagnoseDynamicExceptionSpecification(*this, SpecificationRange,
Exceptions.empty());
return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
}

Expand Down
4 changes: 4 additions & 0 deletions clang/test/CXX/class/class.friend/p6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
class A {
friend static class B; // expected-error {{'static' is invalid in friend declarations}}
friend extern class C; // expected-error {{'extern' is invalid in friend declarations}}
#if __cplusplus < 201103L
friend register class E; // expected-error {{'register' is invalid in friend declarations}}
#else
friend register class E; // expected-error {{'register' is invalid in friend declarations}} expected-warning {{deprecated}}
#endif
friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}}
friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}}
friend __thread class G; // expected-error {{'__thread' is invalid in friend declarations}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void g() {

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

for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}
Expand Down
5 changes: 5 additions & 0 deletions clang/test/FixIt/fixit-cxx0x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,8 @@ namespace NonStaticConstexpr {
}
};
}

int RegisterVariable() {
register int n; // expected-warning {{'register' storage class specifier is deprecated}}
return n;
}
4 changes: 2 additions & 2 deletions clang/test/Sema/thread-specifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DC11 -D__thread=_Thread_local
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local
// 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
// 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
// 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
// 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

#ifdef __cplusplus
// In C++, we define __private_extern__ to extern.
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/attr-cxx0x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct align_member {
};

void f(alignas(1) char c) { // expected-error {{'alignas' attribute cannot be applied to a function parameter}}
alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}}
alignas(1) register char k; // expected-error {{'alignas' attribute cannot be applied to a variable with 'register' storage class}} expected-warning {{deprecated}}
try {
} catch (alignas(4) int n) { // expected-error {{'alignas' attribute cannot be applied to a 'catch' variable}}
}
Expand Down
31 changes: 31 additions & 0 deletions clang/test/SemaCXX/deprecated.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %clang_cc1 -std=c++98 %s -Wdeprecated -verify
// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify
// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify

void f() throw();
void g() throw(int);
void h() throw(...);
#if __cplusplus >= 201103L
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}}
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
// expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept(false)' instead}}
#endif

void stuff() {
register int n;
#if __cplusplus >= 201103L
// expected-warning@-2 {{'register' storage class specifier is deprecated}}
#endif

bool b;
++b; // expected-warning {{incrementing expression of type bool is deprecated}}

// FIXME: This is ill-formed in C++11.
char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
}

struct S { int n; };
struct T : private S {
// FIXME: This is ill-formed in C++11.
S::n; // expected-warning {{access declarations are deprecated; use using declarations instead}}
};

0 comments on commit 8ca78a1

Please sign in to comment.