[C++ RFC] magic_varargs_p issues (PR c++/70144)

Jakub Jelinek jakub@redhat.com
Wed Mar 9 17:18:00 GMT 2016


Hi!

The following testcase results in ICE in C++, while is properly rejected in
C.  The problem is that the C++ FE treats some varargs builtins as magic and
doesn't perform any conversion on their args.
The first patch is just minimal, just ensures that we reject the builtins
without library implementation there.  But, as the second testcase shows,
e.g. for __builtin_classify_type_p there is disagreement between C and C++,
where the former applies function-to-pointer and array-to-pointer
conversions even for those magic builtins, but C++ does not.
Unfortunately the second patch breaks some Cilk+ tests, so I'd probably need
to tweak it slightly, e.g. by magic_varargs_p returning 0 / 1 / 2 levels,
0 would mean no magic, 1 would mean do decay_conversion, 2 would mean do
just mark_type_use + reject_gcc_builtin, and return 2 just for Cilk+
reductions and 1 for all other magic varargs functions (for type generic
I believe function-to-pointer and array-to-pointer are desirable, aren't
they).

So, what approach do you prefer?  I've so far bootstrapped/regtested the
second patch, which showed those
+FAIL: g++.dg/cilk-plus/AN/builtin_fn_custom_tplt.cc
+UNRESOLVED: g++.dg/cilk-plus/AN/builtin_fn_custom_tplt.cc
+FAIL: g++.dg/cilk-plus/AN/builtin_fn_mutating_tplt.cc
+UNRESOLVED: g++.dg/cilk-plus/AN/builtin_fn_mutating_tplt.cc
(for all opt/-g levels) regressions.

	Jakub
-------------- next part --------------
2016-03-09  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70144
	* call.c (build_over_call): For magic_varargs_p arguments,
	call reject_gcc_builtin if the argument is a FUNCTION_DECL.

	* c-c++-common/pr70144.c: New test.

--- gcc/cp/call.c.jj	2016-03-04 08:23:29.000000000 +0100
+++ gcc/cp/call.c	2016-03-09 13:04:34.280011774 +0100
@@ -7516,8 +7516,12 @@ build_over_call (struct z_candidate *can
     {
       tree a = (*args)[arg_index];
       if (magic_varargs_p (fn))
-	/* Do no conversions for magic varargs.  */
-	a = mark_type_use (a);
+	{
+	  /* Do no conversions for magic varargs.  */
+	  a = mark_type_use (a);
+	  if (TREE_CODE (a) == FUNCTION_DECL && reject_gcc_builtin (a))
+	    return error_mark_node;
+	}
       else if (DECL_CONSTRUCTOR_P (fn)
 	       && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn),
 							     TREE_TYPE (a)))
--- gcc/testsuite/c-c++-common/pr70144.c.jj	2016-03-09 13:10:58.246778355 +0100
+++ gcc/testsuite/c-c++-common/pr70144.c	2016-03-09 13:10:04.000000000 +0100
@@ -0,0 +1,9 @@
+/* PR c++/70144 */
+/* { dg-do compile } */
+
+void
+foo ()
+{
+  __builtin_constant_p (__builtin_constant_p) ?: ({ unsigned t = 0; t; });	/* { dg-error "must be directly called" } */
+  __builtin_classify_type (__builtin_expect);	/* { dg-error "must be directly called" } */
+}
-------------- next part --------------
2016-03-09  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70144
	* call.c (build_over_call): For magic_varargs_p, call decay_conversion
	instead of mark_type_use.  Don't store error_mark_node arguments to
	argarray, instead return error_mark_node.

	* c-c++-common/pr70144-1.c: New test.
	* c-c++-common/pr70144-2.c: New test.

--- gcc/cp/call.c.jj	2016-03-04 08:23:29.000000000 +0100
+++ gcc/cp/call.c	2016-03-09 13:29:40.674522135 +0100
@@ -7516,8 +7516,8 @@ build_over_call (struct z_candidate *can
     {
       tree a = (*args)[arg_index];
       if (magic_varargs_p (fn))
-	/* Do no conversions for magic varargs.  */
-	a = mark_type_use (a);
+	/* For magic varargs only do decay_conversion.  */
+	a = decay_conversion (a, complain);
       else if (DECL_CONSTRUCTOR_P (fn)
 	       && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn),
 							     TREE_TYPE (a)))
@@ -7530,6 +7530,8 @@ build_over_call (struct z_candidate *can
 	}
       else
 	a = convert_arg_to_ellipsis (a, complain);
+      if (a == error_mark_node)
+	return error_mark_node;
       argarray[j++] = a;
     }
 
--- gcc/testsuite/c-c++-common/pr70144-1.c.jj	2016-03-09 13:10:58.246778355 +0100
+++ gcc/testsuite/c-c++-common/pr70144-1.c	2016-03-09 13:10:04.000000000 +0100
@@ -0,0 +1,9 @@
+/* PR c++/70144 */
+/* { dg-do compile } */
+
+void
+foo ()
+{
+  __builtin_constant_p (__builtin_constant_p) ?: ({ unsigned t = 0; t; });	/* { dg-error "must be directly called" } */
+  __builtin_classify_type (__builtin_expect);	/* { dg-error "must be directly called" } */
+}
--- gcc/testsuite/c-c++-common/pr70144-2.c.jj	2016-03-09 13:31:28.354062276 +0100
+++ gcc/testsuite/c-c++-common/pr70144-2.c	2016-03-09 13:31:49.673773235 +0100
@@ -0,0 +1,12 @@
+/* PR c++/70144 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int
+main ()
+{
+  if (__builtin_constant_p (__builtin_memset) != 0
+      || __builtin_classify_type (__builtin_memset) != 5)
+    __builtin_abort ();
+  return 0;
+}


More information about the Gcc-patches mailing list