Added several type checks, especially for functions. Moved check for implicit

int return type.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3858 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2008-07-31 18:31:15 +00:00
parent 52c0c284da
commit 22d89f558e

View File

@@ -303,7 +303,7 @@ static void ParseEnumDecl (void)
/* We expect an identifier */ /* We expect an identifier */
if (CurTok.Tok != TOK_IDENT) { if (CurTok.Tok != TOK_IDENT) {
Error ("Identifier expected"); Error ("Identifier expected");
continue; continue;
} }
/* Remember the identifier and skip it */ /* Remember the identifier and skip it */
@@ -503,7 +503,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
D->Type[0].C = T_SHORT; D->Type[0].C = T_SHORT;
D->Type[1].C = T_END; D->Type[1].C = T_END;
} }
break; break;
case TOK_INT: case TOK_INT:
NextToken (); NextToken ();
@@ -530,7 +530,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
case TOK_LONG: case TOK_LONG:
NextToken (); NextToken ();
OptionalInt (); OptionalInt ();
D->Type[0].C = T_LONG; D->Type[0].C = T_LONG;
D->Type[1].C = T_END; D->Type[1].C = T_END;
break; break;
@@ -609,7 +609,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
/* Declare the struct in the current scope */ /* Declare the struct in the current scope */
Entry = ParseStructDecl (Ident, StructType); Entry = ParseStructDecl (Ident, StructType);
/* Encode the struct entry into the type */ /* Encode the struct entry into the type */
D->Type[0].C = StructType; D->Type[0].C = StructType;
SetSymEntry (D->Type, Entry); SetSymEntry (D->Type, Entry);
D->Type[1].C = T_END; D->Type[1].C = T_END;
break; break;
@@ -742,7 +742,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
ParseDecl (&Spec, &Decl, DM_NEED_IDENT); ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] != '\0') { if (Decl.Ident[0] != '\0') {
/* We have a name given. Search for the symbol */ /* We have a name given. Search for the symbol */
SymEntry* Sym = FindLocalSym (Decl.Ident); SymEntry* Sym = FindLocalSym (Decl.Ident);
if (Sym) { if (Sym) {
/* Found it, change the default type to the one given */ /* Found it, change the default type to the one given */
@@ -849,7 +849,7 @@ static void ParseAnsiParamList (FuncDesc* F)
static FuncDesc* ParseFuncDecl (const DeclSpec* Spec) static FuncDesc* ParseFuncDecl (void)
/* Parse the argument list of a function. */ /* Parse the argument list of a function. */
{ {
unsigned Offs; unsigned Offs;
@@ -881,19 +881,6 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec)
} }
} }
/* Check for an implicit int return in the function */
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
Spec->Type[0].C == T_INT &&
Spec->Type[1].C == T_END) {
/* Function has an implicit int return. Output a warning if we don't
* have the C89 standard enabled explicitly.
*/
if (IS_Get (&Standard) >= STD_C99) {
Warning ("Implicit `int' return type is an obsolete feature");
}
F->Flags |= FD_OLDSTYLE_INTRET;
}
/* Parse params */ /* Parse params */
if ((F->Flags & FD_OLDSTYLE) == 0) { if ((F->Flags & FD_OLDSTYLE) == 0) {
/* New style function */ /* New style function */
@@ -1031,21 +1018,21 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
/* Remember the current type pointer */ /* Remember the current type pointer */
Type* T = D->Type + D->Index; Type* T = D->Type + D->Index;
/* Read the flags */ /* Read the flags */
unsigned Flags = FunctionModifierFlags (); unsigned Flags = FunctionModifierFlags ();
/* Parse the function */ /* Parse the function */
Decl (Spec, D, Mode); Decl (Spec, D, Mode);
/* Check that we have a function */ /* Check that we have a function */
if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) { if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
Error ("Function modifier applied to non function"); Error ("Function modifier applied to non function");
} else { } else {
ApplyFunctionModifiers (T, Flags); ApplyFunctionModifiers (T, Flags);
} }
/* Done */ /* Done */
return; return;
} }
if (CurTok.Tok == TOK_LPAREN) { if (CurTok.Tok == TOK_LPAREN) {
@@ -1080,19 +1067,19 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
if (CurTok.Tok == TOK_LPAREN) { if (CurTok.Tok == TOK_LPAREN) {
/* Function declaration */ /* Function declaration */
FuncDesc* F; FuncDesc* F;
NextToken (); NextToken ();
/* Parse the function declaration */ /* Parse the function declaration */
F = ParseFuncDecl (Spec); F = ParseFuncDecl ();
/* Add the function type. Be sure to bounds check the type buffer */ /* Add the function type. Be sure to bounds check the type buffer */
AddFuncTypeToDeclaration (D, F); AddFuncTypeToDeclaration (D, F);
} else { } else {
/* Array declaration */ /* Array declaration */
long Size = UNSPECIFIED; long Size = UNSPECIFIED;
NextToken (); NextToken ();
/* Read the size if it is given */ /* Read the size if it is given */
if (CurTok.Tok != TOK_RBRACK) { if (CurTok.Tok != TOK_RBRACK) {
ExprDesc Expr; ExprDesc Expr;
ConstAbsIntExpr (hie1, &Expr); ConstAbsIntExpr (hie1, &Expr);
@@ -1108,8 +1095,8 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
} }
ConsumeRBrack (); ConsumeRBrack ();
/* Add the array type with the size */ /* Add the array type with the size */
AddArrayToDeclaration (D, Size); AddArrayToDeclaration (D, Size);
} }
} }
} }
@@ -1160,17 +1147,58 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
/* Fix any type qualifiers attached to an array type */ /* Fix any type qualifiers attached to an array type */
FixArrayQualifiers (D->Type); FixArrayQualifiers (D->Type);
/* Check several things for function or function pointer types */
if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) {
/* A function. Check the return type */
Type* RetType = GetFuncReturn (D->Type);
/* Functions may not return functions or arrays */
if (IsTypeFunc (RetType)) {
Error ("Functions are not allowed to return functions");
} else if (IsTypeArray (RetType)) {
Error ("Functions are not allowed to return arrays");
}
/* The return type must not be qualified */
if (GetQualifier (RetType) != T_QUAL_NONE && RetType[1].C == T_END) {
if (GetType (RetType) == T_TYPE_VOID) {
/* A qualified void type is always an error */
Error ("function definition has qualified void return type");
} else {
/* For others, qualifiers are ignored */
Warning ("type qualifiers ignored on function return type");
RetType[0].C = UnqualifiedType (RetType[0].C);
}
}
/* Warn about an implicit int return in the function */
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
RetType[0].C == T_INT && RetType[1].C == T_END) {
/* Function has an implicit int return. Output a warning if we don't
* have the C89 standard enabled explicitly.
*/
if (IS_Get (&Standard) >= STD_C99) {
Warning ("Implicit `int' return type is an obsolete feature");
}
GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET;
}
}
/* Check the size of the generated type */ /* Check the size of the generated type */
if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) { if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) {
unsigned Size = SizeOf (D->Type); unsigned Size = SizeOf (D->Type);
if (Size >= 0x10000) { if (Size >= 0x10000) {
if (D->Ident[0] != '\0') { if (D->Ident[0] != '\0') {
Error ("Size of `%s' is invalid (0x%06X)", D->Ident, Size); Error ("Size of `%s' is invalid (0x%06X)", D->Ident, Size);
} else { } else {
Error ("Invalid size in declaration (0x%06X)", Size); Error ("Invalid size in declaration (0x%06X)", Size);
} }
} }
} }
} }