1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Merge pull request #2377 from acqn/Diagnostics

[cc65] Diagnosis improvements
This commit is contained in:
Bob Andrews 2024-01-23 22:16:35 +01:00 committed by GitHub
commit 6c7106c9d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 70 deletions

View File

@ -2417,48 +2417,54 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
/* Parse attributes for this declarator */ /* Parse attributes for this declarator */
ParseAttribute (D); ParseAttribute (D);
/* 'inline' is only allowed on functions */ /* Check a few things for the instance (rather than the type) */
if (Mode != DM_ACCEPT_PARAM_IDENT && if (D->Ident[0] != '\0') {
(D->StorageClass & SC_TYPEMASK) != SC_FUNC && /* Check a few pre-C99 things */
(D->StorageClass & SC_INLINE) == SC_INLINE) { if ((Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE && IsRankInt (Spec->Type)) {
Error ("'inline' on non-function declaration"); /* If the standard was not set explicitly to C89, print a warning
D->StorageClass &= ~SC_INLINE; ** for typedefs with implicit int type specifier.
}
/* Check a few pre-C99 things */
if (D->Ident[0] != '\0' && (Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) {
/* Check and warn about an implicit int return in the function */
if (IsTypeFunc (D->Type) && IsRankInt (GetFuncReturnType (D->Type))) {
/* 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) { if (IS_Get (&Standard) >= STD_C99) {
Warning ("Implicit 'int' return type is an obsolete feature"); if ((D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
Warning ("Implicit 'int' type specifier is an obsolete feature");
} else {
Warning ("Type specifier defaults to 'int' in typedef of '%s'",
D->Ident);
Note ("Implicit 'int' type specifier is an obsolete feature");
}
} }
GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET;
} }
/* For anything that is not a function, check for an implicit int /* Check other things depending on the "kind" of the instance */
** declaration. if ((D->StorageClass & SC_TYPEMASK) == SC_FUNC) {
*/ /* Special handling for main() */
if (!IsTypeFunc (D->Type) && IsRankInt (D->Type)) { if (strcmp (D->Ident, "main") == 0) {
if ((D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { /* main() cannot be a fastcall function */
/* If the standard was not set explicitly to C89, print a warning if (IsQualFastcall (D->Type)) {
** for variables with implicit int type. Error ("'main' cannot be declared __fastcall__");
*/
if (IS_Get (&Standard) >= STD_C99) {
Warning ("Implicit 'int' is an obsolete feature");
} }
} else {
/* If the standard was not set explicitly to C89, print a warning /* main() cannot be an inline function */
** for typedefs with implicit int type. if ((D->StorageClass & SC_INLINE) == SC_INLINE) {
*/ Error ("'main' cannot be declared inline");
if (IS_Get (&Standard) >= STD_C99) { D->StorageClass &= ~SC_INLINE;
Warning ("Type defaults to 'int' in typedef of '%s'", }
D->Ident);
Note ("Implicit 'int' is an obsolete feature"); /* Check return type */
if (GetUnqualRawTypeCode (GetFuncReturnType (D->Type)) != T_INT) {
/* If cc65 extensions aren't enabled, don't allow a main function
** that doesn't return an int.
*/
if (IS_Get (&Standard) != STD_CC65) {
Error ("'main' must always return an int");
}
} }
} }
} else if (Mode != DM_ACCEPT_PARAM_IDENT &&
(D->StorageClass & SC_INLINE) == SC_INLINE) {
/* 'inline' is only allowed on functions */
Error ("'inline' on non-function declaration");
D->StorageClass &= ~SC_INLINE;
} }
} }

View File

@ -450,7 +450,6 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Parse argument declarations and function body. */ /* Parse argument declarations and function body. */
{ {
int ParamComplete; /* If all paramemters have complete types */ int ParamComplete; /* If all paramemters have complete types */
int C99MainFunc = 0;/* Flag for C99 main function returning int */
SymEntry* Param; SymEntry* Param;
const Type* RType; /* Real type used for struct parameters */ const Type* RType; /* Real type used for struct parameters */
const Type* ReturnType; /* Return type */ const Type* ReturnType; /* Return type */
@ -513,34 +512,6 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Mark this as the main function */ /* Mark this as the main function */
CurrentFunc->Flags |= FF_IS_MAIN; CurrentFunc->Flags |= FF_IS_MAIN;
/* Main cannot be a fastcall function */
if (IsQualFastcall (Func->Type)) {
Error ("'main' cannot be declared as __fastcall__");
}
/* main() cannot be an inline function */
if ((Func->Flags & SC_INLINE) == SC_INLINE) {
Error ("'main' cannot be declared inline");
Func->Flags &= ~SC_INLINE;
}
/* Check return type */
if (GetUnqualRawTypeCode (ReturnType) == T_INT) {
/* Determine if this is a main function in a C99 environment that
** returns an int.
*/
if (IS_Get (&Standard) >= STD_C99) {
C99MainFunc = 1;
}
} else {
/* If cc65 extensions aren't enabled, don't allow a main function
** that doesn't return an int.
*/
if (IS_Get (&Standard) != STD_CC65) {
Error ("'main' must always return an int");
}
}
/* Add a forced import of a symbol that is contained in the startup /* Add a forced import of a symbol that is contained in the startup
** code. This will force the startup code to be linked in. ** code. This will force the startup code to be linked in.
*/ */
@ -665,7 +636,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* If this is the main function in a C99 environment returning an int, /* If this is the main function in a C99 environment returning an int,
** let it always return zero. Otherwise output a warning. ** let it always return zero. Otherwise output a warning.
*/ */
if (C99MainFunc) { if (IS_Get (&Standard) >= STD_C99 && GetUnqualRawTypeCode (ReturnType) == T_INT) {
g_getimmed (CF_INT | CF_CONST, 0, 0); g_getimmed (CF_INT | CF_CONST, 0, 0);
} else if (IS_Get (&WarnReturnType)) { } else if (IS_Get (&WarnReturnType)) {
Warning ("Control reaches end of non-void function [-Wreturn-type]"); Warning ("Control reaches end of non-void function [-Wreturn-type]");

View File

@ -1,4 +1,4 @@
bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers
bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature bug1889-missing-identifier.c:3: Warning: Implicit 'int' type specifier is an obsolete feature
bug1889-missing-identifier.c:4: Error: 'inline' on empty declaration bug1889-missing-identifier.c:4: Error: 'inline' on empty declaration
bug1889-missing-identifier.c:6: Error: Expression expected bug1889-missing-identifier.c:6: Error: Expression expected

View File

@ -33,4 +33,6 @@ inline int main(void) /* Error */
f2b(); /* Still imported */ f2b(); /* Still imported */
} }
inline int main(void); /* Error */
/* Warning: non-external inline functions declared but undefined in TU */ /* Warning: non-external inline functions declared but undefined in TU */

View File

@ -13,8 +13,9 @@ inline-error.c:22: Error: 'inline' on non-function declaration
inline-error.c:23: Error: 'inline' on non-function declaration inline-error.c:23: Error: 'inline' on non-function declaration
inline-error.c:24: Error: 'inline' on non-function declaration inline-error.c:24: Error: 'inline' on non-function declaration
inline-error.c:34: Warning: Variable 'fp2' is defined but never used inline-error.c:34: Warning: Variable 'fp2' is defined but never used
inline-error.c:37: Warning: Inline function 'f1a' used but never defined inline-error.c:36: Error: 'main' cannot be declared inline
inline-error.c:37: Warning: Inline function 'f1b' used but never defined inline-error.c:39: Warning: Inline function 'f1a' used but never defined
inline-error.c:37: Warning: Static function 'f1c' used but never defined inline-error.c:39: Warning: Inline function 'f1b' used but never defined
inline-error.c:37: Warning: Inline function 'f2a' used but never defined inline-error.c:39: Warning: Static function 'f1c' used but never defined
inline-error.c:37: Warning: Inline function 'f2b' used but never defined inline-error.c:39: Warning: Inline function 'f2a' used but never defined
inline-error.c:39: Warning: Inline function 'f2b' used but never defined