constexpr.c (get_fundef_copy): Use the original function for non-recursive evaluations.
authorNathan Sidwell <nathan@acm.org>
Wed, 27 Apr 2016 13:28:44 +0000 (13:28 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 27 Apr 2016 13:28:44 +0000 (13:28 +0000)
cp/
* constexpr.c (get_fundef_copy): Use the original function for
non-recursive evaluations.
(save_fundef_copy): Always expect a slot to be available.

testsuite/
* g++.dg/cpp0x/constexpr-recursion3.C: New.
* g++.dg/ubsan/pr63956.C: Adjust error location.

From-SVN: r235506

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ubsan/pr63956.C

index 6fc42bc..b21666b 100644 (file)
@@ -1,3 +1,9 @@
+2016-04-27  Nathan Sidwell  <nathan@acm.org>
+
+       * constexpr.c (get_fundef_copy): Use the original function for
+       non-recursive evaluations.
+       (save_fundef_copy): Always expect a slot to be available.
+
 2016-04-27  Bernd Schmidt  <bschmidt@redhat.com>
 
        * parser.c (cp_parser_postfix_expression): Call
index 41f0b5c..f0307a3 100644 (file)
@@ -989,7 +989,8 @@ maybe_initialize_fundef_copies_table ()
 }
 
 /* Reuse a copy or create a new unshared copy of the function FUN.
-   Return this copy.  */
+   Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
+   is parms, TYPE is result.  */
 
 static tree
 get_fundef_copy (tree fun)
@@ -997,15 +998,26 @@ get_fundef_copy (tree fun)
   maybe_initialize_fundef_copies_table ();
 
   tree copy;
-  tree *slot = fundef_copies_table->get (fun);
-  if (slot == NULL || *slot == NULL_TREE)
+  bool existed;
+  tree *slot = &fundef_copies_table->get_or_insert (fun, &existed);
+
+  if (!existed)
     {
+      /* There is no cached function available, or in use.  We can use
+        the function directly.  That the slot is now created records
+        that this function is now in use.  */
+      copy = build_tree_list (DECL_SAVED_TREE (fun), DECL_ARGUMENTS (fun));
+      TREE_TYPE (copy) = DECL_RESULT (fun);
+    }
+  else if (*slot == NULL_TREE)
+    {
+      /* We've already used the function itself, so make a copy.  */
       copy = build_tree_list (NULL, NULL);
-      /* PURPOSE is body, VALUE is parms, TYPE is result.  */
       TREE_PURPOSE (copy) = copy_fn (fun, TREE_VALUE (copy), TREE_TYPE (copy));
     }
   else
     {
+      /* We have a cached function available.  */
       copy = *slot;
       *slot = TREE_CHAIN (copy);
     }
@@ -1013,12 +1025,14 @@ get_fundef_copy (tree fun)
   return copy;
 }
 
-/* Save the copy COPY of function FUN for later reuse by get_fundef_copy().  */
+/* Save the copy COPY of function FUN for later reuse by
+   get_fundef_copy().  By construction, there will always be an entry
+   to find.  */
 
 static void
 save_fundef_copy (tree fun, tree copy)
 {
-  tree *slot = &fundef_copies_table->get_or_insert (fun, NULL);
+  tree *slot = fundef_copies_table->get (fun);
   TREE_CHAIN (copy) = *slot;
   *slot = copy;
 }
index 4752a4c..e51f3bf 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-27  Nathan Sidwell  <nathan@acm.org>
+
+       * g++.dg/cpp0x/constexpr-recursion3.C: New.
+       * g++.dg/ubsan/pr63956.C: Adjust error location.
+
 2016-04-27  Nick Clifton  <nickc@redhat.com>
 
        PR middle-end/49889
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C
new file mode 100644 (file)
index 0000000..29230e9
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int Foo (int i)
+{
+  return (i ? Foo (i - 1): 0) + i;
+}
+
+static int a = Foo (0);
+static int b = Foo (1);
+static int d = Foo (3);
+static int c = Foo (2);
+static int e = Foo (4);
+static int g = Foo (6);
+static int f = Foo (5);
index 90360be..25db8a4 100644 (file)
@@ -92,7 +92,7 @@ constexpr int
 fn6 (const int &a, int b)
 {
   if (b != 2)
-    b = a;
+    b = a;  // { dg-error "is not a constant expression" }
   return b;
 }
 
@@ -106,7 +106,7 @@ fn7 (const int *a, int b)
 
 constexpr int n1 = 7;
 constexpr int n2 = fn7 (&n1, 5);
-constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-error "is not a constant expression" }
+constexpr int n3 = fn7 ((const int *) 0, 8);
 
 constexpr int
 fn8 (int i)