This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/81236, missed 'this' capture with template-id in generic lambda
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 14 Mar 2018 23:07:15 -0400
- Subject: Re: C++ PATCH for c++/81236, missed 'this' capture with template-id in generic lambda
- References: <CADzB+2ntf4kfg4A0eJ7KY-i+Szj0TMud1gtptOjyNN-+FJpCNw@mail.gmail.com>
On Tue, Aug 29, 2017 at 5:37 PM, Jason Merrill <jason@redhat.com> wrote:
> We could approach this by extending that change to all generic
> lambdas, and that might be appropriate for GCC 7, but it seems to me
> that this approach will just mean any problems with doing all the
> normal processing in a template will remain latent until someone
> happens to use them in a generic lambda; instead, this patch removes
> the template special case and fixes the normal code to work properly
> in templates.
I noticed today that this caused a regression on the attached
testcases, because we weren't updating the type of the BASELINK after
instantiating the auto function.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit d1d91f146d88b9d7442cce1e03edca55693de139
Author: Jason Merrill <jason@redhat.com>
Date: Wed Mar 14 16:27:08 2018 -0400
PR c++/81236 - auto variable and auto function
* pt.c (tsubst_baselink): Update the type of the BASELINK after
mark_used.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 14321816cde..2ea5fc79a2c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14700,9 +14700,16 @@ tsubst_baselink (tree baselink, tree object_type,
/* If lookup found a single function, mark it as used at this point.
(If lookup found multiple functions the one selected later by
overload resolution will be marked as used at that point.) */
- if (!template_id_p && !really_overloaded_fn (fns)
- && !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error))
- return error_mark_node;
+ if (!template_id_p && !really_overloaded_fn (fns))
+ {
+ tree fn = OVL_FIRST (fns);
+ bool ok = mark_used (fn, complain);
+ if (!ok && !(complain & tf_error))
+ return error_mark_node;
+ if (ok && BASELINK_P (baselink))
+ /* We might have instantiated an auto function. */
+ TREE_TYPE (baselink) = TREE_TYPE (fn);
+ }
if (BASELINK_P (baselink))
{
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn48.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn48.C
new file mode 100644
index 00000000000..bf9448e793e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn48.C
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++14 } }
+
+template <class T> struct A
+{
+ static auto fn() { }
+ static void f()
+ {
+ auto x = fn;
+ }
+};
+
+int main()
+{
+ A<int>::f();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn49.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn49.C
new file mode 100644
index 00000000000..d2e490604a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn49.C
@@ -0,0 +1,12 @@
+// CWG issue 2335
+// { dg-do compile { target c++14 } }
+
+template <class... Ts> struct partition_indices {
+ static auto compute_right () {}
+ static constexpr auto right = compute_right;
+};
+auto foo () -> partition_indices<>;
+void f() {
+ auto x = foo();
+ auto y = x.right;
+}