From patchwork Fri Dec 7 18:08:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: PR c++/55513: do not fold away builtins in COMPOUND_EXPRs Date: Fri, 07 Dec 2012 08:08:20 -0000 From: Aldy Hernandez X-Patchwork-Id: 204591 Message-Id: <50C23094.8000607@redhat.com> To: Jason Merrill Cc: gcc-patches The problem here is that we fold away calls to built-ins in COMPOUND_EXPRs such as: const int t = (__builtin_memcpy (s, "Hello", 6), 777); Since we return true for any built-in in potential_constant_expression_1, this means that check_initializer->store_init_value->maybe_constant_init will chop off the built-in side of a COMPOUND_EXPR when setting a DECL_INITIAL, transforming: (COMPOUND_EXPR (CALL_EXPR built-in) INTEGER_CST) into INTEGER_CST Fixed by setting `non_constant_p' if folding a built-in does not yield a constant. Tested on x86-64 Linux. OK for trunk? commit 9775b837cf9ece71cbf9560c35c638b3f8c0a778 Author: Aldy Hernandez Date: Fri Dec 7 10:40:25 2012 -0600 PR c++/55513 * semantics.c (cxx_eval_builtin_function_call): Set non_constant_p after folding. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 491d97c..f487a61 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6437,7 +6437,10 @@ cxx_eval_builtin_function_call (const constexpr_call *call, tree t, return t; new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t), CALL_EXPR_FN (t), nargs, args); - return fold (new_call); + new_call = fold (new_call); + if (!TREE_CONSTANT (new_call)) + *non_constant_p = true; + return new_call; } /* TEMP is the constant value of a temporary object of type TYPE. Adjust diff --git a/gcc/testsuite/g++.dg/pr55513.C b/gcc/testsuite/g++.dg/pr55513.C new file mode 100644 index 0000000..06eedee --- /dev/null +++ b/gcc/testsuite/g++.dg/pr55513.C @@ -0,0 +1,12 @@ +// { dg-do compile } +// { dg-options "-O0 -fdump-tree-gimple" } + +main () +{ + char s[10]; + const int t = (__builtin_memcpy (s, "Hello", 6), 777); + __builtin_printf ("%d %s\n", t, s); +} + +// { dg-final { scan-tree-dump-times "memcpy" 1 "gimple" } } +// { dg-final { cleanup-tree-dump "gimple" } }