* src/SDCCast.c (createIvalStruct, createIvalArray, createIvalPtr, createIval): imple...
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 29 Nov 2005 21:22:07 +0000 (21:22 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 29 Nov 2005 21:22:07 +0000 (21:22 +0000)
(createIvalCharPtr): implemented flexible array initialisation with a string
* src/SDCCsymt.c (copyStruct): removed, (getSize): fixed comment,
(getAllocSize): removed, the additional allocation size is now in sym->flexArrayLength,
(checkStructFlexArray): new, syntax checks for "flexible array members",
(compStructSize): added syntax checks for "flexible array members"
(copyStruct): removed,
(copyLinkChain): removed inefficient fix for bug 770487
* src/SDCCglue.c (emitRegularMap): getAllocSize has been removed
* src/SDCCsymt.h: added structdef.b_flexArrayMember and symbol->flexArrayLength
* src/SDCCerr.c,
* src/SDCCerr.h: added W_INVALID_FLEXARRAY, W_C89_NO_FLEXARRAY, E_FLEXARRAY_NOTATEND and E_FLEXARRAY_INEMPTYSTRCT
* support/regression/tests/structflexarray.c: added
* support/valdiag/tests/structflexiblearray.c: added

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3999 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/SDCCast.c
src/SDCCglue.c
src/SDCCsymt.c
src/SDCCsymt.h
support/Util/SDCCerr.c
support/Util/SDCCerr.h
support/regression/tests/structflexarray.c [new file with mode: 0644]
support/valdiag/tests/structflexiblearray.c [new file with mode: 0644]

index 4079dd17d3f2327218a2a73ffaeec5a69fd06f29..ae35fe02959687c02d3f7e8c3fc0f2ff6cf029a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2005-11-29 Bernhard Held <bernhard AT bernhardheld.de>
+
+       * src/SDCCast.c (createIvalStruct, createIvalArray, createIvalPtr,
+       createIval): implement symbol independant "flexible array member",
+       (createIvalCharPtr): implemented flexible array initialisation with a
+       string
+       * src/SDCCsymt.c (copyStruct): removed,
+       (getSize): fixed misleading comment,
+       (getAllocSize): removed, the additional allocation size is now in
+       sym->flexArrayLength,
+       (checkStructFlexArray): new, syntax checks for flexible array members,
+       (compStructSize): added syntax checks for "flexible array members"
+       (copyStruct): removed,
+       (copyLinkChain): removed inefficient fix for bug 770487
+       * src/SDCCglue.c (emitRegularMap): getAllocSize has been removed
+       * src/SDCCsymt.h: added structdef.b_flexArrayMember and
+       symbol->flexArrayLength
+       * src/SDCCerr.c,
+       * src/SDCCerr.h: added W_INVALID_FLEXARRAY, W_C89_NO_FLEXARRAY,
+       E_FLEXARRAY_NOTATEND and E_FLEXARRAY_INEMPTYSTRCT
+       * support/regression/tests/structflexarray.c: added
+       * support/valdiag/tests/structflexiblearray.c: added
+
 2005-11-29 Bernhard Held <bernhard AT bernhardheld.de>
 
        * src/SDCCast.c (decorateType): fixed bug 1368489
index 09b4a28c66a5e39edee719bf1ff88f80b82961f3..2a0451b4a5bf07ed2062385b59c9ddd3e97d0613 100644 (file)
@@ -50,8 +50,8 @@ int labelKey = 1;
 int noLineno = 0;
 int noAlloc = 0;
 symbol *currFunc=NULL;
-static ast *createIval (ast *, sym_link *, initList *, ast *);
-static ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
+static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
 static ast *optimizeCompare (ast *);
 ast *optimizeRRCRLC (ast *);
 ast *optimizeSWAP (ast *);
@@ -864,7 +864,7 @@ createIvalType (ast * sym, sym_link * type, initList * ilist)
 /* createIvalStruct - generates initial value for structures       */
 /*-----------------------------------------------------------------*/
 static ast *
-createIvalStruct (ast * sym, sym_link * type, initList * ilist)
+createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
 {
   ast *rast = NULL;
   ast *lAst;
@@ -888,7 +888,10 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist)
       sflds->implicit = 1;
       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
       lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
-      rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
+      rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
+                                                       iloop, rast, rootValue)),
+                           RESULT_TYPE_NONE);
+
     }
 
   if (iloop) {
@@ -905,7 +908,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist)
 /* createIvalArray - generates code for array initialization       */
 /*-----------------------------------------------------------------*/
 static ast *
