OSDN Git Service

./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jun 2009 20:55:27 +0000 (20:55 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jun 2009 20:55:27 +0000 (20:55 +0000)
* 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.
testsuite/:
* gcc.dg/Wcxx-compat-18.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148727 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-parser.c
gcc/c-tree.h
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wcxx-compat-18.c [new file with mode: 0644]
gcc/tree-cfg.c

index 695547c..6b76ed3 100644 (file)
@@ -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
index 0fc1abb..29e399f 100644 (file)
@@ -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;
index 9d3d2f3..c01cc66 100644 (file)
@@ -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);
index 0a40a88..df1e171 100644 (file)
@@ -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))
index e1ea0a3..4a1a8d3 100644 (file)
@@ -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 (file)
index 0000000..9ae2d77
--- /dev/null
@@ -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\[+\]\[+\]" } */
+}
index 8470d76..4c7c0db 100644 (file)
@@ -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.  */