This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix __builtin_constant_p constexpr handling (PR inline-asm/85172)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Nathan Sidwell <nathan at acm dot org>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Apr 2018 21:39:26 +0200
- Subject: [C++ PATCH] Fix __builtin_constant_p constexpr handling (PR inline-asm/85172)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As the following testcases show, potential_constant_expression_1 for some
builtins returns true no matter what their arguments contain (intentionally
so); the problem is that we call unconditionally
cxx_eval_constant_expression on those arguments and that creates a loophole;
normally potential_constant_expression_1 is a check what kind of expressions
we allow in and cxx_eval* can only handle what we accept by that; through
these builtins, anything else can appear there too.
The following patch checks if the expression is potential constant
expression before trying to call cxx_eval_constant_expression, but to avoid
exponential compile time it checks it only for those builtins where
potential_constant_expression_1 has not checked those arguments.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2018-04-04 Jakub Jelinek <jakub@redhat.com>
PR inline-asm/85172
* constexpr.c (cxx_eval_builtin_function_call): For calls to
builtin_valid_in_constant_expr_p functions, don't call
cxx_eval_constant_expression if argument is not
potential_constant_expression.
* g++.dg/ext/builtin13.C: New test.
* g++.dg/ext/atomic-4.C: New test.
--- gcc/cp/constexpr.c.jj 2018-04-03 23:39:16.535665285 +0200
+++ gcc/cp/constexpr.c 2018-04-04 12:25:32.290813343 +0200
@@ -1189,8 +1189,14 @@ cxx_eval_builtin_function_call (const co
bool dummy1 = false, dummy2 = false;
for (i = 0; i < nargs; ++i)
{
- args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i),
- false, &dummy1, &dummy2);
+ args[i] = CALL_EXPR_ARG (t, i);
+ /* If builtin_valid_in_constant_expr_p is true,
+ potential_constant_expression_1 has not recursed into the arguments
+ of the builtin, verify it here. */
+ if (!builtin_valid_in_constant_expr_p (fun)
+ || potential_constant_expression (args[i]))
+ args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false,
+ &dummy1, &dummy2);
if (bi_const_p)
/* For __built_in_constant_p, fold all expressions with constant values
even if they aren't C++ constant-expressions. */
--- gcc/testsuite/g++.dg/ext/builtin13.C.jj 2018-04-04 12:11:03.566767129 +0200
+++ gcc/testsuite/g++.dg/ext/builtin13.C 2018-04-04 12:11:34.380768131 +0200
@@ -0,0 +1,9 @@
+// PR inline-asm/85172
+// { dg-do compile }
+// { dg-options "" }
+
+int
+foo ()
+{
+ return !__builtin_constant_p (({ __asm (""); 0; }));
+}
--- gcc/testsuite/g++.dg/ext/atomic-4.C.jj 2018-04-04 12:10:54.239766822 +0200
+++ gcc/testsuite/g++.dg/ext/atomic-4.C 2018-04-04 12:11:56.058768833 +0200
@@ -0,0 +1,9 @@
+// PR inline-asm/85172
+// { dg-do compile }
+// { dg-options "" }
+
+int
+foo (int *p)
+{
+ return !__atomic_always_lock_free (4, ({ __asm (""); p; }));
+}
Jakub