diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/c-parser.c | 3 | ||||
-rw-r--r-- | gcc/c-tree.h | 3 | ||||
-rw-r--r-- | gcc/c-typeck.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wcxx-compat-18.c | 15 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 2 |
7 files changed, 52 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 695547c..6b76ed3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-06-19 Ian Lance Taylor <ian@airs.com> + + * tree-cfg.c (gimple_redirect_edge_and_branch): Change ERROR_MARK + to GIMPLE_ERROR_MARK. + + * c-typeck.c (build_conditional_expr): Add op1_original_type and + op2_original_type parameters. Warn about using different enum + types. + * c-parser.c (c_parser_conditional_expression): Pass original + types to build_conditional_expr. + * c-tree.h (build_conditional_expr): Update declaration. + 2009-06-19 Ian Lance Taylor <iant@google.com> * config/i386/i386.c (ix86_function_specific_save): Test that diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 0fc1abb..29e399f 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -4597,7 +4597,8 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; ret.value = build_conditional_expr (colon_loc, cond.value, cond.original_code == C_MAYBE_CONST_EXPR, - exp1.value, exp2.value); + exp1.value, exp1.original_type, + exp2.value, exp2.original_type); ret.original_code = ERROR_MARK; if (exp1.value == error_mark_node || exp2.value == error_mark_node) ret.original_type = NULL; diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 9d3d2f3..c01cc66 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -556,7 +556,8 @@ extern struct c_expr parser_build_unary_op (location_t, enum tree_code, extern struct c_expr parser_build_binary_op (location_t, enum tree_code, struct c_expr, struct c_expr); -extern tree build_conditional_expr (location_t, tree, bool, tree, tree); +extern tree build_conditional_expr (location_t, tree, bool, tree, tree, + tree, tree); extern tree build_compound_expr (location_t, tree, tree); extern tree c_cast_expr (location_t, struct c_type_name *, tree); extern tree build_c_cast (location_t, tree, tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 0a40a88..df1e171 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3770,7 +3770,8 @@ c_mark_addressable (tree exp) tree build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, - tree op1, tree op2) + tree op1, tree op1_original_type, tree op2, + tree op2_original_type) { tree type1; tree type2; @@ -3843,6 +3844,20 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, } } + if (warn_cxx_compat) + { + tree t1 = op1_original_type ? op1_original_type : TREE_TYPE (orig_op1); + tree t2 = op2_original_type ? op2_original_type : TREE_TYPE (orig_op2); + + if (TREE_CODE (t1) == ENUMERAL_TYPE + && TREE_CODE (t2) == ENUMERAL_TYPE + && TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2)) + warning_at (colon_loc, OPT_Wc___compat, + ("different enum types in conditional is " + "invalid in C++: %qT vs %qT"), + t1, t2); + } + /* Quickly detect the usual case where op1 and op2 have the same type after promotion. */ if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e1ea0a33..4a1a8d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-06-19 Ian Lance Taylor <iant@google.com> + + * gcc.dg/Wcxx-compat-18.c: New testcase. + 2009-06-19 Richard Guenther <rguenther@suse.de> * gcc.c-torture/execute/20090618-1.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-18.c b/gcc/testsuite/gcc.dg/Wcxx-compat-18.c new file mode 100644 index 0000000..9ae2d77 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wcxx-compat-18.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-Wc++-compat" } */ +enum E1 { A }; +enum E2 { B }; +int +f1 (int i) +{ + return (int) (i ? A : B); /* { dg-warning "invalid in C\[+\]\[+\]" } */ +} +extern enum E1 f2(); +int +f3 (int i) +{ + return (int) (i ? f2 () : B); /* { dg-warning "invalid in C\[+\]\[+\]" } */ +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8470d76..4c7c0db 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4947,7 +4947,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) gsi = gsi_last_bb (bb); stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi); - switch (stmt ? gimple_code (stmt) : ERROR_MARK) + switch (stmt ? gimple_code (stmt) : GIMPLE_ERROR_MARK) { case GIMPLE_COND: /* For COND_EXPR, we only need to redirect the edge. */ |