mirror of git://gcc.gnu.org/git/gcc.git
PR c++/81525 - broken handling of auto in generic lambda.
* pt.c (tsubst_decl) [VAR_DECL]: Use strip_innermost_template_args. From-SVN: r253414
This commit is contained in:
parent
8139a48e67
commit
6411847fcf
|
|
@ -1,3 +1,8 @@
|
||||||
|
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>
|
2017-10-04 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
* call.c (convert_arg_to_ellipsis): Correct comment about passing
|
* call.c (convert_arg_to_ellipsis): Correct comment about passing
|
||||||
|
|
|
||||||
23
gcc/cp/pt.c
23
gcc/cp/pt.c
|
|
@ -13042,15 +13042,20 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
||||||
&& VAR_HAD_UNKNOWN_BOUND (t)
|
&& VAR_HAD_UNKNOWN_BOUND (t)
|
||||||
&& type != error_mark_node)
|
&& type != error_mark_node)
|
||||||
type = strip_array_domain (type);
|
type = strip_array_domain (type);
|
||||||
tree auto_node = type_uses_auto (type);
|
tree sub_args = args;
|
||||||
int len = TREE_VEC_LENGTH (args);
|
if (tree auto_node = type_uses_auto (type))
|
||||||
if (auto_node)
|
{
|
||||||
/* Mask off any template args past the variable's context so we
|
/* Mask off any template args past the variable's context so we
|
||||||
don't replace the auto with an unrelated argument. */
|
don't replace the auto with an unrelated argument. */
|
||||||
TREE_VEC_LENGTH (args) = TEMPLATE_TYPE_LEVEL (auto_node) - 1;
|
int nouter = TEMPLATE_TYPE_LEVEL (auto_node) - 1;
|
||||||
type = tsubst (type, args, complain, in_decl);
|
int extra = TMPL_ARGS_DEPTH (args) - nouter;
|
||||||
if (auto_node)
|
if (extra > 0)
|
||||||
TREE_VEC_LENGTH (args) = len;
|
/* 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))
|
if (VAR_P (r))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// 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>();
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// PR c++/81525
|
// PR c++/81525
|
||||||
// { dg-do compile { target c++14 } }
|
// { dg-do run { target c++14 } }
|
||||||
|
|
||||||
template <int i> struct A {
|
template <int i> struct A {
|
||||||
constexpr operator int () const { return i; }
|
constexpr operator int () const { return i; }
|
||||||
|
|
@ -13,7 +13,7 @@ template <typename T>
|
||||||
void bar (T) {
|
void bar (T) {
|
||||||
constexpr auto N = a<1>;
|
constexpr auto N = a<1>;
|
||||||
auto f = [&] (auto i) {
|
auto f = [&] (auto i) {
|
||||||
return static_cast<int>(N) == 1;
|
if (static_cast<int>(N) != 1) __builtin_abort();
|
||||||
};
|
};
|
||||||
foo (f);
|
foo (f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// 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); }
|
||||||
Loading…
Reference in New Issue