c++: Unshare expressions from constexpr cache.
authorJason Merrill <jason@redhat.com>
Thu, 23 Jan 2020 20:45:36 +0000 (15:45 -0500)
committerJason Merrill <jason@redhat.com>
Fri, 24 Jan 2020 17:34:02 +0000 (12:34 -0500)
Another place we need to unshare cached expressions.

PR c++/92852 - ICE with generic lambda and reference var.
* constexpr.c (maybe_constant_value): Likewise.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp1y/lambda-generic-ref1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/decomp48.C

index c01becefe879b1fd208f5534f71b1fa254a6a904..b1c9e2c632571523459341517077b24d547b8c44 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/92852 - ICE with generic lambda and reference var.
+       * constexpr.c (maybe_constant_value): Likewise.
+
 2020-01-23  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/92804
index f6b8f331bc9c3c21ab8d9dda81173058364e84c6..8e8806345c1d94231120bd94da809d9328f5c078 100644 (file)
@@ -6598,7 +6598,7 @@ maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
   if (cv_cache == NULL)
     cv_cache = hash_map<tree, tree>::create_ggc (101);
   if (tree *cached = cv_cache->get (t))
-    return *cached;
+    return unshare_expr_without_location (*cached);
 
   r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl);
   gcc_checking_assert (r == t
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ref1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ref1.C
new file mode 100644 (file)
index 0000000..a96fa1c
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/92852
+// { dg-do compile { target c++14 } }
+
+struct S { int operator<<(const int &); } glob;
+void foo()
+{
+  S& message_stream = glob;
+  auto format = [&message_stream](auto && x)
+               { message_stream << x ; };
+  format(3);
+  format(4u);
+}
index 3c50b02a6c247165b45192a9b1912650ec795aeb..35413c79a9daf32906cd1bd34a008ac0037b7f8f 100644 (file)
@@ -18,7 +18,7 @@ f2 ()
 {
   S v {1, 2};
   auto& [s, t] = v;    // { dg-warning "structured bindings only available with" "" { target c++14_down } }
-  return s;            // { dg-warning "reference to local variable 'v' returned" "" { target *-*-* } .-1 }
+  return s;            // { dg-warning "reference to local variable 'v' returned" }
 }
 
 int &
@@ -33,7 +33,7 @@ f4 ()
 {
   int a[3] = {1, 2, 3};
   auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
-  return s;            // { dg-warning "reference to local variable 'a' returned" "" { target *-*-* } .-1 }
+  return s;            // { dg-warning "reference to local variable 'a' returned" }
 }
 
 int &
@@ -78,7 +78,7 @@ f10 ()
 {
   S v {1, 2};
   auto& [s, t] = v;    // { dg-warning "structured bindings only available with" "" { target c++14_down } }
-  return &s;           // { dg-warning "address of local variable 'v' returned" "" { target *-*-* } .-1 }
+  return &s;           // { dg-warning "address of local variable 'v' returned" }
 }
 
 int *
@@ -93,7 +93,7 @@ f12 ()
 {
   int a[3] = {1, 2, 3};
   auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
-  return &s;           // { dg-warning "address of local variable 'a' returned" "" { target *-*-* } .-1 }
+  return &s;           // { dg-warning "address of local variable 'a' returned" }
 }
 
 int *