This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Call fold_non_dependent_expr_sfinae before maybe_constant_value (PR c++/56895)


Hi!

As discussed in the PR, these 4 places call maybe_constant_value even
when processing_template_decl, just to try harder to see if the value isn't
constant, and that may crash if fold_non_dependent_expr hasn't been called
first.  This is just optimization to get better warnings, so we don't want
that call to emit any errors, worst case we just won't emit the warnings,
so I'm using fold_non_dependent_expr_sfinae with tf_none.

Bootstrapped/regtested on x86_64-linux and i686-linux, acked by Jason in the
PR, committed to trunk and 4.8 branch.

2013-04-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/56895
	* typeck.c (cp_build_binary_op): Call fold_non_dependent_expr_sfinae
	first before calling maybe_constant_value for warn_for_div_by_zero
	or invalid shift count warning purposes.

	* g++.dg/template/arrow3.C: New test.

--- gcc/cp/typeck.c.jj	2013-04-04 15:03:28.000000000 +0200
+++ gcc/cp/typeck.c	2013-04-09 20:40:20.753714512 +0200
@@ -4047,8 +4047,9 @@ cp_build_binary_op (location_t location,
 	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
 	{
 	  enum tree_code tcode0 = code0, tcode1 = code1;
+	  tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
 
-	  warn_for_div_by_zero (location, maybe_constant_value (op1));
+	  warn_for_div_by_zero (location, maybe_constant_value (cop1));
 
 	  if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
 	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
@@ -4084,7 +4085,11 @@ cp_build_binary_op (location_t location,
 
     case TRUNC_MOD_EXPR:
     case FLOOR_MOD_EXPR:
-      warn_for_div_by_zero (location, maybe_constant_value (op1));
+      {
+	tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+
+	warn_for_div_by_zero (location, maybe_constant_value (cop1));
+      }
 
       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
 	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
@@ -4132,7 +4137,8 @@ cp_build_binary_op (location_t location,
 	}
       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
 	{
-	  tree const_op1 = maybe_constant_value (op1);
+	  tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+	  const_op1 = maybe_constant_value (const_op1);
 	  if (TREE_CODE (const_op1) != INTEGER_CST)
 	    const_op1 = op1;
 	  result_type = type0;
@@ -4178,7 +4184,8 @@ cp_build_binary_op (location_t location,
 	}
       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
 	{
-	  tree const_op1 = maybe_constant_value (op1);
+	  tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+	  const_op1 = maybe_constant_value (const_op1);
 	  if (TREE_CODE (const_op1) != INTEGER_CST)
 	    const_op1 = op1;
 	  result_type = type0;
--- gcc/testsuite/g++.dg/template/arrow3.C.jj	2013-04-09 20:27:31.800321563 +0200
+++ gcc/testsuite/g++.dg/template/arrow3.C	2013-04-09 20:42:34.000000000 +0200
@@ -0,0 +1,38 @@
+// PR c++/56895
+// { dg-do compile }
+
+extern struct A { bool foo (); A bar (); } *a;
+
+template <int>
+int
+baz1 ()
+{
+  return 2 << (a->bar().foo() ? 1 : 0);
+}
+
+template <int>
+int
+baz2 ()
+{
+  return 2 >> (a->bar().foo() ? 1 : 0);
+}
+
+template <int>
+int
+baz3 ()
+{
+  return 10 / (a->bar().foo() ? 1 : 2);
+}
+
+template <int>
+int
+baz4 ()
+{
+  return 10 % (a->bar().foo() ? 1 : 0);
+}
+
+int
+test ()
+{
+  return baz1<0> () + baz2<0> () + baz3<0> () + baz4<0> ();
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]