[C++ PATCH] Fix __builtin_constant_p constexpr handling (PR inline-asm/85172)

Jakub Jelinek jakub@redhat.com
Wed Apr 4 20:35:00 GMT 2018


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



More information about the Gcc-patches mailing list