C++ PATCH: PR 28337

Mark Mitchell mark@codesourcery.com
Wed Jul 19 18:53:00 GMT 2006


This patch fixes PR c++/28337, and ICE-on-valid regression.  Here, we
were letting fold see uninstantiated templates, which is always a
mistake.  The fix is to short-circuit cp_pointer_int_sum; in an
uninstantiated template, all that is of interest is the type of the
result.

Tested on x86_64-unknown-linux-gnu, applied to the mainline and to the
4.1 branch.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-07-18  Mark Mitchell  <mark@codesourcery.com>

	PR c++/28337
	* typeck.c (build_binary_op): Short-circuit pointer arithmetic in
	templates.

2006-07-18  Mark Mitchell  <mark@codesourcery.com>

	PR c++/28337
	* g++.dg/template/string1.C: New test.

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 115544)
+++ gcc/cp/typeck.c	(working copy)
@@ -3043,16 +3043,6 @@ build_binary_op (enum tree_code code, tr
 
   switch (code)
     {
-    case PLUS_EXPR:
-      /* Handle the pointer + int case.  */
-      if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
-	return cp_pointer_int_sum (PLUS_EXPR, op0, op1);
-      else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
-	return cp_pointer_int_sum (PLUS_EXPR, op1, op0);
-      else
-	common = 1;
-      break;
-
     case MINUS_EXPR:
       /* Subtraction of two similar pointers.
 	 We must subtract them as integers, then divide by object size.  */
@@ -3060,11 +3050,33 @@ build_binary_op (enum tree_code code, tr
 	  && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
 							TREE_TYPE (type1)))
 	return pointer_diff (op0, op1, common_type (type0, type1));
-      /* Handle pointer minus int.  Just like pointer plus int.  */
-      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
-	return cp_pointer_int_sum (MINUS_EXPR, op0, op1);
-      else
-	common = 1;
+      /* In all other cases except pointer - int, the usual arithmetic
+	 rules aply.  */
+      else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
+	{
+	  common = 1;
+	  break;
+	}
+      /* The pointer - int case is just like pointer + int; fall
+	 through.  */
+    case PLUS_EXPR:
+      if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
+	  && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
+	{
+	  tree ptr_operand;
+	  tree int_operand;
+	  ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
+	  int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
+	  if (processing_template_decl)
+	    {
+	      result_type = TREE_TYPE (ptr_operand);
+	      break;
+	    }
+	  return cp_pointer_int_sum (code,
+				     ptr_operand, 
+				     int_operand);
+	}
+      common = 1;
       break;
 
     case MULT_EXPR:
Index: gcc/testsuite/g++.dg/template/string1.C
===================================================================
--- gcc/testsuite/g++.dg/template/string1.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/string1.C	(revision 0)
@@ -0,0 +1,7 @@
+// PR c++/28337
+
+template <int> void foo()
+{
+  (0 ? "" : "X") + 1;
+}
+



More information about the Gcc-patches mailing list