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