diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
commit | e56043cd2c207982e812ce6fcecb7353dea58363 (patch) | |
tree | 01a6f37ad5a9ae6b18bdc20f052b04e19b4255c0 /gcc/cp/cvt.c | |
parent | 2e02a1a4548f2ee1ea519c88e68b20621ad16fcc (diff) | |
download | gcc-e56043cd2c207982e812ce6fcecb7353dea58363.tar.gz |
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 164348, with some improvements
in gcc/melt-runtime.[ch]
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
[[merged with trunk rev.164348, so improved MELT runtime!]]
* gcc/melt-runtime.h: improved comments.
(melt_debug_garbcoll, melt_debuggc_eprintf): Moved from melt-runtime.c.
(melt_obmag_string): New declaration.
(struct meltobject_st, struct meltclosure_st, struct
meltroutine_st, struct meltmixbigint_st, struct meltstring_st):
using GTY variable_size and @@MELTGTY@@ comment.
(melt_mark_special): added debug print.
* gcc/melt-runtime.c: Improved comments.
Include bversion.h, realmpfr.h, gimple-pretty-print.h.
(ggc_force_collect) Declared external.
(melt_forward_counter): Added.
(melt_obmag_string): New function.
(melt_alptr_1, melt_alptr_2, melt_break_alptr_1_at)
(melt_break_alptr_2_at, melt_break_alptr_1,melt_break_alptr_1)
(melt_allocate_young_gc_zone, melt_free_young_gc_zone): New.
(delete_special, meltgc_make_special): Improved debug printf and
use melt_break_alptr_1...
(ggc_alloc_*) macros defined for backport to GCC 4.5
(melt_forwarded_copy): Don't clear the new destination zone in old
GGC heap.
(meltgc_add_out_raw_len): Use ggc_alloc_atomic.
(meltgc_raw_new_mappointers, meltgc_raw_put_mappointers)
(meltgc_raw_remove_mappointers): Corrected length argument to
ggc_alloc_cleared_vec_entrypointermelt_st.
(melt_really_initialize): Call melt_allocate_young_gc_zone.
(melt_initialize): Set flag_plugin_added.
(melt_val2passflag): TODO_verify_loops only in GCC 4.5
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@164424 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/cvt.c')
-rw-r--r-- | gcc/cp/cvt.c | 354 |
1 files changed, 315 insertions, 39 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 6fcb1f0a19a..ab2b6bf2d70 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1,6 +1,6 @@ /* Language-level data type conversion for GNU C++. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) @@ -176,7 +176,7 @@ cp_convert_to_pointer (tree type, tree expr) else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) return convert_ptrmem (type, expr, /*allow_inverse_p=*/false, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); else if (TYPE_PTRMEMFUNC_P (intype)) { if (!warn_pmf2ptr) @@ -196,11 +196,11 @@ cp_convert_to_pointer (tree type, tree expr) return error_mark_node; } - if (integer_zerop (expr)) + if (null_ptr_cst_p (expr)) { if (TYPE_PTRMEMFUNC_P (type)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0, - /*c_cast_p=*/false); + /*c_cast_p=*/false, tf_warning_or_error); if (TYPE_PTRMEM_P (type)) { @@ -481,7 +481,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, else { rval = convert_for_initialization (NULL_TREE, type, expr, flags, - "converting", 0, 0, + ICR_CONVERTING, 0, 0, tf_warning_or_error); if (rval == NULL_TREE || rval == error_mark_node) return rval; @@ -610,6 +610,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) } e = integral_constant_value (e); + if (error_operand_p (e)) + return error_mark_node; if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP)) /* We need a new temporary; don't take this shortcut. */; @@ -649,7 +651,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error); + e = convert_to_void (e, ICV_CAST, tf_warning_or_error); return e; } @@ -680,7 +682,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) the original value is within the range of the enumeration values. Otherwise, the resulting enumeration value is unspecified. */ - if (TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, type)) + if (TREE_CODE (expr) == INTEGER_CST + && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type))) warning (OPT_Wconversion, "the result of the conversion is unspecified because " "%qE is outside the range of type %qT", @@ -701,6 +704,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags) return fold_if_not_in_template (convert_to_integer (type, e)); } + if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e)) + return nullptr_node; if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type)) return fold_if_not_in_template (cp_convert_to_pointer (type, e)); if (code == VECTOR_TYPE) @@ -809,17 +814,36 @@ ocp_convert (tree type, tree expr, int convtype, int flags) make it impossible to ignore the reference return value from functions. We issue warnings in the confusing cases. - IMPLICIT is non-NULL iff an expression is being implicitly converted; it - is NULL when the user is explicitly converting an expression to void via - a cast. When non-NULL, IMPLICIT is a string indicating the context of - the implicit conversion. */ + The IMPLICIT is ICV_CAST when the user is explicitly converting an expression + to void via a cast. If an expression is being implicitly converted, IMPLICIT + indicates the context of the implicit conversion. */ tree -convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) +convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { if (expr == error_mark_node || TREE_TYPE (expr) == error_mark_node) return error_mark_node; + + if (implicit == ICV_CAST) + mark_exp_read (expr); + else + { + tree exprv = expr; + + while (TREE_CODE (exprv) == COMPOUND_EXPR) + exprv = TREE_OPERAND (exprv, 1); + if (DECL_P (exprv) + || handled_component_p (exprv) + || TREE_CODE (exprv) == INDIRECT_REF) + /* Expr is not being 'used' here, otherwise we whould have + called mark_{rl}value_use use here, which would have in turn + called mark_exp_read. Rather, we call mark_exp_read directly + to avoid some warnings when + -Wunused-but-set-{variable,parameter} is in effect. */ + mark_exp_read (exprv); + } + if (!TREE_TYPE (expr)) return expr; if (invalid_nonstatic_memfn_p (expr, complain)) @@ -840,12 +864,17 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) tree op1 = TREE_OPERAND (expr,1); tree op2 = TREE_OPERAND (expr,2); bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2); - tree new_op1 = convert_to_void - (op1, (implicit && !side_effects - ? "second operand of conditional" : NULL), complain); - tree new_op2 = convert_to_void - (op2, (implicit && !side_effects - ? "third operand of conditional" : NULL), complain); + tree new_op1, new_op2; + if (implicit != ICV_CAST && !side_effects) + { + new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain); + new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain); + } + else + { + new_op1 = convert_to_void (op1, ICV_CAST, complain); + new_op2 = convert_to_void (op2, ICV_CAST, complain); + } expr = build3 (COND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1, new_op2); @@ -856,9 +885,11 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) { /* The second part of a compound expr contains the value. */ tree op1 = TREE_OPERAND (expr,1); - tree new_op1 = convert_to_void - (op1, (implicit && !TREE_NO_WARNING (expr) - ? "right-hand operand of comma" : NULL), complain); + tree new_op1; + if (implicit != ICV_CAST && !TREE_NO_WARNING (expr)) + new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain); + else + new_op1 = convert_to_void (op1, ICV_CAST, complain); if (new_op1 != op1) { @@ -890,18 +921,133 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (is_volatile && !is_complete) { if (complain & tf_warning) - warning (0, "object of incomplete type %qT will not be accessed in %s", - type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of incomplete type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in second operand " + "of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "incomplete type %qT in third operand " + "of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "incomplete type %qT in left operand of " + "comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "incomplete type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "incomplete type %qT in for increment " + "expression", type); + break; + default: + gcc_unreachable (); + } } /* Don't load the value if this is an implicit dereference, or if the type needs to be handled by ctors/dtors. */ - else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type))) + else if (is_volatile && is_reference) { if (complain & tf_warning) - warning (0, "object of type %qT will not be accessed in %s", - TREE_TYPE (TREE_OPERAND (expr, 0)), - implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of type %qT", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in second operand of " + "conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "implicit dereference will not access object " + "of type %qT in third operand of " + "conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in right operand of " + "comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "implicit dereference will not access object " + "of type %qT in left operand of comma operator", + type); + break; + case ICV_STATEMENT: + warning (0, "implicit dereference will not access object " + "of type %qT in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "implicit dereference will not access object " + "of type %qT in for increment expression", + type); + break; + default: + gcc_unreachable (); + } } + else if (is_volatile && TREE_ADDRESSABLE (type)) + { + if (complain & tf_warning) + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object of non-trivially-copyable type %qT", + type); + break; + case ICV_SECOND_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in second " + "operand of conditional expression", type); + break; + case ICV_THIRD_OF_COND: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in third " + "operand of conditional expression", type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in right " + "operand of comma operator", type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in left " + "operand of comma operator", type); + break; + case ICV_STATEMENT: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in statement", + type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "indirection will not access object of " + "non-trivially-copyable type %qT in for " + "increment expression", type); + break; + default: + gcc_unreachable (); + } + } if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type)) { /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF @@ -911,7 +1057,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) - automatic dereferencing of references, since the user cannot control it. (See also warn_if_unused_value() in stmt.c.) */ if (warn_unused_value - && implicit + && implicit != ICV_CAST && (complain & tf_warning) && !TREE_NO_WARNING (expr) && !is_reference) @@ -929,8 +1075,45 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) int is_complete = COMPLETE_TYPE_P (complete_type (type)); if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning)) - warning (0, "object %qE of incomplete type %qT will not be accessed in %s", - expr, type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_CAST: + warning (0, "conversion to void will not access " + "object %qE of incomplete type %qT", expr, type); + break; + case ICV_SECOND_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in second operand of " + "conditional expression", expr, type); + break; + case ICV_THIRD_OF_COND: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in third operand of " + "conditional expression", expr, type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in right operand of comma operator", + expr, type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in left operand of comma operator", + expr, type); + break; + case ICV_STATEMENT: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in statement", expr, type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "variable %qE of incomplete type %qT will not " + "be accessed in for increment expression", + expr, type); + break; + default: + gcc_unreachable (); + } + break; } @@ -969,18 +1152,81 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) /* [over.over] enumerates the places where we can take the address of an overloaded function, and this is not one of them. */ if (complain & tf_error) - error ("%s cannot resolve address of overloaded function", - implicit ? implicit : "void cast"); + switch (implicit) + { + case ICV_CAST: + error ("conversion to void " + "cannot resolve address of overloaded function"); + break; + case ICV_SECOND_OF_COND: + error ("second operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_OF_COND: + error ("third operand of conditional expression " + "cannot resolve address of overloaded function"); + break; + case ICV_RIGHT_OF_COMMA: + error ("right operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_LEFT_OF_COMMA: + error ("left operand of comma operator " + "cannot resolve address of overloaded function"); + break; + case ICV_STATEMENT: + error ("statement " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_IN_FOR: + error ("for increment expression " + "cannot resolve address of overloaded function"); + break; + } else return error_mark_node; expr = void_zero_node; } - else if (implicit && probe == expr && is_overloaded_fn (probe)) + else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe)) { /* Only warn when there is no &. */ if (complain & tf_warning) - warning (OPT_Waddress, "%s is a reference, not call, to function %qE", - implicit, expr); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Waddress, + "second operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Waddress, + "third operand of conditional expression " + "is a reference, not call, to function %qE", expr); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Waddress, + "right operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Waddress, + "left operand of comma operator " + "is a reference, not call, to function %qE", expr); + break; + case ICV_STATEMENT: + warning (OPT_Waddress, + "statement is a reference, not call, to function %qE", + expr); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Waddress, + "for increment expression " + "is a reference, not call, to function %qE", expr); + break; + default: + gcc_unreachable (); + } + if (TREE_CODE (expr) == COMPONENT_REF) expr = TREE_OPERAND (expr, 0); } @@ -988,7 +1234,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr))) { - if (implicit + if (implicit != ICV_CAST && warn_unused_value && !TREE_NO_WARNING (expr) && !processing_template_decl) @@ -997,7 +1243,35 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) been explicitly cast to void, so we must do so here. */ if (!TREE_SIDE_EFFECTS (expr)) { if (complain & tf_warning) - warning (OPT_Wunused_value, "%s has no effect", implicit); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Wunused_value, + "second operand of conditional expression has no effect"); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Wunused_value, + "third operand of conditional expression has no effect"); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Wunused_value, + "right operand of comma operator has no effect"); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Wunused_value, + "left operand of comma operator has no effect"); + break; + case ICV_STATEMENT: + warning (OPT_Wunused_value, + "statement has no effect"); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Wunused_value, + "for increment expression has no effect"); + break; + default: + gcc_unreachable (); + } } else { @@ -1102,7 +1376,7 @@ convert_force (tree type, tree expr, int convtype) && TYPE_PTRMEMFUNC_P (type)) /* compatible pointer to member functions. */ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1, - /*c_cast_p=*/1); + /*c_cast_p=*/1, tf_warning_or_error); return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); } @@ -1194,7 +1468,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) /* The code for conversions from class type is currently only used for delete expressions. Other expressions are handled by build_new_op. */ - if (!complete_type_or_else (basetype, expr)) + if (!complete_type_or_maybe_complain (basetype, expr, complain)) return error_mark_node; if (!TYPE_HAS_CONVERSION (basetype)) return NULL_TREE; @@ -1309,6 +1583,8 @@ type_promotes_to (tree type) int precision = MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)); tree totype = c_common_type_for_size (precision, 0); + if (TREE_CODE (type) == ENUMERAL_TYPE) + type = ENUM_UNDERLYING_TYPE (type); if (TYPE_UNSIGNED (type) && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) type = c_common_type_for_size (precision, 1); |