summaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e8d526075a7..3ed73b80374 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1314,7 +1314,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
/* As an extension, allow conversion to complex type. */
else if (ARITHMETIC_TYPE_P (to))
{
- if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)
+ if (! (INTEGRAL_CODE_P (fcode)
+ || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
|| SCOPED_ENUM_P (from))
return NULL;
conv = build_conv (ck_std, to, conv);
@@ -1681,7 +1682,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
resolution, or after we've chosen one. */
flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
|LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
- |LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
+ |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL);
/* FIXME: actually we don't want warnings either, but we can't just
have 'complain &= ~(tf_warning|tf_error)' because it would cause
@@ -7176,6 +7177,33 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
&& !check_builtin_function_arguments (fndecl, nargs, argarray))
return error_mark_node;
+ /* If it is a built-in array notation function, then the return type of
+ the function is the element type of the array passed in as array
+ notation (i.e. the first parameter of the function). */
+ if (flag_enable_cilkplus && TREE_CODE (fn) == CALL_EXPR)
+ {
+ enum built_in_function bif =
+ is_cilkplus_reduce_builtin (CALL_EXPR_FN (fn));
+ if (bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ADD
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUL
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ {
+ /* for bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ The pre-defined return-type is the correct one. */
+ tree array_ntn = CALL_EXPR_ARG (fn, 0);
+ TREE_TYPE (fn) = TREE_TYPE (array_ntn);
+ return fn;
+ }
+ }
+
/* Some built-in function calls will be evaluated at compile-time in
fold (). Set optimize to 1 when folding __builtin_constant_p inside
a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
@@ -7414,6 +7442,14 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
if (allocated != NULL)
release_tree_vector (allocated);
+ if ((complain & tf_error)
+ && (flags & LOOKUP_DELEGATING_CONS)
+ && name == complete_ctor_identifier
+ && TREE_CODE (ret) == CALL_EXPR
+ && (DECL_ABSTRACT_ORIGIN (TREE_OPERAND (CALL_EXPR_FN (ret), 0))
+ == current_function_decl))
+ error ("constructor delegates to itself");
+
return ret;
}
@@ -7640,7 +7676,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (init)
{
- if (TREE_CODE (instance) == INDIRECT_REF
+ if (INDIRECT_REF_P (instance)
&& integer_zerop (TREE_OPERAND (instance, 0)))
return get_target_expr_sfinae (init, complain);
init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
@@ -9282,10 +9318,14 @@ initialize_reference (tree type, tree expr,
return error_mark_node;
}
- gcc_assert (conv->kind == ck_ref_bind);
-
- /* Perform the conversion. */
- expr = convert_like (conv, expr, complain);
+ if (conv->kind == ck_ref_bind)
+ /* Perform the conversion. */
+ expr = convert_like (conv, expr, complain);
+ else if (conv->kind == ck_ambig)
+ /* We gave an error in build_user_type_conversion_1. */
+ expr = error_mark_node;
+ else
+ gcc_unreachable ();
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@@ -9392,6 +9432,8 @@ is_std_init_list (tree type)
/* Look through typedefs. */
if (!TYPE_P (type))
return false;
+ if (cxx_dialect == cxx98)
+ return false;
type = TYPE_MAIN_VARIANT (type);
return (CLASS_TYPE_P (type)
&& CP_TYPE_CONTEXT (type) == std_node