-createIvalArray (ast * sym, sym_link * type, initList * ilist)
+createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
 {
   ast *rast = NULL;
   initList *iloop;
@@ -918,83 +921,88 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
   if (IS_CHAR (type->next))
     if ((rast = createIvalCharPtr (sym,
                                    type,
-                        decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
+                        decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
+                                   rootValue)))
 
       return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
 
-    /* not the special case             */
-    if (ilist->type != INIT_DEEP)
-    {
-        werror (E_INIT_STRUCT, "");
-        return NULL;
-    }
+  /* not the special case             */
+  if (ilist->type != INIT_DEEP)
+  {
+      werror (E_INIT_STRUCT, "");
+      return NULL;
+  }
 
-    iloop = ilist->init.deep;
-    lcnt = DCL_ELEM (type);
+  iloop = ilist->init.deep;
+  lcnt = DCL_ELEM (type);
 
-    if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
-    {
-        ast *aSym;
+  if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
+  {
+      ast *aSym;
 
-        aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
-        
-        rast = newNode(ARRAYINIT, aSym, NULL);
-        rast->values.constlist = literalL;
-        
-        // Make sure size is set to length of initializer list.
-        while (iloop)
-        {
-            size++;
-            iloop = iloop->next;
-        }
-        
-        if (lcnt && size > lcnt)
-        {
-            // Array size was specified, and we have more initializers than needed.
-            char *name=sym->opval.val->sym->name;
-            int lineno=sym->opval.val->sym->lineDef;
-            char *filename=sym->opval.val->sym->fileDef;
-            
-            werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
-        }
-    }
-    else
-    {
-        for (;;)
-        {
-            ast *aSym;
-            
-            aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
-            aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
-            rast = createIval (aSym, type->next, iloop, rast);
-            iloop = (iloop ? iloop->next : NULL);
-            if (!iloop)
-            {
-                break;
-            }
-            
-            /* no of elements given and we    */
-            /* have generated for all of them */
-            if (!--lcnt) 
-            {
-                // is this a better way? at least it won't crash
-                char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
-                int lineno = iloop->lineno;
-                char *filename = iloop->filename;
-                werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
-                
-                break;
-            }
-        }
-    }
+      aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
+      
+      rast = newNode(ARRAYINIT, aSym, NULL);
+      rast->values.constlist = literalL;
+      
+      // Make sure size is set to length of initializer list.
+      while (iloop)
+      {
+          size++;
+          iloop = iloop->next;
+      }
+      
+      if (lcnt && size > lcnt)
+      {
+          // Array size was specified, and we have more initializers than needed.
+          char *name=sym->opval.val->sym->name;
+          int lineno=sym->opval.val->sym->lineDef;
+          char *filename=sym->opval.val->sym->fileDef;
+          
+          werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+      }
+  }
+  else
+  {
+      for (;;)
+      {
+          ast *aSym;
+          
+          aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
+          aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
+          rast = createIval (aSym, type->next, iloop, rast, rootValue);
+          iloop = (iloop ? iloop->next : NULL);
+          if (!iloop)
+          {
+              break;
+          }
+          
+          /* no of elements given and we    */
+          /* have generated for all of them */
+          if (!--lcnt) 
+          {
+              // is this a better way? at least it won't crash
+              char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
+              int lineno = iloop->lineno;
+              char *filename = iloop->filename;
+              werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+              
+              break;
+          }
+      }
+  }
 
-    /* if we have not been given a size  */
-    if (!DCL_ELEM (type))
+  /* if we have not been given a size  */
+  if (!DCL_ELEM (type))
     {
+      /* check, if it's a flexible array */
+      if (IS_STRUCT (AST_VALUE (rootValue)->type))
+        AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
+      else
         DCL_ELEM (type) = size;
     }
 
-    return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
+  return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
 }
 
 
