Patchwork [C++] PR 52299, bogus div by zero warning

login
register
mail settings
Submitter Paolo Carlini
Date March 12, 2012, 6:32 p.m.
Message ID <4F5E4143.6090607@oracle.com>
Download mbox | patch
Permalink /patch/146201/
State New
Headers show

Comments

Paolo Carlini - March 12, 2012, 6:32 p.m.
Hi,

I handled this issue as outlined by Jakub in the audit trail. For the 
purpose of the bogus div by zero warning just using 
c_inhibit_evaluation_warnings appears to work fine.

Tested x86_64-linux.

Thanks,
Paolo.

///////////////////////
/cp
2012-03-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52299
	* pt.c (tsubst_copy_and_build, case COND_EXPR): Avoid bogus
	division by zero warnings.

/testsuite
2012-03-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52299
	* g++.dg/warn/Wdiv-by-zero-bogus.C: New.
Jason Merrill - March 12, 2012, 6:37 p.m.
OK.

Jason

Patch

Index: testsuite/g++.dg/warn/Wdiv-by-zero-bogus.C
===================================================================
--- testsuite/g++.dg/warn/Wdiv-by-zero-bogus.C	(revision 0)
+++ testsuite/g++.dg/warn/Wdiv-by-zero-bogus.C	(revision 0)
@@ -0,0 +1,30 @@ 
+// PR c++/52299
+
+template<unsigned x>
+struct test0 {
+  static const unsigned a_
+  = x ? 10 / x : 10;
+};
+
+template<unsigned x>
+struct test1 {
+  static const unsigned a_
+  = !x ? 10 : 10 / x;
+};
+
+template<bool x>
+struct test2 {
+  static const unsigned a_
+  = x ? 10 / x : 10;
+};
+
+template<bool x>
+struct test3 {
+  static const unsigned a_
+  = !x ? 10 : 10 / x;
+};
+
+unsigned i0 = test0<0>::a_;
+unsigned i1 = test1<0>::a_;
+unsigned i2 = test2<false>::a_;
+unsigned i3 = test3<false>::a_;
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 185247)
+++ cp/pt.c	(working copy)
@@ -13943,12 +13943,36 @@  tsubst_copy_and_build (tree t,
       }
 
     case COND_EXPR:
-      return build_x_conditional_expr
-	(RECUR (TREE_OPERAND (t, 0)),
-	 RECUR (TREE_OPERAND (t, 1)),
-	 RECUR (TREE_OPERAND (t, 2)),
-         complain);
+      {
+	tree cond = RECUR (TREE_OPERAND (t, 0));
+	tree op1, op2;
 
+	if (TREE_CODE (cond) == INTEGER_CST)
+	  {
+	    if (integer_zerop (cond))
+	      {
+		++c_inhibit_evaluation_warnings;
+		op1 = RECUR (TREE_OPERAND (t, 1));
+		--c_inhibit_evaluation_warnings;
+		op2 = RECUR (TREE_OPERAND (t, 2));
+	      }
+	    else
+	      {
+		op1 = RECUR (TREE_OPERAND (t, 1));
+		++c_inhibit_evaluation_warnings;
+		op2 = RECUR (TREE_OPERAND (t, 2));
+		--c_inhibit_evaluation_warnings;
+	      }
+	  }
+	else
+	  {
+	    op1 = RECUR (TREE_OPERAND (t, 1));
+	    op2 = RECUR (TREE_OPERAND (t, 2));
+	  }
+
+	return build_x_conditional_expr (cond, op1, op2, complain);
+      }
+
     case PSEUDO_DTOR_EXPR:
       return finish_pseudo_destructor_expr
 	(RECUR (TREE_OPERAND (t, 0)),