diff mbox

Fix oversight in round_up_loc change

Message ID 1944224.OtqtiEtsZg@polaris
State New
Headers show

Commit Message

Eric Botcazou March 4, 2015, 10:30 p.m. UTC
> There might be a similar issue in the block of code just above:
> 
> 	  wide_int val = value;
> 	  bool overflow_p;
> 
> 	  if ((val & (divisor - 1)) == 0)
> 	    return value;
> 
> 	  overflow_p = TREE_OVERFLOW (value);
> 	  val &= ~(divisor - 1);
> 
> but I don't have a testcase and don't know enough of wide_int to assert it.

The testcase is gcc.dg/pr42611.c: the size is artificially truncated, which 
causes the error issued by c/c-decl.c:finish_struct after calling layout_type:

  layout_type (t);

  if (TYPE_SIZE_UNIT (t)
      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
    error ("type %qT is too large", t);

to disappear like the warning in Ada.  And this was papered over in the same 
change by duplicating the error in finalize_record_size:

   if (TREE_CODE (unpadded_size_unit) == INTEGER_CST
       && !TREE_OVERFLOW (unpadded_size_unit)
       && !valid_constant_size_p (unpadded_size_unit))
     error ("type %qT is too large", rli->t);

Issuing an error in finalize_record_size is a bad idea, because it's called by 
all the front-ends on random types which can be artifically generated, so the 
error message can be meaningless (Ada testcase attached).

Tested on x86_64-suse-linux, applied on the mainline as obvious.  This should 
hopefully fix all the regressions introduced under PR c/60226.


2015-03-04  Eric Botcazou  <ebotcazou@adacore.com>

	* fold-const.c (round_up_loc): Cast divisor to signed on all paths
	before negating it.
	* stor-layout.c (finalize_record_size): Revert latest change.


2015-03-04  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/entry_queues3.adb: New test.
diff mbox

Patch

Index: fold-const.c
===================================================================
--- fold-const.c	(revision 221173)
+++ fold-const.c	(working copy)
@@ -16019,8 +16019,8 @@  round_up_loc (location_t loc, tree value
 	    return value;
 
 	  overflow_p = TREE_OVERFLOW (value);
-	  val &= ~(divisor - 1);
-	  val += divisor;
+	  val += divisor - 1;
+	  val &= - (int) divisor;
 	  if (val == 0)
 	    overflow_p = true;
 
@@ -16032,7 +16032,7 @@  round_up_loc (location_t loc, tree value
 
 	  t = build_int_cst (TREE_TYPE (value), divisor - 1);
 	  value = size_binop_loc (loc, PLUS_EXPR, value, t);
-	  t = build_int_cst (TREE_TYPE (value), - (HOST_WIDE_INT) divisor);
+	  t = build_int_cst (TREE_TYPE (value), - (int) divisor);
 	  value = size_binop_loc (loc, BIT_AND_EXPR, value, t);
 	}
     }
Index: stor-layout.c
===================================================================
--- stor-layout.c	(revision 221173)
+++ stor-layout.c	(working copy)
@@ -1627,11 +1627,6 @@  finalize_record_size (record_layout_info
     unpadded_size_unit
       = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
 
-  if (TREE_CODE (unpadded_size_unit) == INTEGER_CST
-      && !TREE_OVERFLOW (unpadded_size_unit)
-      && !valid_constant_size_p (unpadded_size_unit))
-    error ("type %qT is too large", rli->t);
-
   /* Round the size up to be a multiple of the required alignment.  */
   TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
   TYPE_SIZE_UNIT (rli->t)