https://gcc.gnu.org/g:145c90720640ec6711ed3e5aa4152bbe1ee21751

commit r15-8279-g145c90720640ec6711ed3e5aa4152bbe1ee21751
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Mar 18 14:44:08 2025 -0400

    c++: constexpr ref template arg [PR119194]
    
    Here we were assuming that a constant variable appearing in a template
    argument is used for its value.  We also need to handle seeing its address
    taken.
    
            PR c++/119194
    
    gcc/cp/ChangeLog:
    
            * decl2.cc (min_vis_expr_r) [ADDR_EXPR]: New case.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/linkage7.C: New test.

Diff:
---
 gcc/cp/decl2.cc                          | 22 +++++++++++++++++-----
 gcc/testsuite/g++.dg/template/linkage7.C | 17 +++++++++++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 4a9fb1c3c00c..a3149f266030 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2843,16 +2843,28 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void 
*data)
       tpvis = type_visibility (TREE_TYPE (t));
       break;
 
+    case ADDR_EXPR:
+      t = TREE_OPERAND (t, 0);
+      if (VAR_P (t))
+       /* If a variable has its address taken, the lvalue-rvalue conversion is
+          not applied, so skip that case.  */
+       goto addressable;
+      break;
+
     case VAR_DECL:
     case FUNCTION_DECL:
       if (decl_constant_var_p (t))
        /* The ODR allows definitions in different TUs to refer to distinct
           constant variables with internal or no linkage, so such a reference
-          shouldn't affect visibility (PR110323).  FIXME but only if the
-          lvalue-rvalue conversion is applied.  We still want to restrict
-          visibility according to the type of the declaration however.  */
-       tpvis = type_visibility (TREE_TYPE (t));
-      else if (! TREE_PUBLIC (t))
+          shouldn't affect visibility if the lvalue-rvalue conversion is
+          applied (PR110323).  We still want to restrict visibility according
+          to the type of the declaration however.  */
+       {
+         tpvis = type_visibility (TREE_TYPE (t));
+         break;
+       }
+    addressable:
+      if (! TREE_PUBLIC (t))
        tpvis = VISIBILITY_ANON;
       else
        tpvis = DECL_VISIBILITY (t);
diff --git a/gcc/testsuite/g++.dg/template/linkage7.C 
b/gcc/testsuite/g++.dg/template/linkage7.C
new file mode 100644
index 000000000000..6686a0e5e511
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/linkage7.C
@@ -0,0 +1,17 @@
+// PR c++/119194
+// { dg-do compile { target c++11 } }
+
+template <const int& Str>
+[[gnu::noipa]]
+int get_length() {
+    return Str;
+}
+static constexpr int sssss{ 3};
+int main() {
+   if (get_length<sssss>() != sssss)
+     __builtin_abort();
+    return 0;
+}
+
+// { dg-final { scan-assembler {_Z10get_lengthIL_ZL5sssssEEiv} } }
+// { dg-final { scan-assembler-not 
{(weak|glob)[^\n]*_Z10get_lengthIL_Z5sssssEEiv} } }

Reply via email to