re PR c++/11512 (Spurious warning for comma-operator in templates)
authorNathan Sidwell <nathan@codesourcery.com>
Sat, 16 Aug 2003 13:32:11 +0000 (13:32 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sat, 16 Aug 2003 13:32:11 +0000 (13:32 +0000)
PR c++/11512
* stmt.c (expand_expr_stmt_value): Don't warn about any void
typed expression.
cp:
PR c++/11512
* cvt.c (convert_to_void): Indicate which side of conditional has
no effects, and rhs of comma operator. Test for no sideeffect
expressions here and always build a convert expr.
* init.c (expand_default_init): Convert the init to void.
* typeck.c (build_x_compound_expr): Do not check for side effects
here.
(build_compound_expr): Do not convert lhs when building a
template.
testsuite:
PR C++/11512
* g++.dg/template/warn1.C: New.

From-SVN: r70505

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/init.c
gcc/cp/typeck.c
gcc/stmt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/warn1.C [new file with mode: 0644]

index a88550421367532caa819342add6d947d756d8b9..d764ebf6e07d453066d3e4161a985a19fc2f654c 100644 (file)
@@ -1,3 +1,9 @@
+2003-08-16  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/11512
+       * stmt.c (expand_expr_stmt_value): Don't warn about any void
+       typed expression.
+
 2003-08-16  Jan Hubicka  <jh@suse.cz>
 
        * i386.c (ix86_fntype_regparm): Rename from ...
index e6c0bfb7566957ff8cecf097c5a4d9bc7ed1d503..1651a9e579d97612090cde718ffeb182cd1f02a5 100644 (file)
@@ -1,3 +1,15 @@
+2003-08-16  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/11512
+       * cvt.c (convert_to_void): Indicate which side of conditional has
+       no effects, and rhs of comma operator. Test for no sideeffect
+       expressions here and always build a convert expr.
+       * init.c (expand_default_init): Convert the init to void.
+       * typeck.c (build_x_compound_expr): Do not check for side effects
+       here.
+       (build_compound_expr): Do not convert lhs when building a
+       template.
+
 2003-08-15  Nathan Sidwell  <nathan@codesourcery.com>
 
        * cp-tree.def (NON_DEPENDENT_EXPR): Add operand.
index 2cdf39535349221ecd2c2e8a4a8400d4afe3c755..0a8e4789b29ef1a55d657e03f6a114d9b9ee21a0 100644 (file)
@@ -812,8 +812,12 @@ convert_to_void (tree expr, const char *implicit)
         /* The two parts of a cond expr might be separate lvalues.  */
         tree op1 = TREE_OPERAND (expr,1);
         tree op2 = TREE_OPERAND (expr,2);
-        tree new_op1 = convert_to_void (op1, implicit);
-        tree new_op2 = convert_to_void (op2, implicit);
+        tree new_op1 = convert_to_void
+         (op1, (implicit && !TREE_SIDE_EFFECTS (op2)
+                ? "second operand of conditional" : NULL));
+        tree new_op2 = convert_to_void
+         (op2, (implicit && !TREE_SIDE_EFFECTS (op1)
+                ? "third operand of conditional" : NULL));
         
        expr = build (COND_EXPR, TREE_TYPE (new_op1),
                      TREE_OPERAND (expr, 0), new_op1, new_op2);
@@ -824,7 +828,8 @@ convert_to_void (tree expr, const char *implicit)
       {
         /* 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 new_op1 = convert_to_void
+         (op1, implicit ? "right-hand operand of comma" : NULL);
         
         if (new_op1 != op1)
          {
@@ -901,13 +906,9 @@ convert_to_void (tree expr, const char *implicit)
   
   if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
     {
-      /* FIXME: This is where we should check for expressions with no
-         effects.  At the moment we do that in both build_x_component_expr
-         and expand_expr_stmt -- inconsistently too.  For the moment
-         leave implicit void conversions unadorned so that expand_expr_stmt
-         has a chance of detecting some of the cases.  */
-      if (!implicit)
-        expr = build1 (CONVERT_EXPR, void_type_node, expr);
+      if (implicit && !TREE_SIDE_EFFECTS (expr) && warn_unused_value)
+       warning ("%s has no effect", implicit);
+      expr = build1 (CONVERT_EXPR, void_type_node, expr);
     }
   return expr;
 }
index 95824516c8a6bd9c51d0a0b177f3b8bf8010cd90..c2b371114e3db135007bb9ea6cd2013d02cb0942 100644 (file)
@@ -1229,7 +1229,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
 
   rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
   if (TREE_SIDE_EFFECTS (rval))
