Implement P0001R1 - C++17 removal of register storage class specifier c-family/
authorJakub Jelinek <jakub@redhat.com>
Thu, 29 Sep 2016 20:54:56 +0000 (22:54 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 29 Sep 2016 20:54:56 +0000 (22:54 +0200)
Implement P0001R1 - C++17 removal of register storage class specifier
c-family/
* c.opt (Wregister): New warning.
* c-opts.c (c_common_post_options): Enable -Wregister by
default for C++17.
cp/
* decl.c (cp_finish_decl): Diagnose register storage class
on vars except when used in GNU global or local register variable
extension.
(grokdeclarator): Diagnose register storage class on parameters.
* except.c (expand_start_catch_block): Set DECL_REGISTER only
after cp_finish_decl call.
testsuite/
* c-c++-common/Wvarargs-2.c (foo1): Except new warning for C++17.
* c-c++-common/vector-subscript-2.c (vf): Expect new error for
C++17.
* c-c++-common/vector-subscript-5.c (foo): Don't use register
keyword if not __SSE2__.
* c-c++-common/Wvarargs.c (foo1, foo3): Expect new warnings for
C++17.
* g++.dg/compat/struct-layout-1_generate.c (iterative_hash): Remove
register keywords.
* g++.dg/eh/pr29166.C: Add -Wno-register option.
* g++.dg/warn/register-parm-1.C (erroneous_warning,
no_erroneous_warning): Expect new warnings for C++17.
* g++.dg/warn/register-var-2.C (f): Likewise.
* g++.dg/parse/register1.C (f): Expect new error for C++17.
* g++.dg/parse/linkage2.C (foo): Likewise.
* g++.dg/torture/pr36826.C (CoinMin, CoinMax): Avoid register
keyword on parameters for C++17.
* g++.dg/cpp1z/register1.C: New test.
* g++.dg/cpp1z/register2.C: New test.
* g++.dg/cpp1z/register3.C: New test.

From-SVN: r240638

21 files changed:
gcc/c-family/ChangeLog
gcc/c-family/c-opts.c
gcc/c-family/c.opt
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/except.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wvarargs-2.c
gcc/testsuite/c-c++-common/Wvarargs.c
gcc/testsuite/c-c++-common/vector-subscript-2.c
gcc/testsuite/c-c++-common/vector-subscript-5.c
gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
gcc/testsuite/g++.dg/cpp1z/register1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/register2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/register3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/eh/pr29166.C
gcc/testsuite/g++.dg/parse/linkage2.C
gcc/testsuite/g++.dg/parse/register1.C
gcc/testsuite/g++.dg/torture/pr36826.C
gcc/testsuite/g++.dg/warn/register-parm-1.C
gcc/testsuite/g++.dg/warn/register-var-2.C

index c85bd729e4ed7951b4c6ee342ba730fe70d90c73..3e606940d1323c5e9ef7ffc73bf6aaca3ca613d4 100644 (file)
@@ -1,3 +1,10 @@
+2016-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       Implement P0001R1 - C++17 removal of register storage class specifier
+       * c.opt (Wregister): New warning.
+       * c-opts.c (c_common_post_options): Enable -Wregister by
+       default for C++17.
+
 2016-09-29  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * c-opts.c (c_common_post_options): Remove special case for
index 5fe3132b3c277fc434a5f621f9024cd8b5880b86..c5a699d67cf0a06f0aaa170f03b84874fa3efc2a 100644 (file)
@@ -870,6 +870,10 @@ c_common_post_options (const char **pfilename)
     warn_shift_negative_value = (extra_warnings
                                 && (cxx_dialect >= cxx11 || flag_isoc99));
 
+  /* -Wregister is enabled by default in C++17.  */
+  if (!global_options_set.x_warn_register)
+    warn_register = cxx_dialect >= cxx1z;
+
   /* Declone C++ 'structors if -Os.  */
   if (flag_declone_ctor_dtor == -1)
     flag_declone_ctor_dtor = optimize_size;
index 4a9b9e88a250358a9133f500370923ff8fbd4866..e14678103cdb4937be0aa557722eef0d2d35a312 100644 (file)
@@ -842,6 +842,10 @@ Wredundant-decls
 C ObjC C++ ObjC++ Var(warn_redundant_decls) Warning
 Warn about multiple declarations of the same object.
 
+Wregister
+C++ ObjC++ Var(warn_register) Warning
+Warn about uses of register storage specifier.
+
 Wreorder
 C++ ObjC++ Var(warn_reorder) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn when the compiler reorders code.
index 69bc0958a60c643da21f819769399ec59f526a1f..fb0c0e0ffaa70eacdd30b69538ff29b1728b3920 100644 (file)
@@ -1,3 +1,13 @@
+2016-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       Implement P0001R1 - C++17 removal of register storage class specifier
+       * decl.c (cp_finish_decl): Diagnose register storage class
+       on vars except when used in GNU global or local register variable
+       extension.
+       (grokdeclarator): Diagnose register storage class on parameters.
+       * except.c (expand_start_catch_block): Set DECL_REGISTER only
+       after cp_finish_decl call.
+
 2016-09-29  Marek Polacek  <polacek@redhat.com>
 
        * rtti.c (involves_incomplete_p): Add fall through comment.
index 3dfa0423522722d9d3adc35390cb4cfdd3cac85c..65966f8545417b1fb62deb7e90a909db260eab4a 100644 (file)
@@ -6711,6 +6711,19 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (type == error_mark_node)
     return;
 
+  /* Warn about register storage specifiers except when in GNU global
+     or local register variable extension.  */
+  if (VAR_P (decl) && DECL_REGISTER (decl) && asmspec_tree == NULL_TREE)
+    {
+      if (cxx_dialect >= cxx1z)
+       pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
+                "ISO C++1z does not allow %<register%> storage "
+                "class specifier");
+      else
+       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
+                   "%<register%> storage class specifier used");
+    }
+
   /* If a name was specified, get the string.  */
   if (at_namespace_scope_p ())
     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
