This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement P0001R1 - C++17 removal of register storage class specifier


OK.

On Thu, Sep 29, 2016 at 4:21 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch pedwarns in C++17 on register storage class specifier, unless
> it is diagnosed errorneous for other reasons and unless it is used in the
> GNU global or local register variable extension.  Even in C++17, users can
> use -Wno-register to suppress the pedwarn, and for C++98-C++14 users can on
> the other side use -Wregister to get warning about it.  Clang seems to
> warn/error out similarly on variables with register storage class under
> -Wregister too, is quiet about the uses in register int var __asm ("...")
> (global and local), though strangely doesn't complain about register
> keywords on function arguments, which this patch diagnoses.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-09-29  Jakub Jelinek  <jakub@redhat.com>
>
>         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.
>
> --- gcc/c-family/c.opt.jj       2016-09-26 12:06:37.000000000 +0200
> +++ gcc/c-family/c.opt  2016-09-29 14:54:17.712047430 +0200
> @@ -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.
> --- gcc/c-family/c-opts.c.jj    2016-08-19 11:04:38.000000000 +0200
> +++ gcc/c-family/c-opts.c       2016-09-29 15:06:06.213254295 +0200
> @@ -871,6 +871,10 @@ c_common_post_options (const char **pfil
>      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;
> --- gcc/cp/decl.c.jj    2016-09-23 19:37:41.000000000 +0200
> +++ gcc/cp/decl.c       2016-09-29 16:05:03.724470275 +0200
> @@ -6711,6 +6711,19 @@ cp_finish_decl (tree decl, tree init, bo
>    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 *dec
>         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)
> --- gcc/cp/except.c.jj  2016-04-28 21:03:09.000000000 +0200
> +++ gcc/cp/except.c     2016-09-29 15:08:49.891226456 +0200
> @@ -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);
>      }
>
> --- gcc/testsuite/c-c++-common/Wvarargs-2.c.jj  2012-05-02 09:38:12.000000000 +0200
> +++ gcc/testsuite/c-c++-common/Wvarargs-2.c     2016-09-29 16:27:44.273604641 +0200
> @@ -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
> --- gcc/testsuite/c-c++-common/vector-subscript-2.c.jj  2012-05-02 09:38:12.000000000 +0200
> +++ gcc/testsuite/c-c++-common/vector-subscript-2.c     2016-09-29 16:00:38.539756931 +0200
> @@ -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];
>  }
> --- gcc/testsuite/c-c++-common/vector-subscript-5.c.jj  2016-05-24 18:14:11.000000000 +0200
> +++ gcc/testsuite/c-c++-common/vector-subscript-5.c     2016-09-29 16:01:31.002106721 +0200
> @@ -5,7 +5,10 @@ typedef int U __attribute__ ((vector_siz
>  int
>  foo (int i)
>  {
> -  register U u
> +#if __SSE2__
> +  register
> +#endif
> +    U u
>  #if __SSE2__
>        asm ("xmm0")
>  #endif
> --- gcc/testsuite/c-c++-common/Wvarargs.c.jj    2016-02-12 00:50:55.000000000 +0100
> +++ gcc/testsuite/c-c++-common/Wvarargs.c       2016-09-29 16:29:07.213576262 +0200
> @@ -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.  */
> --- gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c.jj   2015-12-16 09:02:09.000000000 +0100
> +++ gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c      2016-09-29 15:42:13.290440870 +0200
> @@ -1028,12 +1028,12 @@ acceptable.  Do NOT use for cryptographi
>
>  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;
> --- gcc/testsuite/g++.dg/eh/pr29166.C.jj        2008-09-05 12:55:05.000000000 +0200
> +++ gcc/testsuite/g++.dg/eh/pr29166.C   2016-09-29 15:42:51.224971251 +0200
> @@ -1,5 +1,6 @@
>  // PR 29166: r4-r7 corrupted when unwinding.
>  // { dg-do run }
> +// { dg-additional-options "-Wno-register" }
>
>  class Ex
>  {
> --- gcc/testsuite/g++.dg/warn/register-parm-1.C.jj      2014-12-19 13:18:35.000000000 +0100
> +++ gcc/testsuite/g++.dg/warn/register-parm-1.C 2016-09-29 16:20:31.061976063 +0200
> @@ -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;
>  }
> --- gcc/testsuite/g++.dg/warn/register-var-2.C.jj       2008-09-05 12:55:03.000000000 +0200
> +++ gcc/testsuite/g++.dg/warn/register-var-2.C  2016-09-29 16:16:29.313973189 +0200
> @@ -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'" } */
>  }
> --- gcc/testsuite/g++.dg/parse/register1.C.jj   2008-09-05 12:55:04.000000000 +0200
> +++ gcc/testsuite/g++.dg/parse/register1.C      2016-09-29 16:16:25.642018699 +0200
> @@ -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;
>  }
> --- gcc/testsuite/g++.dg/parse/linkage2.C.jj    2008-09-05 12:55:04.000000000 +0200
> +++ gcc/testsuite/g++.dg/parse/linkage2.C       2016-09-29 16:16:23.164049410 +0200
> @@ -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 } }
> --- gcc/testsuite/g++.dg/torture/pr36826.C.jj   2008-10-23 13:21:06.000000000 +0200
> +++ gcc/testsuite/g++.dg/torture/pr36826.C      2016-09-29 15:54:18.920457225 +0200
> @@ -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:
> --- gcc/testsuite/g++.dg/cpp1z/register1.C.jj   2016-09-29 15:38:59.976834015 +0200
> +++ gcc/testsuite/g++.dg/cpp1z/register1.C      2016-09-29 16:15:12.972919348 +0200
> @@ -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;
> +}
> --- gcc/testsuite/g++.dg/cpp1z/register2.C.jj   2016-09-29 15:39:44.739279874 +0200
> +++ gcc/testsuite/g++.dg/cpp1z/register2.C      2016-09-29 16:15:35.781636660 +0200
> @@ -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;
> +}
> --- gcc/testsuite/g++.dg/cpp1z/register3.C.jj   2016-09-29 15:40:32.064694004 +0200
> +++ gcc/testsuite/g++.dg/cpp1z/register3.C      2016-09-29 16:24:04.311331969 +0200
> @@ -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;
> +}
>
>         Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]