Merge branch 'master' into StaticConst

This commit is contained in:
acqn
2020-08-27 06:27:23 +08:00
committed by GitHub
45 changed files with 872 additions and 200 deletions

View File

@@ -157,6 +157,11 @@ void Assignment (ExprDesc* Expr)
Error ("Assignment to const");
}
/* Check for assignment to incomplete type */
if (IsIncompleteESUType (ltype)) {
Error ("Assignment to incomplete type '%s'", GetFullTypeName (ltype));
}
/* Skip the '=' token */
NextToken ();

View File

@@ -112,6 +112,7 @@ void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
CodeEntry* E = CL_GetRef (OldLabel, Count);
/* Change the reference to the new label */
CHECK (E->JumpTo != NULL);
CHECK (E->JumpTo == OldLabel);
CL_AddRef (NewLabel, E);

View File

@@ -140,19 +140,10 @@ static void Parse (void)
comma = 0;
while (1) {
Declaration Decl;
Declaration Decl;
/* Read the next declaration */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] == '\0') {
NextToken ();
break;
}
if ((Decl.StorageClass & SC_FICTITIOUS) == SC_FICTITIOUS) {
/* Failed parsing */
goto SkipOneDecl;
}
/* Check if we must reserve storage for the variable. We do this,
**
@@ -163,8 +154,9 @@ static void Parse (void)
**
** This means that "extern int i;" will not get storage allocated.
*/
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF &&
(Decl.StorageClass & SC_FICTITIOUS) != SC_FICTITIOUS) {
if ((Spec.Flags & DS_DEF_STORAGE) != 0 ||
(Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC ||
((Decl.StorageClass & SC_EXTERN) != 0 &&
@@ -296,7 +288,6 @@ static void Parse (void)
}
SkipOneDecl:
/* Check for end of declaration list */
if (CurTok.Tok == TOK_COMMA) {
NextToken ();
@@ -452,10 +443,6 @@ void Compile (const char* FileName)
}
Sym = GetSymType (GetElementType (Entry->Type));
if (Size == 0 && Sym != 0 && SymIsDef (Sym)) {
/* Array of 0-size elements */
Warning ("Array '%s[]' has 0-sized elements", Entry->Name);
}
}
/* For non-ESU types, Size != 0 */

View File

@@ -687,7 +687,10 @@ const Type* GetUnderlyingType (const Type* Type)
Internal ("Enum tag type error in GetUnderlyingTypeCode");
}
return ((SymEntry*)Type->A.P)->V.E.Type;
/* If incomplete enum type is used, just return its raw type */
if (((SymEntry*)Type->A.P)->V.E.Type != 0) {
return ((SymEntry*)Type->A.P)->V.E.Type;
}
}
return Type;
@@ -1247,9 +1250,14 @@ Type* IntPromotion (Type* T)
** to unsigned int.
*/
return IsSignUnsigned (T) ? type_uint : type_int;
} else {
/* Otherwise, the type is not smaller than int, so leave it alone. */
} else if (!IsIncompleteESUType (T)) {
/* The type is a complete type not smaller than int, so leave it alone. */
return T;
} else {
/* Otherwise, this is an incomplete enum, and there is expceted to be an error already.
** Assume int to avoid further errors.
*/
return type_int;
}
}

View File

