This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix __builtin_constant_p constexpr handling (PR inline-asm/85172)
- From: Jason Merrill <jason at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Nathan Sidwell <nathan at acm dot org>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 4 Apr 2018 15:51:14 -0400
- Subject: Re: [C++ PATCH] Fix __builtin_constant_p constexpr handling (PR inline-asm/85172)
- References: <20180404193926.GR8577@tucnak>
OK.
On Wed, Apr 4, 2018 at 3:39 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> 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