C++11: don't warn about the deprecated 'register' keyword if it's combined with
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 17 Jun 2013 01:34:01 +0000 (01:34 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 17 Jun 2013 01:34:01 +0000 (01:34 +0000)
an asm label.

llvm-svn: 184069

clang/lib/Parse/ParseDecl.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/CXX/class/class.friend/p6.cpp
clang/test/SemaCXX/deprecated.cpp

index 70a7ea58f450a33c5e16d22a4fff802b245add2f..b3e8412dcf21cd1bedf62ed2d7fc6fa4fdc19881 100644 (file)
@@ -2771,13 +2771,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
                                            PrevSpec, DiagID);
       break;
     case tok::kw_register:
-      // In C++11, the 'register' storage class specifier is deprecated.
-      // Suppress the warning in system macros, it's used in macros in some
-      // popular C system headers, such as in glibc's htonl() macro.
-      if (getLangOpts().CPlusPlus11 &&
-          !PP.getSourceManager().isInSystemMacro(Tok.getLocation()))
-        Diag(Tok, diag::warn_deprecated_register)
-          << FixItHint::CreateRemoval(Tok.getLocation());
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
                                          PrevSpec, DiagID);
       break;
index f0d9fe8baaeb7a329d7f2fd639e6167c3169ccdc..92e0042bccd22e388f9ac8cc729e7e4d29dd81cb 100644 (file)
@@ -4727,6 +4727,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     SC = SC_None;
   }
 
+  if (getLangOpts().CPlusPlus11 && SCSpec == DeclSpec::SCS_register &&
+      !D.getAsmLabel() && !getSourceManager().isInSystemMacro(
+                              D.getDeclSpec().getStorageClassSpecLoc())) {
+    // In C++11, the 'register' storage class specifier is deprecated.
+    // Suppress the warning in system macros, it's used in macros in some
+    // popular C system headers, such as in glibc's htonl() macro.
+    Diag(D.getDeclSpec().getStorageClassSpecLoc(),
+         diag::warn_deprecated_register)
+      << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
+  }
+
   IdentifierInfo *II = Name.getAsIdentifierInfo();
   if (!II) {
     Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
@@ -4740,7 +4751,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     // C99 6.9p2: The storage-class specifiers auto and register shall not
     // appear in the declaration specifiers in an external declaration.
     if (SC == SC_Auto || SC == SC_Register) {
-
       // If this is a register variable with an asm label specified, then this
       // is a GNU extension.
       if (SC == SC_Register && D.getAsmLabel())
@@ -4750,7 +4760,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       D.setInvalidType();
     }
   }
-  
+
   if (getLangOpts().OpenCL) {
     // Set up the special work-group-local storage class for variables in the
     // OpenCL __local address space.
index ae327391a9a8cb837f2ea893e3515caf416fcd1b..e4c59f781e3de03e7fa831cb57ce17fb6b800883 100644 (file)
@@ -7,7 +7,7 @@ class A {
 #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}}
+  friend register class E; // expected-error {{'register' is invalid in friend declarations}}
 #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}}
index 5b56b03a000c9f9e418f469a48be6db3bfd6c099..0335a80ffc5d555204fde840d4c77d663b3f4585 100644 (file)
@@ -1,8 +1,8 @@
-// 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
+// RUN: %clang_cc1 -std=c++98 %s -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify -triple x86_64-linux-gnu
 
-// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
+// RUN: %clang_cc1 -std=c++1y %s -Wdeprecated -verify -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
 
 #include "Inputs/register.h"
 
@@ -21,6 +21,8 @@ void stuff() {
   // expected-warning@-2 {{'register' storage class specifier is deprecated}}
 #endif
 
+  register int m asm("rbx"); // no-warning
+
   int k = to_int(n); // no-warning
 
   bool b;