Fixed type comparisons of typedefs and arrays.
This commit is contained in:
@@ -558,34 +558,46 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags
|
|||||||
unsigned E_SCType = Entry->Flags & SC_TYPEMASK;
|
unsigned E_SCType = Entry->Flags & SC_TYPEMASK;
|
||||||
unsigned SCType = Flags & SC_TYPEMASK;
|
unsigned SCType = Flags & SC_TYPEMASK;
|
||||||
|
|
||||||
/* Some symbols may be redeclared if certain requirements are met */
|
/* Existing typedefs cannot be redeclared as anything different */
|
||||||
if (IsTypeArray (T) && IsTypeArray (E_Type)) {
|
if (E_SCType == SC_TYPEDEF) {
|
||||||
|
|
||||||
/* Get the array sizes */
|
if (SCType == SC_TYPEDEF) {
|
||||||
long Size = GetElementCount (T);
|
if (TypeCmp (E_Type, T) < TC_IDENTICAL) {
|
||||||
long ESize = GetElementCount (E_Type);
|
Error ("Conflicting types for typedef '%s'", Entry->Name);
|
||||||
|
Entry = 0;
|
||||||
/* If we are handling arrays, the old entry or the new entry may be
|
|
||||||
** an incomplete declaration. Accept this, and if the exsting entry
|
|
||||||
** is incomplete, complete it.
|
|
||||||
*/
|
|
||||||
if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
|
|
||||||
TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) {
|
|
||||||
/* Types not identical: Conflicting types */
|
|
||||||
Error ("Conflicting array types for '%s[]'", Entry->Name);
|
|
||||||
Entry = 0;
|
|
||||||
} else {
|
|
||||||
/* Check if we have a size in the existing definition */
|
|
||||||
if (ESize == UNSPECIFIED) {
|
|
||||||
/* Existing, size not given, use size from new def */
|
|
||||||
SetElementCount (E_Type, Size);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name);
|
||||||
|
Entry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* We have a symbol with this name already */
|
/* Some symbols may be redeclared if certain requirements are met */
|
||||||
if ((Entry->Flags & SC_FUNC) == SC_FUNC) {
|
if (IsTypeArray (T) && IsTypeArray (E_Type)) {
|
||||||
|
|
||||||
|
/* Get the array sizes */
|
||||||
|
long Size = GetElementCount (T);
|
||||||
|
long ESize = GetElementCount (E_Type);
|
||||||
|
|
||||||
|
/* If we are handling arrays, the old entry or the new entry may be
|
||||||
|
** an incomplete declaration. Accept this, and if the exsting entry
|
||||||
|
** is incomplete, complete it.
|
||||||
|
*/
|
||||||
|
if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
|
||||||
|
TypeCmp (T + 1, E_Type + 1) < TC_EQUAL) {
|
||||||
|
/* Conflicting element types */
|
||||||
|
Error ("Conflicting array types for '%s[]'", Entry->Name);
|
||||||
|
Entry = 0;
|
||||||
|
} else {
|
||||||
|
/* Check if we have a size in the existing definition */
|
||||||
|
if (ESize == UNSPECIFIED) {
|
||||||
|
/* Existing, size not given, use size from new def */
|
||||||
|
SetElementCount (E_Type, Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ((Entry->Flags & SC_FUNC) == SC_FUNC) {
|
||||||
|
|
||||||
/* In case of a function, use the new type descriptor, since it
|
/* In case of a function, use the new type descriptor, since it
|
||||||
** contains pointers to the new symbol tables that are needed if
|
** contains pointers to the new symbol tables that are needed if
|
||||||
@@ -616,22 +628,9 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags
|
|||||||
Entry = 0;
|
Entry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (E_SCType == SC_TYPEDEF) {
|
|
||||||
|
|
||||||
if (SCType == SC_TYPEDEF) {
|
|
||||||
/* New typedef must be identical */
|
|
||||||
if (TypeCmp (E_Type, T) < TC_EQUAL) {
|
|
||||||
Error ("Conflicting types for typedef '%s'", Entry->Name);
|
|
||||||
Entry = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Error ("Redefinition of typedef '%s' as different kind of symbol", Entry->Name);
|
|
||||||
Entry = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* New type must be identical */
|
/* New type must be equivalent */
|
||||||
if (SCType != E_SCType) {
|
if (SCType != E_SCType) {
|
||||||
Error ("Redefinition of '%s' as different kind of symbol", Entry->Name);
|
Error ("Redefinition of '%s' as different kind of symbol", Entry->Name);
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
*/
|
*/
|
||||||
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
|
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
|
||||||
RightType = T_TYPE_PTR;
|
RightType = T_TYPE_PTR;
|
||||||
|
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the underlying types are not identical, the types are incompatible */
|
/* If the underlying types are not identical, the types are incompatible */
|
||||||
@@ -350,12 +351,14 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
/* Check member count */
|
/* Check member count */
|
||||||
LeftCount = GetElementCount (lhs);
|
LeftCount = GetElementCount (lhs);
|
||||||
RightCount = GetElementCount (rhs);
|
RightCount = GetElementCount (rhs);
|
||||||
if (LeftCount != UNSPECIFIED &&
|
if (LeftCount != RightCount) {
|
||||||
RightCount != UNSPECIFIED &&
|
if (LeftCount != UNSPECIFIED &&
|
||||||
LeftCount != RightCount) {
|
RightCount != UNSPECIFIED) {
|
||||||
/* Member count given but different */
|
/* Member count given but different */
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
SetResult (Result, TC_INCOMPATIBLE);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
SetResult (Result, TC_EQUAL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ typedef enum {
|
|||||||
TC_COMPATIBLE = TC_SIGN_DIFF, /* Compatible types */
|
TC_COMPATIBLE = TC_SIGN_DIFF, /* Compatible types */
|
||||||
TC_QUAL_DIFF, /* Types differ in qualifier of pointer */
|
TC_QUAL_DIFF, /* Types differ in qualifier of pointer */
|
||||||
TC_STRICT_COMPATIBLE, /* Strict compatibility */
|
TC_STRICT_COMPATIBLE, /* Strict compatibility */
|
||||||
TC_EQUAL, /* Types are equal */
|
TC_EQUAL, /* Types are equivalent */
|
||||||
TC_IDENTICAL /* Types are identical */
|
TC_IDENTICAL /* Types are identical */
|
||||||
} typecmp_t;
|
} typecmp_t;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user