diff options
author | Jason Merrill <jason@redhat.com> | 2025-03-18 14:44:08 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2025-03-18 16:20:22 -0400 |
commit | 145c90720640ec6711ed3e5aa4152bbe1ee21751 (patch) | |
tree | 5441d2132d11421ac21f2835c93a8558ff129b97 /gcc | |
parent | 6751bd4ac48a8529e2476a6848a77e81de540814 (diff) | |
download | gcc-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.cc | 22 | ||||
-rw-r--r-- | 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 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} } } |