aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-03-20 16:31:40 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-03-20 16:31:40 -0400
commit292a8bbb27fd13e87552ca7c98a9d4e82c21b385 (patch)
tree2150935ef639b1e97f5dcdda3907facd092ba69b /gcc
parent3ad7fed1cc87d281881757477c5197d9d3a97232 (diff)
downloadgcc-292a8bbb27fd13e87552ca7c98a9d4e82c21b385.zip
gcc-292a8bbb27fd13e87552ca7c98a9d4e82c21b385.tar.gz
gcc-292a8bbb27fd13e87552ca7c98a9d4e82c21b385.tar.bz2
PR c++/87480 - decltype of member access in default template arg
The issue here is that declval<T>().d is considered instantiation-dependent within a template, as the access to 'd' might depend on the particular specialization. But when we're deducing template arguments for a call, we know that the call and the arguments are non-dependent, so we can do the substitution as though we aren't in a template. Which strictly speaking we aren't, since the default argument is considered a separate definition. * pt.c (type_unification_real): Accept a dependent result in template context. From-SVN: r269826
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/fntmpdefarg11.C15
3 files changed, 29 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2157496..09fb3f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/87480 - decltype of member access in default template arg
+ * pt.c (type_unification_real): Accept a dependent result in
+ template context.
+
2019-03-19 Martin Sebor <msebor@redhat.com>
PR tree-optimization/89688
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0acc16d..6c15419 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -21005,8 +21005,15 @@ type_unification_real (tree tparms,
}
else
{
+ /* Even if the call is happening in template context, getting
+ here means it's non-dependent, and a default argument is
+ considered a separate definition under [temp.decls], so we can
+ do this substitution without processing_template_decl. This
+ is important if the default argument contains something that
+ might be instantiation-dependent like access (87480). */
+ processing_template_decl_sentinel s;
tree substed = NULL_TREE;
- if (saw_undeduced == 1 && processing_template_decl == 0)
+ if (saw_undeduced == 1)
{
/* First instatiate in template context, in case we still
depend on undeduced template parameters. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg11.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg11.C
new file mode 100644
index 0000000..86c8ea9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg11.C
@@ -0,0 +1,15 @@
+// PR c++/87480
+// { dg-do compile { target c++11 } }
+
+template<typename T> T&& declval();
+
+template <typename T, typename = decltype(declval<T>().d)> void f(T) { }
+
+struct A {
+ double d;
+};
+
+template <typename>
+void j(A& a) {
+ f(a);
+}