PR c++/81525 - wrong constant value with generic lambda

* pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto.
	(tsubst_copy) [VAR_DECL]: Handle auto.

From-SVN: r252941
This commit is contained in:
Jason Merrill 2017-09-18 14:36:47 -04:00 committed by Jason Merrill
parent e1eaa7a325
commit 3f2b67a9bb
3 changed files with 38 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2017-09-18 Jason Merrill <jason@redhat.com>
PR c++/81525 - wrong constant value with generic lambda
* pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto.
(tsubst_copy) [VAR_DECL]: Handle auto.
2017-09-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline

View File

@ -12896,7 +12896,15 @@ 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;
}
if (VAR_P (r))
{
@ -14687,6 +14695,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
= TREE_CONSTANT (r) = true;
DECL_INITIAL (r) = init;
if (tree auto_node = type_uses_auto (TREE_TYPE (r)))
TREE_TYPE (r)
= do_auto_deduction (TREE_TYPE (r), init, auto_node,
complain, adc_variable_type);
}
gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
|| decl_constant_var_p (r)

View File

@ -0,0 +1,20 @@
// PR c++/81525
// { dg-do compile { 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 (A<0>{});
}
template <typename T>
void bar (T) {
constexpr auto N = a<1>;
auto f = [&] (auto i) {
static_assert (static_cast<int>(N) == 1, "");
};
foo (f);
}
int main () { bar (0); }