diff options
author | Shujing Zhao <pearly.zhao@oracle.com> | 2010-07-06 05:53:49 +0000 |
---|---|---|
committer | Shujing Zhao <pzhao@gcc.gnu.org> | 2010-07-06 05:53:49 +0000 |
commit | ebeb2c24db1596f623b3b421f9172deea0d35194 (patch) | |
tree | 92954e8b35bbd7a6aa016c7a22bb701b2b4050f5 /gcc | |
parent | c021f10b188584445b45ec9649cff4d39e640c3e (diff) | |
download | gcc-ebeb2c24db1596f623b3b421f9172deea0d35194.zip gcc-ebeb2c24db1596f623b3b421f9172deea0d35194.tar.gz gcc-ebeb2c24db1596f623b3b421f9172deea0d35194.tar.bz2 |
cp-tree.h (impl_conv_void): New type.
/cp
2010-07-06 Shujing Zhao <pearly.zhao@oracle.com>
* cp-tree.h (impl_conv_void): New type.
(convert_to_void): Adjust prototype.
* cvt.c (convert_to_void): Use impl_conv_void, emit and adjust the
diagnostic for easy translation. Change caller.
* typeck.c: Update call to convert_to_void.
* semantics.c: Likewise.
* init.c: Likewise.
/testsuite
2010-07-06 Shujing Zhao <pearly.zhao@oracle.com>
* g++.dg/warn/noeffect2.C: Adjust expected warning.
* g++.dg/warn/volatile1.C: Likewise.
* g++.dg/template/warn1.C: Likewise.
From-SVN: r161863
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 15 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 313 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/warn1.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/noeffect2.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/volatile1.C | 2 |
10 files changed, 324 insertions, 48 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f2cac1..85e8209 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2010-07-06 Shujing Zhao <pearly.zhao@oracle.com> + + * cp-tree.h (impl_conv_void): New type. + (convert_to_void): Adjust prototype. + * cvt.c (convert_to_void): Use impl_conv_void, emit and adjust the + diagnostic for easy translation. Change caller. + * typeck.c: Update call to convert_to_void. + * semantics.c: Likewise. + * init.c: Likewise. + 2010-07-05 Nathan Froyd <froydnj@codesourcery.com> * decl.c (cp_finish_decl): Call add_local_decl. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1d9077c..004a854 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -435,6 +435,17 @@ typedef enum impl_conv_rhs { ICR_ASSIGN /* assignment */ } impl_conv_rhs; +/* Possible cases of implicit or explicit bad conversions to void. */ +typedef enum impl_conv_void { + ICV_CAST, /* (explicit) conversion to void */ + ICV_SECOND_OF_COND, /* second operand of conditional expression */ + ICV_THIRD_OF_COND, /* third operand of conditional expression */ + ICV_RIGHT_OF_COMMA, /* right operand of comma operator */ + ICV_LEFT_OF_COMMA, /* left operand of comma operator */ + ICV_STATEMENT, /* statement */ + ICV_THIRD_IN_FOR /* for increment expression */ +} impl_conv_void; + /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ @@ -4697,8 +4708,8 @@ extern tree ocp_convert (tree, tree, int, int); extern tree cp_convert (tree, tree); extern tree cp_convert_and_check (tree, tree); extern tree cp_fold_convert (tree, tree); -extern tree convert_to_void (tree, const char */*implicit context*/, - tsubst_flags_t); +extern tree convert_to_void (tree, impl_conv_void, + tsubst_flags_t); extern tree convert_force (tree, tree, int); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 40a6351..4fcba45 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -651,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; } @@ -814,19 +814,18 @@ 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 == NULL) + if (implicit == ICV_CAST) mark_exp_read (expr); else { @@ -865,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); @@ -881,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) { @@ -915,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 @@ -936,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) @@ -954,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; } @@ -994,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); } @@ -1013,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) @@ -1022,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 { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 85ad582..ec7dca9 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1374,7 +1374,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, release_tree_vector (parms); if (TREE_SIDE_EFFECTS (rval)) - finish_expr_stmt (convert_to_void (rval, NULL, complain)); + finish_expr_stmt (convert_to_void (rval, ICV_CAST, complain)); } /* This function is responsible for initializing EXP with INIT @@ -2726,7 +2726,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */ body = build2 (COMPOUND_EXPR, void_type_node, base, body); - return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error); + return convert_to_void (body, ICV_CAST, tf_warning_or_error); } /* Create an unnamed variable of the indicated TYPE. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 156f278..887bb42 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -607,10 +607,10 @@ finish_expr_stmt (tree expr) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "statement", tf_warning_or_error); + expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "statement", + convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, tf_warning_or_error); if (check_for_bare_parameter_packs (expr)) @@ -868,11 +868,11 @@ finish_for_expr (tree expr, tree for_stmt) { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "3rd expression in for", + expr = convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "3rd expression in for", + convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR, tf_warning_or_error); expr = maybe_cleanup_point_expr_void (expr); if (check_for_bare_parameter_packs (expr)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ec0b06d..fd8221c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5591,7 +5591,7 @@ build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs) tree cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain) { - lhs = convert_to_void (lhs, "left-hand operand of comma", complain); + lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain); if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -5858,7 +5858,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, Any expression can be explicitly converted to type cv void. */ if (TREE_CODE (type) == VOID_TYPE) - return convert_to_void (expr, /*implicit=*/NULL, complain); + return convert_to_void (expr, ICV_CAST, complain); /* [expr.static.cast] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24b8ccd..d0b1b14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-07-06 Shujing Zhao <pearly.zhao@oracle.com> + + * g++.dg/warn/noeffect2.C: Adjust expected warning. + * g++.dg/warn/volatile1.C: Likewise. + * g++.dg/template/warn1.C: Likewise. + 2010-07-05 H.J. Lu <hongjiu.lu@intel.com> AVX Programming Reference (June, 2010) diff --git a/gcc/testsuite/g++.dg/template/warn1.C b/gcc/testsuite/g++.dg/template/warn1.C index 0cdffcd..2b804f7 100644 --- a/gcc/testsuite/g++.dg/template/warn1.C +++ b/gcc/testsuite/g++.dg/template/warn1.C @@ -9,8 +9,8 @@ template <class T> void Foo(T i) { i++, i++; - i, i++; // { dg-warning "left-hand operand" "" } - i++, i; // { dg-warning "right-hand operand" "" } + i, i++; // { dg-warning "left operand" "" } + i++, i; // { dg-warning "right operand" "" } for (;; --i, ++i) ; } diff --git a/gcc/testsuite/g++.dg/warn/noeffect2.C b/gcc/testsuite/g++.dg/warn/noeffect2.C index 0132365..451e038 100644 --- a/gcc/testsuite/g++.dg/warn/noeffect2.C +++ b/gcc/testsuite/g++.dg/warn/noeffect2.C @@ -10,11 +10,11 @@ extern "C" void FormatDisk(); template <class T> struct C { - C(){ FormatDisk(), 0; } // { dg-warning "right-hand operand of comma" "" } + C(){ FormatDisk(), 0; } // { dg-warning "right operand of comma" "" } }; template struct C<int>; // { dg-message "instantiated" } template <class T> - void f() { FormatDisk(), 0; } // { dg-warning "right-hand operand of comma" "" } + void f() { FormatDisk(), 0; } // { dg-warning "right operand of comma" "" } template void f<int> (); // { dg-message "instantiated" } -void g() { FormatDisk(), 0; } // { dg-warning "right-hand operand of comma" "" } +void g() { FormatDisk(), 0; } // { dg-warning "right operand of comma" "" } diff --git a/gcc/testsuite/g++.dg/warn/volatile1.C b/gcc/testsuite/g++.dg/warn/volatile1.C index 5b1050f..ac9dd4d 100644 --- a/gcc/testsuite/g++.dg/warn/volatile1.C +++ b/gcc/testsuite/g++.dg/warn/volatile1.C @@ -8,5 +8,5 @@ struct A }; void A::baz() volatile { - *this; // { dg-warning "will not be accessed" } + *this; // { dg-warning "indirection will not access" } } |