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.c113
1 files changed, 70 insertions, 43 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9d89c467462..b3ce65c403c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -559,7 +559,7 @@ null_ptr_cst_p (tree t)
{
/* Core issue 903 says only literal 0 is a null pointer constant. */
if (cxx_dialect < cxx0x)
- t = maybe_constant_value (t);
+ t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none));
STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t))
return true;
@@ -1280,7 +1280,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
static_fn_type (tofn)))
return NULL;
- from = build_memfn_type (fromfn, tbase, cp_type_quals (tbase));
+ from = build_memfn_type (fromfn,
+ tbase,
+ cp_type_quals (tbase),
+ type_memfn_rqual (tofn));
from = build_ptrmemfunc_type (build_pointer_type (from));
conv = build_conv (ck_pmem, from, conv);
conv->base_p = true;
@@ -1954,7 +1957,19 @@ add_function_candidate (struct z_candidate **candidates,
{
parmtype = cp_build_qualified_type
(ctype, cp_type_quals (TREE_TYPE (parmtype)));
- parmtype = build_pointer_type (parmtype);
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
+ {
+ /* If the function has a ref-qualifier, the implicit
+ object parameter has reference type. */
+ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
+ parmtype = cp_build_reference_type (parmtype, rv);
+ }
+ else
+ {
+ parmtype = build_pointer_type (parmtype);
+ arg = build_this (arg);
+ argtype = lvalue_type (arg);
+ }
}
/* Core issue 899: When [copy-]initializing a temporary to be bound
@@ -3451,6 +3466,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
int ctorflags = flags;
first_arg = build_int_cst (build_pointer_type (totype), 0);
+ first_arg = build_fold_indirect_ref (first_arg);
/* We should never try to call the abstract or base constructor
from here. */
@@ -3492,7 +3508,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
}
if (conv_fns)
- first_arg = build_this (expr);
+ first_arg = expr;
for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
{
@@ -4072,7 +4088,7 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, enum call_context spawning,
if (fns)
{
- first_mem_arg = build_this (obj);
+ first_mem_arg = obj;
add_candidates (BASELINK_FUNCTIONS (fns),
first_mem_arg, *args, NULL_TREE,
@@ -4568,8 +4584,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
|| (conv2 && conv2->kind == ck_ambig)
|| (conv3 && conv3->kind == ck_ambig))
{
- error ("operands to ?: have different types %qT and %qT",
- arg2_type, arg3_type);
+ if (complain & tf_error)
+ error ("operands to ?: have different types %qT and %qT",
+ arg2_type, arg3_type);
result = error_mark_node;
}
else if (conv2 && (!conv2->bad_p || !conv3))
@@ -4751,10 +4768,11 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
/* In this case, there is always a common type. */
result_type = type_after_usual_arithmetic_conversions (arg2_type,
arg3_type);
- do_warn_double_promotion (result_type, arg2_type, arg3_type,
- "implicit conversion from %qT to %qT to "
- "match other result of conditional",
- input_location);
+ if (complain & tf_warning)
+ do_warn_double_promotion (result_type, arg2_type, arg3_type,
+ "implicit conversion from %qT to %qT to "
+ "match other result of conditional",
+ input_location);
if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
&& TREE_CODE (arg3_type) == ENUMERAL_TYPE)
@@ -4936,7 +4954,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
is considered to be a member of the class of the implicit
object argument for the purpose of defining the type of
the implicit object parameter. */
- ctype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (first_arg)));
+ ctype = TYPE_MAIN_VARIANT (TREE_TYPE (first_arg));
}
else
{
@@ -4990,7 +5008,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
for (ix = 1; args->iterate (ix, &arg); ++ix)
tempvec->quick_push (arg);
non_static_args = tempvec;
- first_arg = build_this ((*args)[0]);
+ first_arg = (*args)[0];
}
fn_first_arg = first_arg;
@@ -5094,8 +5112,8 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
if (code == COND_EXPR)
/* Use build_conditional_expr instead. */
gcc_unreachable ();
- else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
- && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
+ else if (! OVERLOAD_TYPE_P (TREE_TYPE (arg1))
+ && (! arg2 || ! OVERLOAD_TYPE_P (TREE_TYPE (arg2))))
goto builtin;
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
@@ -6731,16 +6749,18 @@ build_over_call (struct z_candidate *cand, int flags,
resolution, and must be of the proper type. */
if (DECL_CONSTRUCTOR_P (fn))
{
+ tree object_arg;
if (first_arg != NULL_TREE)
{
- argarray[j++] = first_arg;
+ object_arg = first_arg;
first_arg = NULL_TREE;
}
else
{
- argarray[j++] = (*args)[arg_index];
+ object_arg = (*args)[arg_index];
++arg_index;
}
+ argarray[j++] = build_this (object_arg);
parm = TREE_CHAIN (parm);
/* We should never try to call the abstract constructor. */
gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
@@ -6756,9 +6776,9 @@ build_over_call (struct z_candidate *cand, int flags,
else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
{
tree parmtype = TREE_VALUE (parm);
- tree arg = (first_arg != NULL_TREE
- ? first_arg
- : (*args)[arg_index]);
+ tree arg = build_this (first_arg != NULL_TREE
+ ? first_arg
+ : (*args)[arg_index]);
tree argtype = TREE_TYPE (arg);
tree converted_arg;
tree base_binfo;
@@ -6794,9 +6814,14 @@ build_over_call (struct z_candidate *cand, int flags,
/* Check that the base class is accessible. */
if (!accessible_base_p (TREE_TYPE (argtype),
BINFO_TYPE (cand->conversion_path), true))
- error ("%qT is not an accessible base of %qT",
- BINFO_TYPE (cand->conversion_path),
- TREE_TYPE (argtype));
+ {
+ if (complain & tf_error)
+ error ("%qT is not an accessible base of %qT",
+ BINFO_TYPE (cand->conversion_path),
+ TREE_TYPE (argtype));
+ else
+ return error_mark_node;
+ }
/* If fn was found by a using declaration, the conversion path
will be to the derived class, not the base declaring fn. We
must convert from derived to base. */
@@ -7429,7 +7454,6 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
tree access_binfo;
tree optype;
tree first_mem_arg = NULL_TREE;
- tree instance_ptr;
tree name;
bool skip_first_for_error;
vec<tree, va_gc> *user_args;
@@ -7537,22 +7561,27 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
return error_mark_node;
}
- instance_ptr = build_this (instance);
+ /* Consider the object argument to be used even if we end up selecting a
+ static member function. */
+ instance = mark_type_use (instance);
/* It's OK to call destructors and constructors on cv-qualified objects.
- Therefore, convert the INSTANCE_PTR to the unqualified type, if
+ Therefore, convert the INSTANCE to the unqualified type, if
necessary. */
if (DECL_DESTRUCTOR_P (fn)
|| DECL_CONSTRUCTOR_P (fn))
{
- tree type = build_pointer_type (basetype);
- if (!same_type_p (type, TREE_TYPE (instance_ptr)))
- instance_ptr = build_nop (type, instance_ptr);
+ if (!same_type_p (basetype, TREE_TYPE (instance)))
+ {
+ instance = build_this (instance);
+ instance = build_nop (build_pointer_type (basetype), instance);
+ instance = build_fold_indirect_ref (instance);
+ }
}
if (DECL_DESTRUCTOR_P (fn))
name = complete_dtor_identifier;
- first_mem_arg = instance_ptr;
+ first_mem_arg = instance;
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
@@ -7588,11 +7617,10 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (init)
{
- tree ob;
- if (integer_zerop (instance_ptr))
+ if (TREE_CODE (instance) == INDIRECT_REF
+ && integer_zerop (TREE_OPERAND (instance, 0)))
return get_target_expr_sfinae (init, complain);
- ob = build_fold_indirect_ref (instance_ptr);
- init = build2 (INIT_EXPR, TREE_TYPE (ob), ob, init);
+ init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
TREE_SIDE_EFFECTS (init) = true;
return init;
}
@@ -7617,11 +7645,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (complain & tf_error)
{
if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
- cxx_incomplete_type_error (instance_ptr, basetype);
+ cxx_incomplete_type_error (instance, basetype);
else if (optype)
error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
basetype, optype, build_tree_list_vec (user_args),
- TREE_TYPE (TREE_TYPE (instance_ptr)));
+ TREE_TYPE (instance));
else
{
char *pretty_name;
@@ -7634,7 +7662,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
arglist = TREE_CHAIN (arglist);
error ("no matching function for call to %<%T::%s(%A)%#V%>",
basetype, pretty_name, arglist,
- TREE_TYPE (TREE_TYPE (instance_ptr)));
+ TREE_TYPE (instance));
if (free_p)
free (pretty_name);
}
@@ -7684,7 +7712,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
fn);
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
- && is_dummy_object (instance_ptr))
+ && is_dummy_object (instance))
{
instance = maybe_resolve_dummy (instance);
if (instance == error_mark_node)
@@ -7693,8 +7721,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
{
/* We captured 'this' in the current lambda now that
we know we really need it. */
- instance_ptr = build_this (instance);
- cand->first_arg = instance_ptr;
+ cand->first_arg = instance;
}
else
{
@@ -7729,10 +7756,10 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
out to be a static member function, `a' is
none-the-less evaluated. */
if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
- && !is_dummy_object (instance_ptr)
- && TREE_SIDE_EFFECTS (instance_ptr))
+ && !is_dummy_object (instance)
+ && TREE_SIDE_EFFECTS (instance))
call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
- instance_ptr, call);
+ instance, call);
else if (call != error_mark_node
&& DECL_DESTRUCTOR_P (cand->fn)
&& !VOID_TYPE_P (TREE_TYPE (call)))