@@ -457,6 +457,37 @@ static unsigned ParseOneStorageClass (void)
static void CheckArrayElementType (Type* DataType)
/* Check if data type consists of arrays of incomplete element types */
{
Type* T = DataType;
while (T->C != T_END) {
if (IsTypeArray (T)) {
++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));
}
}
} else {
++T;
}
}
}
static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
/* Parse a storage class */
{
@@ -908,8 +939,15 @@ static SymEntry* ParseUnionDecl (const char* Name)
}
}
/* Check for incomplete type */
if (IsIncompleteESUType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'",
Decl.Ident,
GetFullTypeName (Decl.Type));
}
/* Handle sizes */
FieldSize = CheckedSizeOf (Decl.Type);
FieldSize = SizeOf (Decl.Type);
if (FieldSize > UnionSize) {
UnionSize = FieldSize;
}
@@ -946,16 +984,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
FieldTab = GetSymTab ();
LeaveStructLevel ();
/* Empty union is not supported now */
if (UnionSize == 0) {
Error ("Empty union type '%s' is not supported", Name);
}
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Empty union is not supported now */
if (UnionSize == 0) {
Error ("Empty union type '%s' is not supported", Name);
}
/* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab);
}
@@ -1092,6 +1130,13 @@ static SymEntry* ParseStructDecl (const char* Name)
}
}
/* Check for incomplete type */
if (IsIncompleteESUType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'",
Decl.Ident,
GetFullTypeName (Decl.Type));
}
/* Add a field entry to the table */
if (FieldWidth > 0) {
/* Full bytes have already been added to the StructSize,
@@ -1116,7 +1161,7 @@ static SymEntry* ParseStructDecl (const char* Name)
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
}
if (!FlexibleMember) {
StructSize += CheckedSizeOf (Decl.Type);
StructSize += SizeOf (Decl.Type);
}
}
@@ -1143,16 +1188,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
FieldTab = GetSymTab ();
LeaveStructLevel ();
/* Empty struct is not supported now */
if (StructSize == 0) {
Error ("Empty struct type '%s' is not supported", Name);
}
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Empty struct is not supported now */
if (StructSize == 0) {
Error ("Empty struct type '%s' is not supported", Name);
}
/* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab);
}
@@ -1904,6 +1949,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
/* Do several fixes on qualifiers */
FixQualifiers (D->Type);
/* Check if the data type consists of any arrays of forbidden types */
CheckArrayElementType (D->Type);
/* If we have a function, add a special storage class */
if (IsTypeFunc (D->Type)) {
D->StorageClass |= SC_FUNC;
@@ -1975,10 +2023,15 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
Error ("Invalid size in declaration (0x%06X)", Size);
}
}
}
if (PrevErrorCount != ErrorCount) {
/* Don't give storage if the declaration is not parsed correctly */
D->StorageClass |= SC_DECL | SC_FICTITIOUS;
if (PrevErrorCount != ErrorCount) {
/* Make the declaration fictitious if is is not parsed correctly */
D->StorageClass |= SC_DECL | SC_FICTITIOUS;
if (Mode == DM_NEED_IDENT && D->Ident[0] == '\0') {
/* Use a fictitious name for the identifier if it is missing */
AnonName (D->Ident, "global");
}
}
}
@@ -2223,7 +2276,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Get the array data */
Type* ElementType = GetElementType (T);
unsigned ElementSize = CheckedSizeOf (ElementType);
unsigned ElementSize = SizeOf (ElementType);
long ElementCount = GetElementCount (T);
/* Special handling for a character array initialized by a literal */

View File

@@ -1862,8 +1862,8 @@ static void UnaryOp (ExprDesc* Expr)
/* Value is not constant */
LoadExpr (CF_NONE, Expr);
/* Get the type of the expression */
Flags = TypeOf (Expr->Type);
/* Adjust the type of the value */
Flags = g_typeadjust (TypeOf (Expr->Type), TypeOf (type_int) | CF_CONST);
/* Handle the operation */
switch (Tok) {
@@ -1876,6 +1876,9 @@ static void UnaryOp (ExprDesc* Expr)
/* The result is an rvalue in the primary */
ED_FinalizeRValLoad (Expr);
}
/* Adjust the type of the expression */
Expr->Type = IntPromotion (Expr->Type);
}

View File

@@ -142,6 +142,10 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
BitFieldFullWidthFlags |= CF_UNSIGNED;
}
} else if ((Flags & CF_TYPEMASK) == 0) {
/* If Expr is an incomplete ESY type, bail out */
if (IsIncompleteESUType (Expr->Type)) {
return;
}
Flags |= TypeOf (Expr->Type);
}

View File

@@ -173,7 +173,11 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}
@@ -360,7 +364,11 @@ static void ParseAutoDecl (Declaration* Decl)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}
@@ -414,7 +422,11 @@ static void ParseStaticDecl (Declaration* Decl)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}