}
/*------------------------------------------------------------------*/
-/* getSize - returns size of a type chain in bits */
+/* getSize - returns size of a type chain in bytes */
/*------------------------------------------------------------------*/
unsigned int
getSize (sym_link * p)
}
}
-/*---------------------------------------------------------------------*/
-/* getAllocSize - returns size of a type chain in bytes for allocation */
-/*---------------------------------------------------------------------*/
-unsigned int
-getAllocSize (sym_link *p)
+/*------------------------------------------------------------------*/
+/* checkStructFlexArray - check tree behind a struct */
+/*------------------------------------------------------------------*/
+static bool
+checkStructFlexArray (symbol *sym, sym_link *p)
{
- if (IS_STRUCT (p) && SPEC_STRUCT (p)->type == STRUCT)
- {
- /* if this is a struct specifier then */
- /* calculate the size as it could end */
- /* with an array of unspecified length */
- symbol *sflds = SPEC_STRUCT (p)->fields;
+ /* if nothing return FALSE */
+ if (!p)
+ return FALSE;
- while (sflds && sflds->next)
- sflds = sflds->next;
+ if (IS_SPEC (p))
+ {
+ /* (nested) struct with flexible array member? */
+ if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember)
+ {
+ werror (W_INVALID_FLEXARRAY);
+ return FALSE;
+ }
+ return FALSE;
+ }
- if (sflds && !IS_BITFIELD (sflds->type))
- return sflds->offset + getAllocSize (sflds->type);
- else
- return SPEC_STRUCT (p)->size;
+ /* this is a declarator */
+ if (IS_ARRAY (p))
+ {
+ /* flexible array member? */
+ if (!DCL_ELEM(p))
+ {
+ if (!options.std_c99)
+ werror (W_C89_NO_FLEXARRAY);
+ return TRUE;
+ }
+ /* walk tree */
+ return checkStructFlexArray (sym, p->next);
}
- else
- return getSize (p);
+ return FALSE;
}
/*------------------------------------------------------------------*/
loop->offset = sum;
checkDecl (loop, 1);
sum += getSize (loop->type);
+
+ /* search for "flexibel array members" */
+ /* and do some syntax checks */
+ if ( su == STRUCT
+ && checkStructFlexArray (loop, loop->type))
+ {
+ /* found a "flexible array member" */
+ sdef->b_flexArrayMember = TRUE;
+ /* is another struct-member following? */
+ if (loop->next)
+ werror (E_FLEXARRAY_NOTATEND);
+ /* is it the first struct-member? */
+ else if (loop == sdef->fields)
+ werror (E_FLEXARRAY_INEMPTYSTRCT);
+ }
}
loop = loop->next;
{
sym_link *head, *curr, *loop;
+ /* note: v_struct and v_struct->fields are not copied! */
curr = p;
head = loop = (curr ? newLink (p->class) : (void *) NULL);
while (curr)