diff options
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 56 |
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 |