@@ -1002,9 +1010,10 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
 /* createIvalCharPtr - generates initial values for char pointers  */
 /*-----------------------------------------------------------------*/
 static ast *
-createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
+createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
 {
   ast *rast = NULL;
+  unsigned size = 0;
 
   /* if this is a pointer & right is a literal array then */
   /* just assignment will do                              */
@@ -1023,10 +1032,10 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
       /* to the array element */
       char *s = SPEC_CVAL (iexpr->etype).v_char;
       int i = 0;
-      int size = getSize (iexpr->ftype);
       int symsize = getSize (type);
-      
-      if (size>symsize)
+
+      size = getSize (iexpr->ftype);
+      if (symsize && size>symsize)
         {
           if (size>(symsize+1))
             {
@@ -1052,6 +1061,16 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
       // now WE don't need iexpr's symbol anymore
       freeStringSymbol(AST_SYMBOL(iexpr));
 
+      /* if we have not been given a size  */
+      if (!DCL_ELEM (type))
+        {
+          /* check, if it's a flexible array */
+          if (IS_STRUCT (AST_VALUE (rootVal)->type))
+            AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
+          else
+            DCL_ELEM (type) = size;
+        }
+
       return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
     }
 
@@ -1062,7 +1081,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
 /* createIvalPtr - generates initial value for pointers            */
 /*-----------------------------------------------------------------*/
 static ast *
-createIvalPtr (ast * sym, sym_link * type, initList * ilist)
+createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
 {
   ast *rast;
   ast *iexpr;
@@ -1075,7 +1094,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist)
 
   /* if character pointer */
   if (IS_CHAR (type->next))
-    if ((rast = createIvalCharPtr (sym, type, iexpr)))
+    if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
       return rast;
 
   return newNode ('=', sym, iexpr);
@@ -1085,7 +1104,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist)
 /* createIval - generates code for initial value                   */
 /*-----------------------------------------------------------------*/
 static ast *
-createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
+createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
 {
   ast *rast = NULL;
 
@@ -1094,15 +1113,15 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
 
   /* if structure then    */
   if (IS_STRUCT (type))
-    rast = createIvalStruct (sym, type, ilist);
+    rast = createIvalStruct (sym, type, ilist, rootValue);
   else
     /* if this is a pointer */
   if (IS_PTR (type))
-    rast = createIvalPtr (sym, type, ilist);
+    rast = createIvalPtr (sym, type, ilist, rootValue);
   else
     /* if this is an array   */
   if (IS_ARRAY (type))
-    rast = createIvalArray (sym, type, ilist);
+    rast = createIvalArray (sym, type, ilist, rootValue);
   else
     /* if type is SPECIFIER */
   if (IS_SPEC (type))
@@ -1118,7 +1137,8 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
 /* initAggregates - initialises aggregate variables with initv     */
 /*-----------------------------------------------------------------*/
 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
-  return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
+  ast *newAst = newAst_VALUE (symbolVal (sym));
+  return createIval (newAst, sym->type, ival, wid, newAst);
 }
 
 /*-----------------------------------------------------------------*/
index 199a7c06594809094ea04fea22bd10ae527f3e39..78da017738a22143ee51f7268be971a887286f92 100644 (file)
@@ -361,7 +361,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                    SPEC_ADDR (sym->etype));
         }
       else {
-        int size = getAllocSize (sym->type);
+        int size = getSize (sym->type) + sym->flexArrayLength;
         if (size==0) {
           werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
         }
index de557529207f98479ff68e0c354fcb6fd4efa817..172acf8060459d5e42d30cf370a5eed597a3d2f6 100644 (file)
@@ -328,20 +328,6 @@ newStruct (char *tag)
   return s;
 }
   