@@ -11634,7 +11647,20 @@ grokdeclarator (const cp_declarator *declarator,
        and in case doing stupid register allocation.  */
 
     if (storage_class == sc_register)
-      DECL_REGISTER (decl) = 1;
+      {
+       DECL_REGISTER (decl) = 1;
+       /* Warn about register storage specifiers on PARM_DECLs.  */
+       if (TREE_CODE (decl) == PARM_DECL)
+         {
+           if (cxx_dialect >= cxx1z)
+             pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
+                      "ISO C++1z does not allow %<register%> storage "
+                      "class specifier");
+           else
+             warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
+                         "%<register%> storage class specifier used");
+         }
+      }
     else if (storage_class == sc_extern)
       DECL_THIS_EXTERN (decl) = 1;
     else if (storage_class == sc_static)
index 014df507f227397b4d7ca02f8c61a564f007f41a..6555d6b5576cf00dc17c91612b27db0df55e001e 100644 (file)
@@ -540,9 +540,9 @@ expand_start_catch_block (tree decl)
       if (init_type != TREE_TYPE (init))
        init = build1 (NOP_EXPR, init_type, init);
       exp = create_temporary_var (init_type);
-      DECL_REGISTER (exp) = 1;
       cp_finish_decl (exp, init, /*init_const_expr=*/false,
                      NULL_TREE, LOOKUP_ONLYCONVERTING);
+      DECL_REGISTER (exp) = 1;
       initialize_handler_parm (decl, exp);
     }
 
index 753b45b2a0f2f8a6fb4df48ecbcc1d2c16daffbe..804d0c2791371b7dd1d551570cb6ea29fdd01c3c 100644 (file)
@@ -1,3 +1,27 @@
+2016-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       Implement P0001R1 - C++17 removal of register storage class specifier
+       * c-c++-common/Wvarargs-2.c (foo1): Except new warning for C++17.
+       * c-c++-common/vector-subscript-2.c (vf): Expect new error for
+       C++17.
+       * c-c++-common/vector-subscript-5.c (foo): Don't use register
+       keyword if not __SSE2__.
+       * c-c++-common/Wvarargs.c (foo1, foo3): Expect new warnings for
+       C++17.
+       * g++.dg/compat/struct-layout-1_generate.c (iterative_hash): Remove
+       register keywords.
+       * g++.dg/eh/pr29166.C: Add -Wno-register option.
+       * g++.dg/warn/register-parm-1.C (erroneous_warning,
+       no_erroneous_warning): Expect new warnings for C++17.
+       * g++.dg/warn/register-var-2.C (f): Likewise.
+       * g++.dg/parse/register1.C (f): Expect new error for C++17.
+       * g++.dg/parse/linkage2.C (foo): Likewise.
+       * g++.dg/torture/pr36826.C (CoinMin, CoinMax): Avoid register
+       keyword on parameters for C++17.
+       * g++.dg/cpp1z/register1.C: New test.
+       * g++.dg/cpp1z/register2.C: New test.
+       * g++.dg/cpp1z/register3.C: New test.
+
 2016-09-29  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.target/i386/adx-check.h (main): Simplify feature bit tests.
