aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-03-17 16:58:22 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-03-17 16:58:22 +0100
commit17366700d4ddcefeb271677029f59646a37a8ed3 (patch)
tree52d1bd6074582ad1e848033093f2d9815718e554 /gcc
parenta3aad0e69c4f3f66a51c03c50c48c0d083db96f7 (diff)
downloadgcc-17366700d4ddcefeb271677029f59646a37a8ed3.zip
gcc-17366700d4ddcefeb271677029f59646a37a8ed3.tar.gz
gcc-17366700d4ddcefeb271677029f59646a37a8ed3.tar.bz2
re PR tree-optimization/70144 (g++ ICE at -O1 and above on valid code on x86_64-linux-gnu in "copy_reference_ops_from_ref")
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. From-SVN: r234297
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/call.c32
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/c-c++-common/pr70144-1.c9
-rw-r--r--gcc/testsuite/c-c++-common/pr70144-2.c12
6 files changed, 58 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fa3917c..15ca9a4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,15 @@
2016-03-17 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.
+
PR c++/70272
* decl.c (begin_destructor_body): Don't insert clobber if
is_empty_class (current_class_type).
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3ad3bd5..1edbce8 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7040,15 +7040,17 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
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 *cand, int flags, tsubst_flags_t complain)
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 *cand, int flags, tsubst_flags_t complain)
}
else
a = convert_arg_to_ellipsis (a, complain);
+ if (a == error_mark_node)
+ return error_mark_node;
argarray[j++] = a;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a08c59b..15b004d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 55035d1..7fe7295 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2016-03-17 Jakub Jelinek <jakub@redhat.com>
+ PR c++/70144
+ * c-c++-common/pr70144-1.c: New test.
+ * c-c++-common/pr70144-2.c: New test.
+
PR c++/70272
* g++.dg/opt/flifetime-dse5.C (main): Remove extra semicolon.
* g++.dg/opt/flifetime-dse6.C: New test.
diff --git a/gcc/testsuite/c-c++-common/pr70144-1.c b/gcc/testsuite/c-c++-common/pr70144-1.c
new file mode 100644
index 0000000..01c7b78
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr70144-1.c
@@ -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" } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr70144-2.c b/gcc/testsuite/c-c++-common/pr70144-2.c
new file mode 100644
index 0000000..0973b79
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr70144-2.c
@@ -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;
+}