aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-08-09 15:21:49 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-08-09 15:21:49 -0400
commit233608bdb134b136c5379c76102368d29d022c52 (patch)
treea18c21a01aaf9a0f12dd195512e3fcffa8d81167 /gcc
parent50a87c1c0c72bc5d238e4e5a7fa93671c0ba4702 (diff)
downloadgcc-233608bdb134b136c5379c76102368d29d022c52.zip
gcc-233608bdb134b136c5379c76102368d29d022c52.tar.gz
gcc-233608bdb134b136c5379c76102368d29d022c52.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C20
3 files changed, 36 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5476c11..d3510cf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2017-08-09 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.
+
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 3d6f4b5..0f899b9 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 0000000..52f4373
--- /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 <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); }