mirror of
https://github.com/cc65/cc65.git
synced 2024-06-07 23:29:39 +00:00
Merge branch 'master' into fptest
This commit is contained in:
commit
baf4768c84
|
@ -285,11 +285,14 @@ static void Parse (void)
|
|||
*/
|
||||
const char* bssName = GetSegName (SEG_BSS);
|
||||
|
||||
if (Sym->V.BssName && strcmp (Sym->V.BssName, bssName) != 0) {
|
||||
Error ("Global variable '%s' already was defined in the '%s' segment.",
|
||||
Sym->Name, Sym->V.BssName);
|
||||
if (Sym->V.BssName != 0) {
|
||||
if (strcmp (Sym->V.BssName, bssName) != 0) {
|
||||
Error ("Global variable '%s' already was defined in the '%s' segment",
|
||||
Sym->Name, Sym->V.BssName);
|
||||
}
|
||||
} else {
|
||||
Sym->V.BssName = xstrdup (bssName);
|
||||
}
|
||||
Sym->V.BssName = xstrdup (bssName);
|
||||
|
||||
/* This is to make the automatical zeropage setting of the symbol
|
||||
** work right.
|
||||
|
@ -511,7 +514,7 @@ void Compile (const char* FileName)
|
|||
|
||||
/* Mark as defined; so that it will be exported, not imported */
|
||||
Entry->Flags |= SC_DEF;
|
||||
} else {
|
||||
} else if (!IsTypeArray (Entry->Type)) {
|
||||
/* Tentative declared variable is still of incomplete type */
|
||||
Error ("Definition of '%s' has type '%s' that is never completed",
|
||||
Entry->Name,
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) };
|
||||
const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) };
|
||||
const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) };
|
||||
const Type type_short[] = { TYPE(T_SHORT), TYPE(T_END) };
|
||||
const Type type_ushort[] = { TYPE(T_USHORT), TYPE(T_END) };
|
||||
const Type type_int[] = { TYPE(T_INT), TYPE(T_END) };
|
||||
const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) };
|
||||
const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) };
|
||||
|
@ -315,7 +317,7 @@ unsigned CheckedSizeOf (const Type* T)
|
|||
{
|
||||
unsigned Size = SizeOf (T);
|
||||
if (Size == 0) {
|
||||
if (HasUnknownSize (T + 1)) {
|
||||
if (HasUnknownSize (T)) {
|
||||
Error ("Size of type '%s' is unknown", GetFullTypeName (T));
|
||||
} else {
|
||||
Error ("Size of type '%s' is 0", GetFullTypeName (T));
|
||||
|
@ -736,8 +738,10 @@ const Type* GetSignedType (const Type* T)
|
|||
case T_RANK_CHAR:
|
||||
return type_schar;
|
||||
|
||||
case T_RANK_INT:
|
||||
case T_RANK_SHORT:
|
||||
return type_short;
|
||||
|
||||
case T_RANK_INT:
|
||||
return type_int;
|
||||
|
||||
case T_RANK_LONG:
|
||||
|
@ -758,8 +762,10 @@ const Type* GetUnsignedType (const Type* T)
|
|||
case T_RANK_CHAR:
|
||||
return type_uchar;
|
||||
|
||||
case T_RANK_INT:
|
||||
case T_RANK_SHORT:
|
||||
return type_ushort;
|
||||
|
||||
case T_RANK_INT:
|
||||
return type_uint;
|
||||
|
||||
case T_RANK_LONG:
|
||||
|
@ -1025,7 +1031,11 @@ int HasUnknownSize (const Type* T)
|
|||
int TypeHasAttrData (const Type* T)
|
||||
/* Return true if the given type has attribute data */
|
||||
{
|
||||
return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T);
|
||||
return IsClassStruct (T) ||
|
||||
IsTypeArray (T) ||
|
||||
IsClassFunc (T) ||
|
||||
IsTypeVoid (T) ||
|
||||
IsTypeBitField (T);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -215,6 +215,8 @@ struct Type {
|
|||
extern const Type type_char[];
|
||||
extern const Type type_schar[];
|
||||
extern const Type type_uchar[];
|
||||
extern const Type type_short[];
|
||||
extern const Type type_ushort[];
|
||||
extern const Type type_int[];
|
||||
extern const Type type_uint[];
|
||||
extern const Type type_long[];
|
||||
|
|
|
@ -493,33 +493,36 @@ static void FixQualifiers (Type* DataType)
|
|||
|
||||
|
||||
|
||||
static void CheckArrayElementType (Type* DataType)
|
||||
static void CheckArrayElementType (const Type* T)
|
||||
/* Check if data type consists of arrays of incomplete element types */
|
||||
{
|
||||
Type* T = DataType;
|
||||
|
||||
while (T->C != T_END) {
|
||||
if (IsTypeArray (T)) {
|
||||
/* If the array is multi-dimensional, keep going until we get the
|
||||
** true element type.
|
||||
*/
|
||||
++T;
|
||||
if (IsIncompleteESUType (T)) {
|
||||
/* We cannot have an array of incomplete elements */
|
||||
Error ("Array of incomplete element type '%s'", GetFullTypeName (T));
|
||||
} else if (SizeOf (T) == 0) {
|
||||
/* If the array is multi-dimensional, try to get the true
|
||||
** element type.
|
||||
*/
|
||||
if (IsTypeArray (T)) {
|
||||
continue;
|
||||
}
|
||||
/* We could support certain 0-size element types as an extension */
|
||||
if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) {
|
||||
Error ("Array of 0-size element type '%s'", GetFullTypeName (T));
|
||||
if (SizeOf (T) == 0) {
|
||||
if (IsTypeArray (T) || IsIncompleteESUType (T)) {
|
||||
/* We cannot have an array of incomplete elements */
|
||||
if (!IsTypeArray (T) || GetElementCount (T) == UNSPECIFIED) {
|
||||
Error ("Array of incomplete element type '%s'",
|
||||
GetFullTypeName (T));
|
||||
return;
|
||||
}
|
||||
} else if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) {
|
||||
/* We could support certain 0-size element types as an extension */
|
||||
Error ("Array of 0-size element type '%s'",
|
||||
GetFullTypeName (T));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (IsTypeStruct (T)) {
|
||||
/* Elements cannot contain flexible array members themselves */
|
||||
if (IsClassStruct (T)) {
|
||||
SymEntry* TagEntry = GetESUTagSym (T);
|
||||
if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) {
|
||||
Error ("Invalid use of struct with flexible array member");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -756,7 +759,7 @@ static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags)
|
|||
Flags |= SC_FICTITIOUS;
|
||||
}
|
||||
|
||||
return AddEnumSym (Name, Flags, MemberType, FieldTab, DSFlags);
|
||||
return AddEnumSym (Name, SC_DEF | Flags, MemberType, FieldTab, DSFlags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1200,9 +1203,7 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
|
|||
if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) {
|
||||
Field->Flags |= SC_HAVEFAM;
|
||||
Flags |= SC_HAVEFAM;
|
||||
if (IsTypeStruct (Decl.Type)) {
|
||||
Error ("Invalid use of struct with flexible array member");
|
||||
}
|
||||
Error ("Invalid use of struct with flexible array member");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,12 @@ typedef struct x {
|
|||
int b[]; /* Ok: Flexible array member can be last */
|
||||
} x;
|
||||
|
||||
typedef union u {
|
||||
int a;
|
||||
x x; /* Ok: Union member can contain flexible array member */
|
||||
} u;
|
||||
|
||||
struct y {
|
||||
x x; /* Not ok: Contains flexible array member */
|
||||
u u; /* Not ok: Contains union that contains flexible array member */
|
||||
int a;
|
||||
};
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
/* Bug #2017 - cc65 erroneously allows arrays of structs with flexible array members */
|
||||
|
||||
struct z {
|
||||
typedef struct x {
|
||||
int a;
|
||||
int c;
|
||||
int b[];
|
||||
};
|
||||
int b[]; /* Ok: Flexible array member can be last */
|
||||
} x;
|
||||
|
||||
struct z y[3]; /* Should be an error */
|
||||
typedef union u {
|
||||
int a;
|
||||
x x; /* Ok: Union member can contain flexible array member */
|
||||
} u;
|
||||
|
||||
union u y[3]; /* Should be an error */
|
||||
|
|
6
test/err/zero-size.c
Normal file
6
test/err/zero-size.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
char a[][] = { 0, 0 }; /* Error: Array type has incomplete element type 'char[]' */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
31
test/val/fam.c
Normal file
31
test/val/fam.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Bug #2016 and #2017 - flexible array members */
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b[]; /* Ok: Flexible array member can be last */
|
||||
} X;
|
||||
|
||||
typedef union {
|
||||
X x; /* Ok: Contains flexible array member */
|
||||
int a;
|
||||
} U;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
int a;
|
||||
};
|
||||
int b[]; /* Ok: Flexible array member can be last */
|
||||
} Y;
|
||||
|
||||
X x;
|
||||
U u;
|
||||
Y y;
|
||||
|
||||
_Static_assert(sizeof x == sizeof (int), "sizeof x != sizeof (int)");
|
||||
_Static_assert(sizeof u == sizeof (int), "sizeof u != sizeof (int)");
|
||||
_Static_assert(sizeof y == sizeof (int), "sizeof y != sizeof (int)");
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user