Allowed old-style (K and R) function declarations to be fastcall.
That lets them match old-style definitions. It avoids "Type conflict" error messages. It allows shorter function calls. Fixed the types of some variables in "test/ref/otccex.c". It avoids crashes on 64-bit Windows (32-bit Windows with 64-bit pointers).
This commit is contained in:
@@ -171,8 +171,9 @@ static void Parse (void)
|
||||
(CurTok.Tok != TOK_SEMI)) {
|
||||
|
||||
FuncDesc* D = GetFuncDesc (Decl.Type);
|
||||
|
||||
if (D->Flags & FD_EMPTY) {
|
||||
D->Flags = (D->Flags & ~(FD_EMPTY | FD_VARIADIC)) | FD_VOID_PARAM;
|
||||
D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1132,7 +1132,7 @@ static Type* ParamTypeCvt (Type* T)
|
||||
|
||||
|
||||
static void ParseOldStyleParamList (FuncDesc* F)
|
||||
/* Parse an old style (K&R) parameter list */
|
||||
/* Parse an old-style (K&R) parameter list */
|
||||
{
|
||||
/* Some fix point tokens that are used for error recovery */
|
||||
static const token_t TokenList[] = { TOK_COMMA, TOK_RPAREN, TOK_SEMI };
|
||||
@@ -1234,7 +1234,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
|
||||
|
||||
|
||||
static void ParseAnsiParamList (FuncDesc* F)
|
||||
/* Parse a new style (ANSI) parameter list */
|
||||
/* Parse a new-style (ANSI) parameter list */
|
||||
{
|
||||
/* Parse params */
|
||||
while (CurTok.Tok != TOK_RPAREN) {
|
||||
@@ -1330,32 +1330,30 @@ static FuncDesc* ParseFuncDecl (void)
|
||||
|
||||
/* Check for several special parameter lists */
|
||||
if (CurTok.Tok == TOK_RPAREN) {
|
||||
/* Parameter list is empty */
|
||||
F->Flags |= (FD_EMPTY | FD_VARIADIC);
|
||||
/* Parameter list is empty (K&R-style) */
|
||||
F->Flags |= FD_EMPTY;
|
||||
} else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) {
|
||||
/* Parameter list declared as void */
|
||||
NextToken ();
|
||||
F->Flags |= FD_VOID_PARAM;
|
||||
} else if (CurTok.Tok == TOK_IDENT &&
|
||||
(NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) {
|
||||
/* If the identifier is a typedef, we have a new style parameter list,
|
||||
** if it's some other identifier, it's an old style parameter list.
|
||||
/* If the identifier is a typedef, we have a new-style parameter list;
|
||||
** if it's some other identifier, it's an old-style parameter list.
|
||||
*/
|
||||
Sym = FindSym (CurTok.Ident);
|
||||
if (Sym == 0 || !SymIsTypeDef (Sym)) {
|
||||
/* Old style (K&R) function. */
|
||||
/* Old-style (K&R) function. */
|
||||
F->Flags |= FD_OLDSTYLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse params */
|
||||
if ((F->Flags & FD_OLDSTYLE) == 0) {
|
||||
|
||||
/* New style function */
|
||||
/* New-style function */
|
||||
ParseAnsiParamList (F);
|
||||
|
||||
} else {
|
||||
/* Old style function */
|
||||
/* Old-style function */
|
||||
ParseOldStyleParamList (F);
|
||||
}
|
||||
|
||||
|
||||
@@ -359,8 +359,8 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall)
|
||||
CHECK ((Param->Flags & SC_PARAM) != 0);
|
||||
}
|
||||
} else if (!Ellipsis) {
|
||||
/* Too many arguments. Do we have an open param list? */
|
||||
if ((Func->Flags & FD_VARIADIC) == 0) {
|
||||
/* Too many arguments. Do we have an open or empty param. list? */
|
||||
if ((Func->Flags & (FD_VARIADIC | FD_EMPTY)) == 0) {
|
||||
/* End of param list reached, no ellipsis */
|
||||
Error ("Too many arguments in function call");
|
||||
}
|
||||
@@ -401,8 +401,9 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall)
|
||||
Flags |= TypeOf (Expr.Type);
|
||||
|
||||
/* If this is a fastcall function, don't push the last argument */
|
||||
if (ParamCount != Func->ParamCount || !IsFastcall) {
|
||||
if ((CurTok.Tok == TOK_COMMA && NextTok.Tok != TOK_RPAREN) || !IsFastcall) {
|
||||
unsigned ArgSize = sizeofarg (Flags);
|
||||
|
||||
if (FrameSize > 0) {
|
||||
/* We have the space already allocated, store in the frame.
|
||||
** Because of invalid type conversions (that have produced an
|
||||
@@ -472,8 +473,14 @@ static void FunctionCall (ExprDesc* Expr)
|
||||
/* Handle function pointers transparently */
|
||||
IsFuncPtr = IsTypeFuncPtr (Expr->Type);
|
||||
if (IsFuncPtr) {
|
||||
/* Check whether it's a fastcall function that has parameters */
|
||||
IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && Func->ParamCount > 0 &&
|
||||
/* Check whether it's a fastcall function that has parameters.
|
||||
** Note: if a function is forward-declared in the old K & R style, then
|
||||
** it may be called with any number of arguments, even though its
|
||||
** parameter count is zero. Handle K & R functions as though there are
|
||||
** parameters.
|
||||
*/
|
||||
IsFastcall = (Func->Flags & FD_VARIADIC) == 0 &&
|
||||
(Func->ParamCount > 0 || (Func->Flags & FD_EMPTY)) &&
|
||||
(AutoCDecl ?
|
||||
IsQualFastcall (Expr->Type + 1) :
|
||||
!IsQualCDecl (Expr->Type + 1));
|
||||
|
||||
Reference in New Issue
Block a user