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} } }