From: Nathan Sidwell Date: Wed, 27 Apr 2016 13:28:44 +0000 (+0000) Subject: constexpr.c (get_fundef_copy): Use the original function for non-recursive evaluations. X-Git-Tag: basepoints/gcc-8~7386 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c98ff9b1a24246e19da39fce967fe2f88be828e;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6fc42bc030dd..b21666b8e84b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-04-27 Nathan Sidwell + + * 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 * parser.c (cp_parser_postfix_expression): Call diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 41f0b5c00eec..f0307a3df134 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 4752a4cb069b..e51f3bf2c882 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-04-27 Nathan Sidwell + + * g++.dg/cpp0x/constexpr-recursion3.C: New. + * g++.dg/ubsan/pr63956.C: Adjust error location. + 2016-04-27 Nick Clifton 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 000000000000..29230e93e173 --- /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 90360be112a0..25db8a40e520 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)