Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/15?
-- >8 --
In this test we crash in lookup_member with
s.S::template a<42> == 42
but not without the "S::". The problem is that lookup_member gets
a TEMPLATE_DECL and not an identifier.
In tsubst_expr/COMPONENT_REF for variable templates we should not
go to the "Lookup the template functions" block; we should let
finish_class_member_access_expr do the job.
PR c++/123143
gcc/cp/ChangeLog:
* pt.cc (tsubst_expr) <case COMPONENT_REF>: Check identifier_p
before doing lookup for a template function.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/var-templ88.C: New test.
---
gcc/cp/pt.cc | 3 ++-
gcc/testsuite/g++.dg/cpp1y/var-templ88.C | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ88.C
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index bcc1525ff8b..140d232aa85 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22453,7 +22453,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t
complain, tree in_decl)
}
}
else if (TREE_CODE (member) == SCOPE_REF
- && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
+ && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR
+ && identifier_p (TREE_OPERAND (TREE_OPERAND (member, 1), 0)))
{
/* Lookup the template functions now that we know what the
scope is. */
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ88.C
b/gcc/testsuite/g++.dg/cpp1y/var-templ88.C
new file mode 100644
index 00000000000..63160067e7a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ88.C
@@ -0,0 +1,20 @@
+// PR c++/123143
+// { dg-do compile { target c++14 } }
+
+constexpr int x = 42;
+struct S { static constexpr int x = 20; template <int N> static constexpr int
a = N; };
+
+template<typename>
+void
+f ()
+{
+ constexpr S s;
+ static_assert (s.template a<42> == 42, "");
+ static_assert (s.S::template a<42> == 42, "");
+}
+
+void
+g ()
+{
+ f<int>();
+}
base-commit: 132139c00a8ed6d6941a7d51fecca886d13d527a
--
2.53.0