X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Ftypeconv.c;h=ecde7349fbaac217d810ac5094d9f50f434dbb99;hb=c6ee5a841878ccdbf9ab85d3dafdd088648b93ba;hp=cf3c9a3ef4bbb1b8f7a21bc6bd5c47384f8c56f8;hpb=daf8e0d1e61af355cbf7139ff7af0478251dfbab;p=cc65 diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index cf3c9a3ef..ecde7349f 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 2002-2008 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -55,24 +55,10 @@ -static void DoPtrConversions (ExprDesc* Expr) -/* If the expression is a function, convert it to pointer to function. - * If the expression is an array, convert it to pointer to first element. - */ -{ - if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); - } else if (IsTypeArray (Expr->Type)) { - Expr->Type = ArrayToPtr (Expr->Type); - } -} - - - -static void DoConversion (ExprDesc* Expr, const type* NewType) +static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - type* OldType; + Type* OldType; unsigned OldSize; unsigned NewSize; @@ -116,7 +102,7 @@ static void DoConversion (ExprDesc* Expr, const type* NewType) LoadExpr (CF_NONE, Expr); /* Emit typecast code */ - g_typecast (TypeOf (NewType), TypeOf (OldType)); + g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); /* Value is now in primary and an rvalue */ ED_MakeRValExpr (Expr); @@ -142,7 +128,7 @@ static void DoConversion (ExprDesc* Expr, const type* NewType) Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits)); /* If the new type is signed, sign extend the value */ - if (!IsSignUnsigned (NewType)) { + if (IsSignSigned (NewType)) { if (Expr->IVal & (0x01UL << (NewBits-1))) { /* Beware: Use the safe shift routine here. */ Expr->IVal |= shl_l (~0UL, NewBits); @@ -162,7 +148,7 @@ static void DoConversion (ExprDesc* Expr, const type* NewType) LoadExpr (CF_NONE, Expr); /* Emit typecast code. */ - g_typecast (TypeOf (NewType) | CF_FORCECHAR, TypeOf (OldType)); + g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR); /* Value is now a rvalue in the primary */ ED_MakeRValExpr (Expr); @@ -176,16 +162,21 @@ ExitPoint: -void TypeConversion (ExprDesc* Expr, type* NewType) +void TypeConversion (ExprDesc* Expr, Type* NewType) /* Do an automatic conversion of the given expression to the new type. Output * warnings or errors where this automatic conversion is suspicious or * impossible. */ { - /* Get the type of the right hand side. Treat function types as - * pointer-to-function - */ - DoPtrConversions (Expr); +#if 0 + /* Debugging */ + printf ("Expr:\n=======================================\n"); + PrintExprDesc (stdout, Expr); + printf ("Type:\n=======================================\n"); + PrintType (stdout, NewType); + printf ("\n"); + PrintRawType (stdout, NewType); +#endif /* First, do some type checking */ if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) { @@ -195,6 +186,11 @@ void TypeConversion (ExprDesc* Expr, type* NewType) Error ("Illegal type"); } + /* If Expr is a function, convert it to pointer to function */ + if (IsTypeFunc(Expr->Type)) { + Expr->Type = PointerTo (Expr->Type); + } + /* If both types are equal, no conversion is needed */ if (TypeCmp (Expr->Type, NewType) >= TC_EQUAL) { /* We're already done */ @@ -206,7 +202,10 @@ void TypeConversion (ExprDesc* Expr, type* NewType) /* Handle conversions to int type */ if (IsClassPtr (Expr->Type)) { - /* Pointer -> int conversion */ + /* Pointer -> int conversion. Convert array to pointer */ + if (IsTypeArray (Expr->Type)) { + Expr->Type = ArrayToPtr (Expr->Type); + } Warning ("Converting pointer to integer without a cast"); } else if (!IsClassInt (Expr->Type) && !IsClassFloat (Expr->Type)) { Error ("Incompatible types"); @@ -221,7 +220,13 @@ void TypeConversion (ExprDesc* Expr, type* NewType) } else if (IsClassPtr (NewType)) { /* Handle conversions to pointer type */ - if (IsClassPtr (Expr->Type)) { + if (IsClassPtr (Expr->Type)) { + + /* Convert array to pointer */ + if (IsTypeArray (Expr->Type)) { + Expr->Type = ArrayToPtr (Expr->Type); + } + /* Pointer to pointer assignment is valid, if: * - both point to the same types, or * - the rhs pointer is a void pointer, or @@ -229,7 +234,7 @@ void TypeConversion (ExprDesc* Expr, type* NewType) */ if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) { /* Compare the types */ - switch (TypeCmp (NewType, Expr->Type)) { + switch (TypeCmp (NewType, Expr->Type)) { case TC_INCOMPATIBLE: Error ("Incompatible pointer types"); @@ -244,18 +249,12 @@ void TypeConversion (ExprDesc* Expr, type* NewType) break; } } + } else if (IsClassInt (Expr->Type)) { /* Int to pointer assignment is valid only for constant zero */ if (!ED_IsConstAbsInt (Expr) || Expr->IVal != 0) { Warning ("Converting integer to pointer without a cast"); } - } else if (IsTypeFuncPtr (NewType) && IsTypeFunc(Expr->Type)) { - /* Assignment of function to function pointer is allowed, provided - * that both functions have the same parameter list. - */ - if (TypeCmp (Indirect (NewType), Expr->Type) < TC_EQUAL) { - Error ("Incompatible types"); - } } else { Error ("Incompatible types"); } @@ -274,11 +273,9 @@ void TypeConversion (ExprDesc* Expr, type* NewType) void TypeCast (ExprDesc* Expr) -/* Handle an explicit cast. The function returns true if the resulting - * expression is an lvalue and false if not. - */ +/* Handle an explicit cast. */ { - type NewType[MAXTYPELEN]; + Type NewType[MAXTYPELEN]; /* Skip the left paren */ NextToken (); @@ -293,7 +290,7 @@ void TypeCast (ExprDesc* Expr) hie10 (Expr); /* Convert functions and arrays to "pointer to" object */ - DoPtrConversions (Expr); + Expr->Type = PtrConversion (Expr->Type); /* Convert the value. */ DoConversion (Expr, NewType); @@ -302,3 +299,4 @@ void TypeCast (ExprDesc* Expr) +