aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2016-04-27 13:28:44 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2016-04-27 13:28:44 +0000
commit3c98ff9b1a24246e19da39fce967fe2f88be828e (patch)
treea55d8cdb9a0ba79683644f8c44d1fc9099e93d68 /gcc
parent437244c7737eeb63973e1e285d5dc6844ab13f9f (diff)
downloadgcc-3c98ff9b1a24246e19da39fce967fe2f88be828e.zip
gcc-3c98ff9b1a24246e19da39fce967fe2f88be828e.tar.gz
gcc-3c98ff9b1a24246e19da39fce967fe2f88be828e.tar.bz2
constexpr.c (get_fundef_copy): Use the original function for non-recursive evaluations.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C14
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr63956.C4
5 files changed, 47 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6fc42bc..b21666b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 41f0b5c..f0307a3 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4752a4c..e51f3bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..29230e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C
@@ -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);
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63956.C b/gcc/testsuite/g++.dg/ubsan/pr63956.C
index 90360be..25db8a4 100644
--- a/gcc/testsuite/g++.dg/ubsan/pr63956.C
+++ b/gcc/testsuite/g++.dg/ubsan/pr63956.C
@@ -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)