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 <al...@redhat.com>
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" } }