From f2c9afceefaf89809b3aadc3d165dd5a5a63f570 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 17 Jun 2013 01:34:01 +0000 Subject: [PATCH] C++11: don't warn about the deprecated 'register' keyword if it's combined with an asm label. llvm-svn: 184069 --- clang/lib/Parse/ParseDecl.cpp | 7 ------- clang/lib/Sema/SemaDecl.cpp | 14 ++++++++++++-- clang/test/CXX/class/class.friend/p6.cpp | 2 +- clang/test/SemaCXX/deprecated.cpp | 10 ++++++---- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 70a7ea58f450..b3e8412dcf21 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -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; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f0d9fe8baaeb..92e0042bccd2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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. diff --git a/clang/test/CXX/class/class.friend/p6.cpp b/clang/test/CXX/class/class.friend/p6.cpp index ae327391a9a8..e4c59f781e3d 100644 --- a/clang/test/CXX/class/class.friend/p6.cpp +++ b/clang/test/CXX/class/class.friend/p6.cpp @@ -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}} diff --git a/clang/test/SemaCXX/deprecated.cpp b/clang/test/SemaCXX/deprecated.cpp index 5b56b03a000c..0335a80ffc5d 100644 --- a/clang/test/SemaCXX/deprecated.cpp +++ b/clang/test/SemaCXX/deprecated.cpp @@ -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; -- GitLab