]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constexpr ref template arg [PR119194]
authorJason Merrill <jason@redhat.com>
Tue, 18 Mar 2025 18:44:08 +0000 (14:44 -0400)
committerJason Merrill <jason@redhat.com>
Tue, 18 Mar 2025 22:21:52 +0000 (18:21 -0400)
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.

(cherry picked from commit 145c90720640ec6711ed3e5aa4152bbe1ee21751)

gcc/cp/decl2.cc
gcc/testsuite/g++.dg/template/linkage7.C [new file with mode: 0644]

index bf8f566b8e371eb560dd056ad55b0dcc1235767e..19d3fd3287d63b716059632b60b9cecdb2d3c683 100644 (file)
@@ -2710,6 +2710,14 @@ 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 TEMPLATE_DECL:
       if (DECL_ALIAS_TEMPLATE_P (t) || standard_concept_p (t))
        /* FIXME: We don't maintain TREE_PUBLIC / DECL_VISIBILITY for
@@ -2723,11 +2731,15 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data)
       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 (file)
index 0000000..6686a0e
--- /dev/null
@@ -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} } }