OK.
On Wed, Apr 4, 2018 at 3:39 PM, Jakub Jelinek <ja...@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 <ja...@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