Commit 6411847f by Jason Merrill Committed by Jason Merrill

PR c++/81525 - broken handling of auto in generic lambda.

	* pt.c (tsubst_decl) [VAR_DECL]: Use strip_innermost_template_args.

From-SVN: r253414
parent 8139a48e
2017-10-04 Jason Merrill <jason@redhat.com>
PR c++/81525 - broken handling of auto in generic lambda.
* pt.c (tsubst_decl) [VAR_DECL]: Use strip_innermost_template_args.
2017-10-04 Nathan Sidwell <nathan@acm.org>
* call.c (convert_arg_to_ellipsis): Correct comment about passing
......
......@@ -13042,15 +13042,20 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
&& VAR_HAD_UNKNOWN_BOUND (t)
&& type != error_mark_node)
type = strip_array_domain (type);
tree auto_node = type_uses_auto (type);
int len = TREE_VEC_LENGTH (args);
if (auto_node)
/* Mask off any template args past the variable's context so we
don't replace the auto with an unrelated argument. */
TREE_VEC_LENGTH (args) = TEMPLATE_TYPE_LEVEL (auto_node) - 1;
type = tsubst (type, args, complain, in_decl);
if (auto_node)
TREE_VEC_LENGTH (args) = len;
tree sub_args = args;
if (tree auto_node = type_uses_auto (type))
{
/* Mask off any template args past the variable's context so we
don't replace the auto with an unrelated argument. */
int nouter = TEMPLATE_TYPE_LEVEL (auto_node) - 1;
int extra = TMPL_ARGS_DEPTH (args) - nouter;
if (extra > 0)
/* This should never happen with the new lambda instantiation
model, but keep the handling just in case. */
gcc_assert (!CHECKING_P),
sub_args = strip_innermost_template_args (args, extra);
}
type = tsubst (type, sub_args, complain, in_decl);
}
if (VAR_P (r))
{
......
// Related to c++/81525
// { dg-do compile { target c++14 } }
template <class X>
struct A
{
template <class T>
static void f()
{
[](auto b) {
auto c = +b;
}(42);
}
};
int main()
{
A<int>::f<int>();
}
// PR c++/81525
// { dg-do compile { target c++14 } }
// { dg-do run { target c++14 } }
template <int i> struct A {
constexpr operator int () const { return i; }
......@@ -13,7 +13,7 @@ template <typename T>
void bar (T) {
constexpr auto N = a<1>;
auto f = [&] (auto i) {
return static_cast<int>(N) == 1;
if (static_cast<int>(N) != 1) __builtin_abort();
};
foo (f);
}
......
// PR c++/81525
// { dg-do run { target c++14 } }
template <int i> struct A {
constexpr operator int () const { return i; }
};
template <int i> constexpr A<i> a = {};
template <typename F> void foo (F f) {
f (42);
}
template <typename T>
void bar (T) {
constexpr auto N = a<1>;
auto f = [&] (auto i) {
if (static_cast<decltype(i)>(N) != 1) __builtin_abort();
};
foo (f);
}
int main () { bar (0); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment