1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 22:25:28 +00:00

Fixed diagnostics on qualifiers of function return types.

This commit is contained in:
acqn
2023-10-28 15:24:13 +08:00
parent 8e62cbf092
commit d424883716

View File

@@ -493,8 +493,44 @@ static void FixQualifiers (Type* DataType)
static void FixFunctionReturnType (Type* T)
/* Check if the data type consists of any functions returning forbidden return
** types and remove qualifiers from the return types if they are not void.
*/
{
while (T->C != T_END) {
if (IsTypeFunc (T)) {
++T;
/* Functions may not return functions or arrays */
if (IsTypeFunc (T)) {
Error ("Functions are not allowed to return functions");
} else if (IsTypeArray (T)) {
Error ("Functions are not allowed to return arrays");
}
/* The return type must not be qualified */
if ((GetQualifier (T) & T_QUAL_CVR) != T_QUAL_NONE) {
/* We are stricter than the standard here */
if (GetRawTypeRank (T) == T_RANK_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");
T[0].C &= ~T_QUAL_CVR;
}
}
} else {
++T;
}
}
}
static void CheckArrayElementType (const Type* T) static void CheckArrayElementType (const Type* T)
/* Check if data type consists of arrays of incomplete element types */ /* Check recursively if type consists of arrays of forbidden element types */
{ {
while (T->C != T_END) { while (T->C != T_END) {
if (IsTypeArray (T)) { if (IsTypeArray (T)) {
@@ -2061,46 +2097,39 @@ void ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode)
/* Do several fixes on qualifiers */ /* Do several fixes on qualifiers */
FixQualifiers (D->Type); FixQualifiers (D->Type);
/* Check if the data type consists of any arrays of forbidden types */ /* Check if the data type consists of any functions returning forbidden return
CheckArrayElementType (D->Type); ** types and remove qualifiers from the return types if they are not void.
*/
FixFunctionReturnType (D->Type);
/* If we have a function, add a special storage class */ /* Check recursively if the data type consists of arrays of forbidden types */
if (IsTypeFunc (D->Type)) { CheckArrayElementType (D->Type);
D->StorageClass |= SC_FUNC;
}
/* Parse attributes for this declarator */ /* Parse attributes for this declarator */
ParseAttribute (D); ParseAttribute (D);
/* Check several things for function or function pointer types */ /* If we have a function, add a special storage class */
if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { if (IsTypeFunc (D->Type)) {
/* A function. Check the return type */ D->StorageClass |= SC_FUNC;
Type* RetType = GetFuncReturnTypeModifiable (D->Type);
/* Functions may not return functions or arrays */ } else if (!IsTypeVoid (D->Type)) {
if (IsTypeFunc (RetType)) { /* Check the size of the generated type */
Error ("Functions are not allowed to return functions"); unsigned Size = SizeOf (D->Type);
} else if (IsTypeArray (RetType)) {
Error ("Functions are not allowed to return arrays");
}
/* The return type must not be qualified */ if (Size >= 0x10000) {
if (GetQualifier (RetType) != T_QUAL_NONE && RetType[1].C == T_END) { if (D->Ident[0] != '\0') {
Error ("Size of '%s' is invalid (0x%06X)", D->Ident, Size);
if (GetRawTypeRank (RetType) == T_RANK_VOID) {
/* A qualified void type is always an error */
Error ("function definition has qualified void return type");
} else { } else {
/* For others, qualifiers are ignored */ Error ("Invalid size in declaration (0x%06X)", Size);
Warning ("type qualifiers ignored on function return type");
RetType[0].C = GetUnqualRawTypeCode (RetType);
} }
} }
}
/* Warn about an implicit int return in the function */ /* Check a few pre-C99 things */
if ((Spec->Flags & DS_DEF_TYPE) != 0 && if ((Spec->Flags & DS_DEF_TYPE) != 0) {
RetType[0].C == T_INT && RetType[1].C == T_END) { /* 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 /* Function has an implicit int return. Output a warning if we don't
** have the C89 standard enabled explicitly. ** have the C89 standard enabled explicitly.
*/ */
@@ -2110,29 +2139,16 @@ void ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode)
GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET; GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET;
} }
} /* For anthing that is not a function or typedef, check for an implicit
** int declaration.
/* For anthing that is not a function or typedef, check for an implicit
** int declaration.
*/
if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
(D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
/* If the standard was not set explicitly to C89, print a warning
** for variables with implicit int type.
*/ */
if ((Spec->Flags & DS_DEF_TYPE) != 0 && IS_Get (&Standard) >= STD_C99) { if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
Warning ("Implicit 'int' is an obsolete feature"); (D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
} /* If the standard was not set explicitly to C89, print a warning
} ** for variables with implicit int type.
*/
if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) { if (IS_Get (&Standard) >= STD_C99) {
/* Check the size of the generated type */ Warning ("Implicit 'int' is an obsolete feature");
unsigned Size = SizeOf (D->Type);
if (Size >= 0x10000) {
if (D->Ident[0] != '\0') {
Error ("Size of '%s' is invalid (0x%06X)", D->Ident, Size);
} else {
Error ("Invalid size in declaration (0x%06X)", Size);
} }
} }
} }