aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-03-18 14:44:08 -0400
committerJason Merrill <jason@redhat.com>2025-03-18 16:20:22 -0400
commit145c90720640ec6711ed3e5aa4152bbe1ee21751 (patch)
tree5441d2132d11421ac21f2835c93a8558ff129b97 /gcc
parent6751bd4ac48a8529e2476a6848a77e81de540814 (diff)
downloadgcc-145c90720640ec6711ed3e5aa4152bbe1ee21751.zip
gcc-145c90720640ec6711ed3e5aa4152bbe1ee21751.tar.gz
gcc-145c90720640ec6711ed3e5aa4152bbe1ee21751.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/decl2.cc22
-rw-r--r--gcc/testsuite/g++.dg/template/linkage7.C17
2 files changed, 34 insertions, 5 deletions
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 4a9fb1c..a3149f2 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 0000000..6686a0e
--- /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} } }