index a2e031f91403a2f98dcbca582b42355debcb1d89..1eacde1cbf26745b0d5a6e6be967b340cffc2185 100644 (file)
@@ -23,7 +23,7 @@ foo0 (int a, int b, ...)
 }
 
 void
-foo1 (int a, register int b, ...)
+foo1 (int a, register int b, ...)      // { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
 {
     va_list vp;
     /* 'b' is declared with register storage, but don't warn
index 0f90cb3bfce1685d10cd7feb2bf16b06bdccff6d..20d8ec77c03e4480e9d3e58929109795cb4c2825 100644 (file)
@@ -23,7 +23,7 @@ foo0 (int a, int b, ...)
 }
 
 void
-foo1 (int a, register int b, ...)
+foo1 (int a, register int b, ...)      // { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
 {
     va_list vp;
     /* 'b' is declared with register storage, but don't warn
@@ -45,7 +45,7 @@ foo2 (int a, int b, ...)
 }
 
 void
-foo3 (int a, register int b, ...)
+foo3 (int a, register int b, ...)      // { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
 {
     va_list vp;
     /* 'b' is declared with register storage, so warn.  */
index 84d55b91d20036521eb44d9d02750379a13cc9ff..e7bd251e060494ce0e3df72ec12977dc30bd49d4 100644 (file)
@@ -7,6 +7,6 @@
 
 float vf(int i)
 {
-  register vector float a;
+  register vector float a;     // { dg-error "ISO C++1z does not allow 'register' storage class specifier" "" { target c++1z } }
   return a[0];
 }
index 916b4a2d9a6ff8d29d9a04c2fc1ab3e614af74d4..66ed87a4d0bfe41550b9d3f5f9341615609cf603 100644 (file)
@@ -5,7 +5,10 @@ typedef int U __attribute__ ((vector_size (16)));
 int
 foo (int i)
 {
-  register U u
+#if __SSE2__
+  register
+#endif
+    U u
 #if __SSE2__
       asm ("xmm0")
 #endif
index 9fab3a8d0f7860a7ca627a17fb654045fc232aca..71d4af93a41933cb360737ad872f62c8ea3b76f6 100644 (file)
@@ -1028,12 +1028,12 @@ acceptable.  Do NOT use for cryptographic purposes.
 
 static hashval_t
 iterative_hash (const void *k_in /* the key */,
-               register size_t  length /* the length of the key */,
-               register hashval_t initval /* the previous hash, or
-                                             an arbitrary value */)
+               size_t  length /* the length of the key */,
+               hashval_t initval /* the previous hash, or
+                                    an arbitrary value */)
 {
-  register const unsigned char *k = (const unsigned char *)k_in;
-  register hashval_t a,b,c,len;
+  const unsigned char *k = (const unsigned char *)k_in;
+  hashval_t a,b,c,len;
 
   /* Set up the internal state */
   len = length;
diff --git a/gcc/testsuite/g++.dg/cpp1z/register1.C b/gcc/testsuite/g++.dg/cpp1z/register1.C
new file mode 100644 (file)
index 0000000..a55a717
--- /dev/null
@@ -0,0 +1,29 @@
+// P0001R1 - C++17 removal of register keyword
+// { dg-do compile }
+
+#if defined(__i386__) || defined(__x86_64__)
+#define REG1 "ebx"
+#define REG2 "edi"
+#endif
+
+#ifdef REG1
+register int a __asm (REG1);   // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+#endif
+register int b;                        // { dg-error "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+register int c ();             // { dg-error "storage class 'register' invalid for function" }
+int foo (register int d)       // { dg-error "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+{
+  return d;
+}
+int bar ()
+{
+#ifdef REG2
+  register int e __asm (REG2); // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+#else
+  int e;
+#endif
+  register int f;              // { dg-error "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+  e = 6;
+  f = 7;
+  return e + f;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/register2.C b/gcc/testsuite/g++.dg/cpp1z/register2.C
new file mode 100644 (file)
index 0000000..1c1be5e
--- /dev/null
@@ -0,0 +1,30 @@
+// P0001R1 - C++17 removal of register keyword
+// { dg-do compile }
+// { dg-options "-Wno-register" }
+
+#if defined(__i386__) || defined(__x86_64__)
+#define REG1 "ebx"
+#define REG2 "edi"
+#endif
+
+#ifdef REG1
+register int a __asm (REG1);   // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+#endif
+register int b;                        // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+register int c ();             // { dg-error "storage class 'register' invalid for function" }
+int foo (register int d)       // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+{
+  return d;
+}
+int bar ()
+{
+#ifdef REG2
+  register int e __asm (REG2); // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+#else
+  int e;
+#endif
+  register int f;              // { dg-bogus "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
+  e = 6;
+  f = 7;
+  return e + f;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/register3.C b/gcc/testsuite/g++.dg/cpp1z/register3.C
new file mode 100644 (file)
index 0000000..90b7f9d
--- /dev/null
@@ -0,0 +1,30 @@
+// P0001R1 - C++17 removal of register keyword
+// { dg-do compile { target c++14_down } }
+// { dg-options "-Wregister" }
+
+#if defined(__i386__) || defined(__x86_64__)
+#define REG1 "ebx"
+#define REG2 "edi"
+#endif
+
+#ifdef REG1
+register int a __asm (REG1);   // { dg-bogus "'register' storage class specifier used" }
+#endif
+register int b;                        // { dg-warning "'register' storage class specifier used" }
+register int c ();             // { dg-error "storage class 'register' invalid for function" }
+int foo (register int d)       // { dg-warning "'register' storage class specifier used" }
+{
+  return d;
+}
+int bar ()
+{
+#ifdef REG2
+  register int e __asm (REG2); // { dg-bogus "'register' storage class specifier used" }
+#else
+  int e;
+#endif
+  register int f;              // { dg-warning "'register' storage class specifier used" }
+  e = 6;
+  f = 7;
+  return e + f;
+}
index 432b64e98496bedf8dc137acf68489e02f919db9..8d816486a6ebdc805a5bec0da08f2234b9d76dbe 100644 (file)
@@ -1,5 +1,6 @@
 // PR 29166: r4-r7 corrupted when unwinding.
 // { dg-do run }
+// { dg-additional-options "-Wno-register" }
 
 class Ex 
 { 
index aa204df2a1003d1895a0be7f088b41ec6eec9a4c..71402bbca40dd3fb873265ba07febc0d54b3174e 100644 (file)
@@ -1,3 +1,3 @@
 // PR c++/27884
 
-extern "C" void foo(register int *my_perl);
+extern "C" void foo(register int *my_perl);    // { dg-error "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
index 3be2e652502fa10675a9389875ec8a7d10fdb2cd..4db85d4f0e16e874ff114b592e86d39d8d30872b 100644 (file)
@@ -8,7 +8,7 @@ public:
   operator int() { return i; }
 };
 
-C f (register C x)
+C f (register C x)     // { dg-error "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
 {
   return x + 31;
 }
index 436220ba8a7917c08eaa40287ca274e7e534e171..5418aaa7cd6da4f00b054f5ddafd3fe84645728b 100644 (file)
@@ -1,5 +1,10 @@
+#if __cplusplus > 201402L
+template <class T> T CoinMax(const T x1, const T x2); 
+template <class T> T CoinMin(const T x1, const T x2);
+#else
 template <class T> T CoinMax(register const T x1, register const T x2); 
 template <class T> T CoinMin(register const T x1, register const T x2);
+#endif
 class CoinIndexedVector;
 class ClpModel {
 protected:
index 44232d3cf41ad746e1d99ae97487cad545367c5c..15d1aa53f26055c841457bb62dd1c2532500d39d 100644 (file)
@@ -1,9 +1,9 @@
 // PR c++/60955
 // { dg-options "-Wextra" }
 
-unsigned int erroneous_warning(register int a) {
+unsigned int erroneous_warning(register int a) {       // { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
     if ((a) & 0xff) return 1; else return 0;
 }
-unsigned int no_erroneous_warning(register int a) {
+unsigned int no_erroneous_warning(register int a) {    // { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } }
     if (a & 0xff) return 1; else return 0;
 }
index 28f5df0cf52c5f5516560a564ae3d9dda672fab2..d829f8ac7c2c4072e00918cc51bf752f0a0440c0 100644 (file)
@@ -9,6 +9,6 @@ void g(int *);
 
 void f(void) 
 { 
-  register int x;
+  register int x;      /* { dg-warning "ISO C\\+\\+1z does not allow 'register' storage class specifier" "" { target c++1z } } */
   g(&x); /* { dg-warning "address requested for 'x', which is declared 'register'" } */
 }