aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2021-02-23 09:40:09 -0500
committerPatrick Palka <ppalka@redhat.com>2021-02-23 09:40:09 -0500
commit5bd7afb71fca3a5a6e9f8586d86903bae1849193 (patch)
tree1967b2d7bd4f0593d0ddc6f4d9f91ce45deae1e0 /gcc
parentcac960a3ec450377ebeea9a2ea563a545e54f2d6 (diff)
downloadgcc-5bd7afb71fca3a5a6e9f8586d86903bae1849193.zip
gcc-5bd7afb71fca3a5a6e9f8586d86903bae1849193.tar.gz
gcc-5bd7afb71fca3a5a6e9f8586d86903bae1849193.tar.bz2
c++: Fix folding of non-dependent BASELINKs [PR95468]
Here, the problem ultimately seems to be that tsubst_copy_and_build, when called with empty args as we do during non-dependent expression folding, doesn't touch BASELINKs at all: it delegates to tsubst_copy which then immediately exits early due to the empty args. This means that the CAST_EXPR int(1) in the BASELINK A::condition<int(1)> never gets folded (as part of folding of the overall CALL_EXPR), which later causes us to crash when performing overload resolution of the rebuilt CALL_EXPR (which is still in terms of this templated BASELINK). This doesn't happen when condition() is a namespace-scope function because then condition<int(1)> is represented by a TEMPLATE_ID_EXPR rather than by a BASELINK, which does get handled directly from tsubst_copy_and_build. This patch fixes this issue by having tsubst_copy_and_build handle BASELINK directly rather than delegating to tsubst_copy, so that it processes BASELINKs even when args is empty. gcc/cp/ChangeLog: PR c++/95468 * pt.c (tsubst_copy_and_build) <case BASELINK>: New case, copied over from tsubst_copy. gcc/testsuite/ChangeLog: PR c++/95468 * g++.dg/template/non-dependent15.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent15.C12
2 files changed, 17 insertions, 0 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0393531..3576e0e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19856,6 +19856,11 @@ tsubst_copy_and_build (tree t,
case SCOPE_REF:
RETURN (tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
/*address_p=*/false));
+
+ case BASELINK:
+ RETURN (tsubst_baselink (t, current_nonlambda_class_type (),
+ args, complain, in_decl));
+
case ARRAY_REF:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl);
diff --git a/gcc/testsuite/g++.dg/template/non-dependent15.C b/gcc/testsuite/g++.dg/template/non-dependent15.C
new file mode 100644
index 0000000..00dfe26
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent15.C
@@ -0,0 +1,12 @@
+// PR c++/95468
+// { dg-do compile { target c++11 } }
+
+struct A {
+ template <int N>
+ static constexpr int condition() { return N; }
+};
+
+template <int> struct B {};
+
+template <class>
+using T = B<A::condition<int(1)>()>;