summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-11-01 23:38:37 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-11-01 23:38:37 +0000
commit7366f8e06093256082548af7d4e7d3baf7bfeb83 (patch)
tree2003a8e758230e7201734c2537f7aa137a264839
parentc3c8524640ffce0427d81f78501f32c3c8a07427 (diff)
Fix missing -Wregister warning when 'register' is applied to a function parameter.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317140 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDecl.cpp8
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp1
-rw-r--r--test/SemaCXX/deprecated.cpp7
-rw-r--r--test/SemaCXX/varargs.cpp2
4 files changed, 16 insertions, 2 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d68b430bae..0c00ef7e26 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11718,6 +11718,14 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
StorageClass SC = SC_None;
if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
SC = SC_Register;
+ // In C++11, the 'register' storage class specifier is deprecated.
+ // In C++17, it is not allowed, but we tolerate it as an extension.
+ if (getLangOpts().CPlusPlus11) {
+ Diag(DS.getStorageClassSpecLoc(),
+ getLangOpts().CPlusPlus1z ? diag::ext_register_storage_class
+ : diag::warn_deprecated_register)
+ << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
+ }
} else if (getLangOpts().CPlusPlus &&
DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
SC = SC_Auto;
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
index 0b7a902f93..13721518e6 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p2.cpp
@@ -39,6 +39,7 @@ struct S {
void foo(auto int ap, register int rp) {
#if __cplusplus >= 201103L // C++11 or later
// expected-warning@-2 {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}}
+// expected-warning@-3 {{'register' storage class specifier is deprecated}}
#endif
auto int abo;
#if __cplusplus >= 201103L // C++11 or later
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index a838cda7c4..773085bf2b 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -20,7 +20,12 @@ void i() throw(...);
// expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
#endif
-void stuff() {
+void stuff(register int q) {
+#if __cplusplus > 201402L
+ // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
+#elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS)
+ // expected-warning@-4 {{'register' storage class specifier is deprecated}}
+#endif
register int n;
#if __cplusplus > 201402L
// expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
diff --git a/test/SemaCXX/varargs.cpp b/test/SemaCXX/varargs.cpp
index f9027c2479..f2f53dc200 100644
--- a/test/SemaCXX/varargs.cpp
+++ b/test/SemaCXX/varargs.cpp
@@ -8,7 +8,7 @@ void f(const string& s, ...) { // expected-note {{parameter of type 'const stri
__builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}}
}
-void g(register int i, ...) {
+void g(register int i, ...) { // expected-warning 0-1{{deprecated}}
__builtin_va_start(ap, i); // UB in C, OK in C++
}