diff options
author | Nathan Sidwell <nathan@acm.org> | 2016-04-27 13:28:44 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2016-04-27 13:28:44 +0000 |
commit | 3c98ff9b1a24246e19da39fce967fe2f88be828e (patch) | |
tree | a55d8cdb9a0ba79683644f8c44d1fc9099e93d68 /gcc | |
parent | 437244c7737eeb63973e1e285d5dc6844ab13f9f (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-recursion3.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr63956.C | 4 |
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) |