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]

Fix PR tree-optimization/43769


This is an ICE at -O present on 4.3 and 4.4 branches only, a regression from 
earlier series.  The compiler aborts in tree-sra.c:bitfield_overlaps_p as it 
is faced with a field of variable (self-referential) size contained in a 
record type with fixed size; the typical case is a discriminated record type 
with default discriminant in Ada, for which the maximal size is allocated.

Fixed by computing a maximum size (which should always exist in this case).

Tested on x86_64-suse-linux, pre-approved by Richard in the audit trail, 
applied on the 4.3 and 4.4 branches (and the testcase everywhere).


2010-04-18  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/43769
	* tree-sra.c (bitfield_overlaps_p): If the length of the element is
	self-referential, try to compute an upper bound.


2010-04-18  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/rep_clause5.ad[sb]: New test.
	* gnat.dg/rep_clause5_pkg.ads: New helper.


-- 
Eric Botcazou
Index: tree-sra.c
===================================================================
--- tree-sra.c	(revision 157442)
+++ tree-sra.c	(working copy)
@@ -2931,6 +2931,12 @@ bitfield_overlaps_p (tree blen, tree bpo
   else
     gcc_unreachable ();
 
+  if (CONTAINS_PLACEHOLDER_P (flen))
+    flen = size_binop (MULT_EXPR,
+		       fold_convert (bitsizetype,
+				     lang_hooks.types.max_size (fld->type)),
+		       bitsize_unit_node);
+
   gcc_assert (host_integerp (blen, 1)
 	      && host_integerp (bpos, 1)
 	      && host_integerp (flen, 1)
-- { dg-do compile }
-- { dg-options "-O" }

package body Rep_Clause5 is

    function To_LNumber(S : String) return LNumber_Type is
        V :  VString;
        LV : Long_Type;
        LN : LNumber_Type;
    begin
        LV := To_Long(V, 10);
        LN := LNumber_Type(LV);
        return LN;
    end;

    procedure Merge_Numbered(LNodes : in out LNodes_Ptr) is
        T1  : Token_Type;
        LNO : LNumber_Type;
    begin
        for X in LNodes.all'Range loop
            T1 := LNodes(X).Line(0);
            if T1.Token /= LEX_LF then
                declare
                    S : String := Element(T1.SID);
                begin
                    begin
                        LNO := To_LNumber(S);
                    exception
                        when Bad_Number =>
                            LNO := 0;
                        when Too_Large =>
                            LNO := 0;
                    end;
                end;
            end if;
        end loop;
    end;

end Rep_Clause5;
with Rep_Clause5_Pkg; use Rep_Clause5_Pkg;

package Rep_Clause5 is

    Bad_Number : exception;
    Too_Large  : exception;

    type LNumber_Type is range 0..99999;

    procedure Merge_Numbered(LNodes : in out LNodes_Ptr);

end Rep_Clause5;
package Rep_Clause5_Pkg is

    type ID_Type      is mod 65536;
    type String_ID    is new ID_Type;
    type LNumber_Type is range 0..99999;
    subtype Long_Type is Integer;

    type Func_ID is (No_Func, FUN_SGN, FUN_EXP, FUN_LOG, FUN_LOG10);

    type Token_Kind is (
        No_Token,
        LEX_BINARY,
        LEX_SECTION,
        LEX_003,
        LEX_004,
        LEX_005,
        LEX_006,
        LEX_007,
        LEX_008,
        LEX_009,
        LEX_LF,
        LEX_011,
        LEX_012,
        LEX_013,
        LEX_014,
        LEX_015,
        LEX_016,
        LEX_017,
        LEX_018,
        LEX_019,
        LEX_020,
        LEX_021,
        LEX_022,
        LEX_023,
        LEX_024,
        LEX_025,
        LEX_026,
        LEX_027,
        LEX_028,
        LEX_029,
        LEX_030,
        LEX_031,
        LEX_032,
        '!',
        '"',
        '#',
        '$',
        '%',
        '&',
        ''',
        '(',
        ')',
        '*',
        '+',
        ',',
        '-',
        '.',
        '/',
        '0',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        ':',
        ';',
        '<',
        '=',
        '>',
        '?',
        '@',
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
        'G',
        'H',
        'I',
        'J',
        'K',
        'L',
        'M',
        'N',
        'O',
        'P',
        'Q',
        'R',
        'S',
        'T',
        'U',
        'V',
        'W',
        'X',
        'Y',
        'Z',
        '[',
        '\',
        ']',
        '^',
        '_',
        '`',
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
        'g',
        'h',
        'i',
        'j',
        'k',
        'l',
        'm',
        'n',
        'o',
        LEX_SFUN3,
        LEX_SFUN2,
        LEX_SFUN1,
        LEX_SFUNN,
        LEX_FUN3,
        LEX_FUN2,
        LEX_FUN1,
        LEX_FUNN,
        'x',
        'y',
        'z',
        '{',
        '|',
        '}',
        '~',
        LEX_CRTA,
        LEX_ISNULL,
        LEX_USING,
        LEX_HANDLE,
        LEX_CALLX,
        LEX_COMPLEX,
        LEX_FIXED,
        LEX_ENV,
        LEX_SPARSE,
        LEX_SUBROUTINE,
        LEX_CALL,
        LEX_BOX,
        LEX_VLINE,
        LEX_HLINE,
        LEX_MAXLENGTH,
        LEX_DLENGTH,
        LEX_INPUT,
        LEX_INITIALIZE,
        LEX_OUTPUT,
        LEX_UNLINK,
        LEX_SEEK,
        LEX_EXIT,
        LEX_NOT,
        LEX_COMMON,
        LEX_CHAIN,
        LEX_DEF,
        LEX_ARITY,
        LEX_RESUME,
        LEX_PIC_S,
        LEX_BG,
        LEX_FG,
        LEX_PC,
        LEX_CRT,
        LEX_ENUM,
        LEX_DECLARE,
        LEX_CURSOR,
        LEX_DROP,
        LEX_CURRENT,
        LEX_ISOLATION,
        LEX_SET,
        LEX_TRANSACTION,
        LEX_COMMIT,
        LEX_ABORT,
        LEX_BEGIN,
        LEX_PREVIOUS,
        LEX_LAST,
        LEX_FIRST,
        LEX_KEY,
        LEX_START,
        LEX_REWRITE,
        LEX_INDEX,
        LEX_SECONDARY,
        LEX_PRIMARY,
        LEX_COLUMN,
        LEX_TEMP,
        LEX_TABLE,
        LEX_CREATE,
        LEX_HASH,
        LEX_BTREE,
        LEX_UPDATE,
        LEX_ERROR,
        LEX_ACCEPT,
        LEX_AVG,
        LEX_MAX,
        LEX_MIN,
        LEX_FIELD,
        LEX_RESTORE,
        LEX_END,
        LEX_STEP,
        LEX_NEXT,
        LEX_FOR,
        LEX_RETURN,
        LEX_GOSUB,
        LEX_RANGE,
        LEX_EXPON,
        LEX_XOR,
        LEX_OR,
        LEX_AND,
        LEX_SHIFTR,
        LEX_GE,
        LEX_NE,
        LEX_SHIFTL,
        LEX_LE,
        LEX_VARYING,
        LEX_LENGTH,
        LEX_PRINT,
        LEX_IF,
        LEX_GOTO,
        LEX_ON,
        LEX_THEN,
        LEX_DELETE,
        LEX_TO,
        LEX_SEQUENCE,
        LEX_NONUNIQUE,
        LEX_UNIQUE,
        LEX_FILE,
        LEX_CLOSE,
        LEX_OPEN,
        LEX_DATABASE,
        LEX_RECORD,
        LEX_DATA,
        LEX_WRITE,
        LEX_READ,
        LEX_STOP,
        LEX_LET,
        LEX_MOD,
        LEX_LONG,
        LEX_DIM,
        LEX_SHORT,
        LEX_REM,
        LEX_SHELL,
        LEX_TOKEN,
        LEX_FLOAT,
        LEX_SIDENT,
        LEX_INLREM,
        LEX_ENDLIT,
        LEX_STRLIT,
        LEX_IDENT,
        LEX_LNUMBER,
        LEX_HEX,
        LEX_NUMBER,
        LEX_EOF,
        LEX_QUIT,
        LEX_LIST,
        LEX_REMOVE,
        LEX_RENUMBER,
        LEX_CONTINUE,
        LEX_RUN,
        LEX_MERGE,
        LEX_ENTER,
        LEX_NEW,
        LEX_RESET,
        LEX_SYMTAB,
        LEX_CLS,
        LEX_EDIT,
        LEX_SAVE,
        LEX_RESAVE,
        LEX_LOAD,
        LEX_NAME,
        LEX_LISTP,
        LEX_SHOW,
        LEX_STACK,
        LEX_STATUS,
        LEX_CACHE,
        LEX_INSPECT,
        LEX_STOW,
        LEX_PKGRUN,
        LEX_POP,
        LEX_CHECK,
        LEX_INSERT,
        LEX_INTO,
        LEX_VALUES,
        LEX_NULL,
        LEX_WHERE,
        LEX_FROM,
        LEX_EXEC,
        LEX_SELECT,
        LEX_AS,
        LEX_ALL,
        LEX_BY,
        LEX_CROSS,
        LEX_DESC,
        LEX_FULL,
        LEX_GROUP,
        LEX_INNER,
        LEX_JOIN,
        LEX_LEFT,
        LEX_LIMIT,
        LEX_NATURAL,
        LEX_OFFSET,
        LEX_ORDER,
        LEX_OUTER,
        LEX_RIGHT,
        LEX_FETCH,
        LEX_DISTINCT,
        LEX_DEFAULT,
        LEX_RETURNING,
        LEX_LEVEL,
        LEX_COMMITTED,
        LEX_SERIALIZABLE,
        LEX_ONLY,
        LEX_HOLD,
        LEX_FORWARD,
        LEX_WITH,
        LEX_PRIOR,
        LEX_RELATIVE,
        LEX_BACKWARD,
        LEX_OF,
        LEX_SCROLL,
        LEX_NOWAIT,
        LEX_HAVING,
        LEX_END_TOKENS
    );

    type Aux_Kind is (No_Aux, SID_Aux, FID_Aux, LNO_Aux);

    type Token_Type(Aux : Aux_Kind := No_Aux) is
        record
            Token : Token_Kind := No_Token;
            case Aux is
                when SID_Aux =>
                    SID :       String_ID;
                when FID_Aux =>
                    FID :       Func_ID;
                when LNO_Aux =>
                    LNO :       LNumber_Type;
                when No_Aux =>
                    null;
            end case;
        end record;

    for Token_Type use
        record
            Aux     at 0 range 0..2;
            Token   at 0 range 3..12;
            SID     at 0 range 16..31;
            FID     at 0 range 16..31;
            LNO     at 0 range 13..31;
        end record;

    type Tokens_Index is range 0..999999;
    type Token_Array is array(Tokens_Index range <>) of Token_Type;
    type Token_Line is access all Token_Array;	

    type Line_Node is
        record
            Line :     Token_Line;
            LNO :      LNumber_Type := 0;
            Numbered : Boolean := False;
        end record;

    type Nodes_Index is range 0..999999;
    type LNodes_Array is array(Nodes_Index range <>) of Line_Node;
    type LNodes_Ptr is access all LNodes_Array;

    type VString is
        record
            Max_Length : Natural := 0;
            Fixed :      Boolean := False;
        end record;

    function To_Long(Object : VString; Radix : Natural) return Long_Type;

    function Element (V : String_ID) return String;

end Rep_Clause5_Pkg;

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