> 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  <ebotca...@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  <ebotca...@adacore.com>

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


-- 
Eric Botcazou
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)
-- { dg-do compile }

procedure Entry_Queues3 is

  generic
    type Large_Range is range <>;
  package Queue is
  end;

  package body Queue is
    task T is
      entry E(Large_Range);
    end T ;
 
    task body T is
      begin
        accept E(Large_Range'First) do
          null;
        end e ; 
      end T ;
  end Queue;
 
  type Large_Range is range 0 .. Long_Integer'Last;

  package My_Queue is new Queue(Large_Range); -- { dg-warning "warning" }

begin
  null;
end;

Reply via email to