On 12/2/25 2:33 PM, Jakub Jelinek wrote:
Hi!

DECL_HARD_REGISTER is set only in cp_finish_decl together with
set_user_assembler_name.  If user attempts to take address of
such a var later, cxx_mark_addressable diagnoses it.
But if as in the following testcase the address is taken in its
initializer, we just ICE during expansion.

The following patch fixes it by emitting errors if TREE_ADDRESABLE
at the point we'd otherwise set DECL_HARD_REGISTER on it.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.
2025-12-02  Jakub Jelinek  <[email protected]>

        PR c++/122860
        * decl.cc (make_rtl_for_nonlocal_decl): Diagnose taking address
        of a hard register decl in its initializer.
        (cp_finish_decl): Likewise.

        * g++.dg/ext/pr122860.C: New test.

--- gcc/cp/decl.cc.jj   2025-12-01 13:23:50.255133865 +0100
+++ gcc/cp/decl.cc      2025-12-01 14:38:45.020235700 +0100
@@ -8654,8 +8654,15 @@ make_rtl_for_nonlocal_decl (tree decl, t
         placed in a particular register.  */
        if (VAR_P (decl) && DECL_REGISTER (decl))
        {
-         set_user_assembler_name (decl, asmspec);
-         DECL_HARD_REGISTER (decl) = 1;
+         if (TREE_ADDRESSABLE (decl))
+           error_at (DECL_SOURCE_LOCATION (decl),
+                     "address of explicit register variable %qD requested",
+                     decl);
+         else
+           {
+             set_user_assembler_name (decl, asmspec);
+             DECL_HARD_REGISTER (decl) = 1;
+           }
        }
        else
        {
@@ -9656,8 +9663,15 @@ cp_finish_decl (tree decl, tree init, bo
if (VAR_P (decl) && DECL_REGISTER (decl) && asmspec)
        {
-         set_user_assembler_name (decl, asmspec);
-         DECL_HARD_REGISTER (decl) = 1;
+         if (TREE_ADDRESSABLE (decl))
+           error_at (DECL_SOURCE_LOCATION (decl),
+                     "address of explicit register variable %qD requested",
+                     decl);
+         else
+           {
+             set_user_assembler_name (decl, asmspec);
+             DECL_HARD_REGISTER (decl) = 1;
+           }
        }
        return;
      }
--- gcc/testsuite/g++.dg/ext/pr122860.C.jj      2025-12-01 15:17:57.450515758 
+0100
+++ gcc/testsuite/g++.dg/ext/pr122860.C 2025-12-01 15:17:41.950784234 +0100
@@ -0,0 +1,30 @@
+// PR c++/122860
+// { dg-do compile }
+// { dg-options "-Wno-register" }
+
+void
+foo ()
+{
+  register __UINTPTR_TYPE__ val asm ("1") = (__UINTPTR_TYPE__) &val;     // { dg-error 
"address of explicit register variable 'val' requested" }
+}
+
+template <typename T>
+void
+bar ()
+{
+  register T val asm ("1") = (T) &val;   // { dg-error "address of explicit 
register variable 'val' requested" }
+}
+
+template <typename T>
+void
+baz ()
+{
+  register __UINTPTR_TYPE__ val asm ("1") = (__UINTPTR_TYPE__) &val;     // { dg-error 
"address of explicit register variable 'val' requested" }
+}
+
+void
+qux ()
+{
+  bar <__UINTPTR_TYPE__> ();
+  baz <int> ();
+}

        Jakub


Reply via email to