X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Ftypeconv.c;h=ecde7349fbaac217d810ac5094d9f50f434dbb99;hb=c6ee5a841878ccdbf9ab85d3dafdd088648b93ba;hp=104e2d9bf6d260d132d59f669a559eff500638a6;hpb=de3a20a8985f10008ec829cc13346a7d0fe232df;p=cc65 diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 104e2d9bf..ecde7349f 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 2002-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 2002-2008 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -102,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); @@ -128,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); @@ -148,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); @@ -168,10 +168,15 @@ void TypeConversion (ExprDesc* Expr, Type* NewType) * impossible. */ { - /* Get the type of the right hand side. Treat function types as - * pointer-to-function - */ - Expr->Type = PtrConversion (Expr->Type); +#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)) { @@ -181,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 */ @@ -192,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"); @@ -207,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 @@ -215,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"); @@ -230,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"); } @@ -260,9 +273,7 @@ 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]; @@ -288,4 +299,4 @@ void TypeCast (ExprDesc* Expr) - +