https://gcc.gnu.org/g:a8f53501ef8ebbb0dbef431e0275806eafd2e41f
commit a8f53501ef8ebbb0dbef431e0275806eafd2e41f 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. (cherry picked from commit 145c90720640ec6711ed3e5aa4152bbe1ee21751) 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 c1e4a4e148fa..56b222412b86 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2713,6 +2713,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 @@ -2726,11 +2734,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 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} } }