https://gcc.gnu.org/g:40f0f6ab75a391906bed40cbdc098b0df3a91af7

commit r15-6736-g40f0f6ab75a391906bed40cbdc098b0df3a91af7
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Jan 9 10:49:45 2025 -0500

    c++: template-id dependence wrt local static arg [PR117792]
    
    Here we end up ICEing at instantiation time for the call to
    f<local_static> ultimately because we wrongly consider the call to be
    non-dependent, and so we specialize f ahead of time and then get
    confused when fully substituting this specialization.
    
    The call is dependent due to [temp.dep.temp]/3 and we miss that because
    function template-id arguments aren't coerced until overload resolution,
    and so the local static template argument lacks an implicit cast to
    reference type that value_dependent_expression_p looks for before
    considering dependence of the address.  Other kinds of template-ids aren't
    affected since they're coerced ahead of time.
    
    So when considering dependence of a function template-id, we need to
    conservatively consider dependence of the address of each argument (if
    applicable).
    
            PR c++/117792
    
    gcc/cp/ChangeLog:
    
            * pt.cc (type_dependent_expression_p): Consider the dependence
            of the address of each template argument of a function
            template-id.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1z/nontype7.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/pt.cc                          | 10 ++++++++--
 gcc/testsuite/g++.dg/cpp1z/nontype7.C | 22 ++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dfaa8906a2cf..081285ef7209 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -29034,9 +29034,15 @@ type_dependent_expression_p (tree expression)
 
       if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
        {
-         if (any_dependent_template_arguments_p
-             (TREE_OPERAND (expression, 1)))
+         tree args = TREE_OPERAND (expression, 1);
+         if (any_dependent_template_arguments_p (args))
            return true;
+         /* Arguments of a function template-id aren't necessarily coerced
+            yet so we must conservatively assume that the address (and not
+            just value) of the argument matters as per [temp.dep.temp]/3.  */
+         for (tree arg : tree_vec_range (args))
+           if (has_value_dependent_address (arg))
+             return true;
          expression = TREE_OPERAND (expression, 0);
          if (identifier_p (expression))
            return true;
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype7.C 
b/gcc/testsuite/g++.dg/cpp1z/nontype7.C
new file mode 100644
index 000000000000..f103d5a6888e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype7.C
@@ -0,0 +1,22 @@
+// PR c++/117792
+// { dg-do compile { target c++17 } }
+
+template<const int& N, class T>
+void f(T) { }
+
+template<int N, class T>
+void f(...) = delete;
+
+template<const int& N> int v;
+
+template<const int& N> struct A { };
+
+template<class T>
+void g() {
+  static constexpr int local_static = 0;
+  auto x = v<local_static>; // OK
+  A<local_static> y; // OK
+  f<local_static>(0); // ICE
+}
+
+template void g<int>();

Reply via email to