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:
Greg King
2019-07-22 09:05:01 -04:00
parent cceffbdb8c
commit a0db846a97
7 changed files with 66 additions and 75 deletions

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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));