-/*------------------------------------------------------------------*/
-/* copyStruct - copies a structdef including the fields-list        */
-/*------------------------------------------------------------------*/
-static structdef *
-copyStruct (structdef *src)
-{
-  structdef *dest;
-
-  dest = newStruct ("");
-  memcpy (dest, src, sizeof (structdef));
-  dest->fields = copySymbolChain (src->fields);
-  return dest;
-}
-  
 /*------------------------------------------------------------------*/
 /* sclsFromPtr - Return the storage class a pointer points into.    */
 /*               S_FIXED is returned for generic pointers or other  */
@@ -810,7 +796,7 @@ newBoolLink ()
 }
 
 /*------------------------------------------------------------------*/
-/* getSize - returns size of a type chain in bits                   */
+/* getSize - returns size of a type chain in bytes                  */
 /*------------------------------------------------------------------*/
 unsigned int 
 getSize (sym_link * p)
@@ -874,29 +860,41 @@ 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;
 }
 
 /*------------------------------------------------------------------*/
@@ -1306,6 +1304,21 @@ compStructSize (int su, structdef * sdef)
             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;
@@ -1639,14 +1652,12 @@ copyLinkChain (sym_link * p)
 {
   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)
     {
       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
-if (getenv ("SDCCCOPYSTRUCT")) // this breaks regression test bug-221220??
-      if (IS_STRUCT (loop))
-        SPEC_STRUCT (loop) = copyStruct (SPEC_STRUCT (loop));
       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
       loop = loop->next;
       curr = curr->next;
index c9668d2d28192d9e9daeafab1084d07cd73658a9..3699759ae1498bdc676d7c7336fcd842eff67402 100644 (file)
@@ -86,6 +86,8 @@ typedef struct structdef
     struct symbol *fields;              /* pointer to fields     */
     unsigned size;                      /* sizeof the table in bytes  */
     int type;                           /* STRUCT or UNION */
+    bool b_flexArrayMember;             /* has got an flexible array member,
+                                           only needed for syntax checks */
   }
 structdef;
 
@@ -185,7 +187,8 @@ DECLARATOR_TYPE;
 typedef struct declarator
   {
     DECLARATOR_TYPE dcl_type;           /* POINTER,ARRAY or FUNCTION  */
-    unsigned int num_elem;              /* # of elems if type==array  */
+    unsigned int num_elem;              /* # of elems if type==array, */
+                                        /* always 0 for flexible arrays */
     unsigned ptr_const:1;               /* pointer is constant        */
     unsigned ptr_volatile:1;            /* pointer is volatile        */
     struct sym_link *tspec;             /* pointer type specifier     */
@@ -246,6 +249,11 @@ typedef struct symbol
     short level;                        /* declration lev,fld offset */
     short block;                        /* sequential block # of defintion */
     int key;
+    unsigned flexArrayLength;           /* if the symbol specifies a struct
+    with a "flexible array member", then the additional length in bytes for
+    the "fam" is stored here. Because the lenght can be different from symbol
+    to symbol AND v_struct isn't copied in copyLinkChain(), it's located here
+    in the symbol and not in v_struct or the declarator */
     unsigned implicit:1;                /* implicit flag                     */
     unsigned undefined:1;               /* undefined variable                */
     unsigned _isparm:1;                 /* is a parameter          */
@@ -568,7 +576,6 @@ value *checkStructIval (symbol *, value *);
 value *checkArrayIval (sym_link *, value *);
 value *checkIval (sym_link *, value *);
 unsigned int getSize (sym_link *);
-unsigned int getAllocSize (sym_link *);
 unsigned int bitsForType (sym_link *);
 sym_link *newIntLink ();
 sym_link *newCharLink ();
index ea38e287d427bc07106c6ff5b457024366a2d9e2..aa804d64c6c4e6db339b80c33bdfba7fa645b4b6 100644 (file)
@@ -424,6 +424,14 @@ struct
    "integer constant '%s' out of range, truncated to %.0lf." },
 { W_CMP_SU_CHAR, ERROR_LEVEL_PEDANTIC,
    "comparison of 'signed char' with 'unsigned char' requires promotion to int" },
