On Tue, Aug 29, 2017 at 5:37 PM, Jason Merrill <ja...@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 <ja...@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; +}