From 233608bdb134b136c5379c76102368d29d022c52 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 9 Aug 2017 15:21:49 -0400 Subject: [PATCH] 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: r250999 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 12 +++++++++++ .../g++.dg/cpp1y/lambda-generic-const4.C | 20 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5476c1135b6..d3510cf1965 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2017-08-09 Jason Merrill + PR c++/81525 - wrong constant value with generic lambda + * pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto. + (tsubst_copy) [VAR_DECL]: Handle auto. + PR c++/81359 - Unparsed NSDMI error from SFINAE context. * init.c (get_nsdmi): Add complain parm. * typeck2.c (digest_nsdmi_init): Add complain parm. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d6f4b512b5..0f899b9edec 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12875,7 +12875,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)) { @@ -14656,6 +14664,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) diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C new file mode 100644 index 00000000000..52f4373ccbd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C @@ -0,0 +1,20 @@ +// PR c++/81525 +// { dg-do compile { target c++14 } } + +template struct A { + constexpr operator int () const { return i; } +}; +template constexpr A a = {}; + +template void foo (F f) { + f (A<0>{}); +} +template +void bar (T) { + constexpr auto N = a<1>; + auto f = [&] (auto i) { + static_assert (static_cast(N) == 1, ""); + }; + foo (f); +} +int main () { bar (0); } -- 2.30.2