-    finish_expr_stmt (rval);
+    finish_expr_stmt (convert_to_void (rval, NULL));
 }
 
 /* This function is responsible for initializing EXP with INIT
index f89b74ac2f6a9d277c548b947d224f59b6b5c887..21186ebca818468671d000664501f1ba747dd24e 100644 (file)
@@ -4296,21 +4296,7 @@ build_x_compound_expr (tree op1, tree op2)
 
   result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE);
   if (!result)
-    {
-      if (! TREE_SIDE_EFFECTS (op1))
-       {
-         /* FIXME: This test should be in the implicit cast to void
-            of the LHS.  */
-         /* the left-hand operand of a comma expression is like an expression
-            statement: we should warn if it doesn't have any side-effects,
-            unless it was explicitly cast to (void).  */
-         if (warn_unused_value
-             && !(TREE_CODE (op1) == CONVERT_EXPR
-                  && VOID_TYPE_P (TREE_TYPE (op1))))
-           warning("left-hand operand of comma expression has no effect");
-       }
-      result = build_compound_expr (op1, op2);
-    }
+    result = build_compound_expr (op1, op2);
 
   if (processing_template_decl && result != error_mark_node)
     return build_min (COMPOUND_EXPR, TREE_TYPE (result), 
@@ -4323,18 +4309,22 @@ build_x_compound_expr (tree op1, tree op2)
 tree
 build_compound_expr (tree lhs, tree rhs)
 {
-  lhs = decl_constant_value (lhs);
-  lhs = convert_to_void (lhs, "left-hand operand of comma");
+  if (!processing_template_decl)
+    {
+      lhs = decl_constant_value (lhs);
+      lhs = convert_to_void (lhs, "left-hand operand of comma");
+    }
+  
   if (lhs == error_mark_node || rhs == error_mark_node)
     return error_mark_node;
-
+  
   if (TREE_CODE (rhs) == TARGET_EXPR)
     {
       /* If the rhs is a TARGET_EXPR, then build the compound
          expression inside the target_expr's initializer. This
         helps the compiler to eliminate unncessary temporaries.  */
       tree init = TREE_OPERAND (rhs, 1);
-
+      
       init = build (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
       TREE_OPERAND (rhs, 1) = init;
       
index 81661873c2c92a6610eed84024728260fa88c900..defbb70df21fa26ca37cd2dd9eda1311cbad3f89 100644 (file)
@@ -2152,17 +2152,13 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
      except for last statement in ({...}) where they may be useful.  */
   if (! want_value
       && (expr_stmts_for_value == 0 || ! maybe_last)
-      && exp != error_mark_node)
+      && exp != error_mark_node
+      && warn_unused_value)
     {
-      if (! TREE_SIDE_EFFECTS (exp))
-       {
-         if (warn_unused_value
-             && !(TREE_CODE (exp) == CONVERT_EXPR
-                  && VOID_TYPE_P (TREE_TYPE (exp))))
-           warning ("%Hstatement with no effect", &emit_locus);
-       }
-      else if (warn_unused_value)
+      if (TREE_SIDE_EFFECTS (exp))
        warn_if_unused_value (exp);
+      else if (!VOID_TYPE_P (TREE_TYPE (exp)))
+       warning ("%Hstatement with no effect", &emit_locus);
     }
 
   /* If EXP is of function type and we are expanding statements for
index e12c2f7bd3324b77a8307d891350d373ffb0bfb7..47e7e9725e612ce4ae34b26200f202c0de391ae6 100644 (file)
@@ -1,3 +1,8 @@
+2003-08-16  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR C++/11512
+       * g++.dg/template/warn1.C: New.
+
 2003-08-15  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/template/error2.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/warn1.C b/gcc/testsuite/g++.dg/template/warn1.C
new file mode 100644 (file)
index 0000000..827c65e
--- /dev/null
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 14 Aug 2003 <nathan@codesourcery.com>
+
+// PR 11512. erroneous warnings
+
+template <class T>  void Foo(T i) 
+{ 
+  i++, i++;
+  i, i++; // { dg-warning "left-hand operand" "" }
+  i++, i; // { dg-warning "right-hand operand" "" }
+  for (;; --i, ++i)
+    ;
+} 
+void Bar ()
+{ 
+  Foo (1);  // { dg-error "instantiated" "" }
+}
+
+struct M {};
+
+struct C
+{
+  M m;
+  C () :m (M ()) {}
+};
+
+
+void Baz (int i)
+{
+  i ? i + 1 : i + 2; // { dg-error "operand of" "" }
+  i ? i++ : 0;
+}