+{ W_INVALID_FLEXARRAY, ERROR_LEVEL_WARNING,
+   "invalid use of structure with flexible array member" },
+{ W_C89_NO_FLEXARRAY, ERROR_LEVEL_PEDANTIC,
+   "ISO C90 does not support flexible array members" },
+{ E_FLEXARRAY_NOTATEND, ERROR_LEVEL_ERROR,
+   "flexible array member not at end of struct" },
+{ E_FLEXARRAY_INEMPTYSTRCT, ERROR_LEVEL_ERROR,
+   "flexible array in otherwise empty struct" },
 };
 
 /*
index b48e0b624eb29f36c7e53755160cc345fe449516..64d1bb6bd8e874231892c6b3377ae767a10622c9 100644 (file)
@@ -201,6 +201,10 @@ SDCCERR - SDCC Standard error handler
 #define E_BANKED_WITH_CALLEESAVES     183 /* banked and callee-saves mixed */
 #define W_INVALID_INT_CONST           184 /* invalid integer literal string */
 #define W_CMP_SU_CHAR                 185 /* comparison of 'signed char' with 'unsigned char' requires promotion to int */
+#define W_INVALID_FLEXARRAY           186 /* invalid use of structure with flexible array member */
+#define W_C89_NO_FLEXARRAY            187 /* ISO C90 does not support flexible array members */
+#define E_FLEXARRAY_NOTATEND          188 /* flexible array member not at end of struct */
+#define E_FLEXARRAY_INEMPTYSTRCT      189 /* flexible array in otherwise empty struct */
 
 #define MAX_ERROR_WARNING             256 /* size of disable warnings array */
 
diff --git a/support/regression/tests/structflexarray.c b/support/regression/tests/structflexarray.c
new file mode 100644 (file)
index 0000000..0c3bea2
--- /dev/null
@@ -0,0 +1,46 @@
+/* Check basic behaviour of "flexible array members"
+ */
+#include <testfwk.h>
+
+struct str1
+{
+  char c;
+  short i[];
+};
+
+struct str1 s11 = { 1, {2, 3} };
+struct str1 s12 = { 4, {5, 6, 7} }; /* different size */
+
+static void
+testFlexibleArray1(void)
+{
+  /* test sizeof */
+  ASSERT(sizeof(s11) == 1);
+  /* test allocation size */
+#if ! defined(PORT_HOST)
+   ASSERT((char *) &s12 - (char *) &s11 == 1 + 4);
+#endif
+}
+
+
+/* test initialisation with string */
+
+struct str2
+{
+  short s;
+  char str2[];
+};
+
+struct str2 s21 = { 1, "sdcc" };
+struct str2 s22 = { 2, "sdcc is great" }; /* different size */
+
+static void
+testFlexibleArray2(void)
+{
+  /* test sizeof */
+  ASSERT(sizeof(s21) == 2);
+  /* test allocation size */
+#if ! defined(PORT_HOST)
+   ASSERT((char *) &s22 - (char *) &s21 == 2 + 5);
+#endif
+}
diff --git a/support/valdiag/tests/structflexiblearray.c b/support/valdiag/tests/structflexiblearray.c
new file mode 100644 (file)
index 0000000..e3a7ecc
--- /dev/null
@@ -0,0 +1,24 @@
+
+#ifdef TEST1
+struct tag {
+  int good1;
+  int flex[];          /* ERROR(GCC) */
+  int good2;
+} badstruct;           /* ERROR(SDCC) */
+#endif
+
+#ifdef TEST2
+struct tag {
+  int flex[];          /* ERROR(GCC) */
+} badstruct;           /* ERROR(SDCC) */
+#endif
+
+#ifdef TEST3
+struct tag {
+  int good1;
+  struct tag2 {
+    int good2;
+    int flex[];
+  } nestedstruct;      /* IGNORE(SDCC) */
+} badstruct;           /* ERROR(SDCC) */
+#endif