This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ RFC] magic_varargs_p issues (PR c++/70144)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Mar 2016 18:07:46 +0100
- Subject: Re: [C++ RFC] magic_varargs_p issues (PR c++/70144)
- Authentication-results: sourceware.org; auth=none
- References: <20160309171831 dot GO3017 at tucnak dot redhat dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Wed, Mar 09, 2016 at 06:18:31PM +0100, Jakub Jelinek wrote:
> 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.
I've also successfully bootstrapped/regtested the other patch (though,
at least the
+ if (a == error_mark_node)
+ return error_mark_node;
hunk should be added in there too, and finally attached patch, which is
the combination of the two, use the first patch for Cilk+ reductions
and second otherwise. I've noticed that convert_arguments also checks
magic_varargs_p, but I don't understand much the relationship of
build_over_call and convert_arguments, are those used either one, or another
one, and so all this should be in both?
2016-03-09 Jakub Jelinek <jakub@redhat.com>
PR c++/70144
* cp-tree.h (magic_varargs_p): Return int instead of bool.
* call.c (magic_varargs_p): Return int instead of bool, return 2 for
Cilk+ reductions, otherwise 1 for magic varargs and 0 for normal
varargs.
(build_over_call): If magic_varargs_p == 2, call reject_gcc_builtin,
if magic_varargs_p == 1, 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/cp-tree.h.jj 2016-03-05 07:46:50.000000000 +0100
+++ gcc/cp/cp-tree.h 2016-03-10 16:17:21.121129641 +0100
@@ -5563,7 +5563,7 @@ public:
/* in call.c */
extern bool check_dtor_name (tree, tree);
-bool magic_varargs_p (tree);
+int magic_varargs_p (tree);
extern tree build_conditional_expr (location_t, tree, tree, tree,
tsubst_flags_t);
--- gcc/cp/call.c.jj 2016-03-09 15:06:21.697396705 +0100
+++ gcc/cp/call.c 2016-03-10 16:08:12.850558154 +0100
@@ -7040,15 +7040,17 @@ convert_for_arg_passing (tree type, tree
return val;
}
-/* Returns true iff FN is a function with magic varargs, i.e. ones for
- which no conversions at all should be done. This is true for some
- builtins which don't act like normal functions. */
+/* Returns non-zero iff FN is a function with magic varargs, i.e. ones for
+ which just decay_conversion or no conversions at all should be done.
+ This is true for some builtins which don't act like normal functions.
+ Return 2 if no conversions at all should be done, 1 if just
+ decay_conversion. */
-bool
+int
magic_varargs_p (tree fn)
{
if (flag_cilkplus && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
- return true;
+ return 2;
if (DECL_BUILT_IN (fn))
switch (DECL_FUNCTION_CODE (fn))
@@ -7057,14 +7059,14 @@ magic_varargs_p (tree fn)
case BUILT_IN_CONSTANT_P:
case BUILT_IN_NEXT_ARG:
case BUILT_IN_VA_START:
- return true;
+ return 1;
default:;
return lookup_attribute ("type generic",
TYPE_ATTRIBUTES (TREE_TYPE (fn))) != 0;
}
- return false;
+ return 0;
}
/* Returns the decl of the dispatcher function if FN is a function version. */
@@ -7515,9 +7517,17 @@ build_over_call (struct z_candidate *can
for (; arg_index < vec_safe_length (args); ++arg_index)
{
tree a = (*args)[arg_index];
- if (magic_varargs_p (fn))
- /* Do no conversions for magic varargs. */
- a = mark_type_use (a);
+ int magic = magic_varargs_p (fn);
+ if (magic == 2)
+ {
+ /* Do no conversions for certain magic varargs. */
+ a = mark_type_use (a);
+ if (TREE_CODE (a) == FUNCTION_DECL && reject_gcc_builtin (a))
+ return error_mark_node;
+ }
+ else if (magic == 1)
+ /* For other 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 +7540,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;
+}
Jakub