Re: [C++ Patch] PR 52299, bogus div by zero warning

2012-03-12 Thread Jason Merrill

OK.

Jason


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

2012-03-12 Thread Paolo Carlini

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  

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

/testsuite
2012-03-12  Paolo Carlini  

PR c++/52299
* g++.dg/warn/Wdiv-by-zero-bogus.C: New.

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
+struct test0 {
+  static const unsigned a_
+  = x ? 10 / x : 10;
+};
+
+template
+struct test1 {
+  static const unsigned a_
+  = !x ? 10 : 10 / x;
+};
+
+template
+struct test2 {
+  static const unsigned a_
+  = x ? 10 / x : 10;
+};
+
+template
+struct test3 {
+  static const unsigned a_
+  = !x ? 10 : 10 / x;
+};
+
+unsigned i0 = test0<0>::a_;
+unsigned i1 = test1<0>::a_;
+unsigned i2 = test2::a_;
+unsigned i3 = test3::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)),