1 /*****************************************************************************/
5 /* Handle type conversions */
9 /* (C) 2002-2003 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
48 /*****************************************************************************/
50 /*****************************************************************************/
54 static void DoPtrConversions (ExprDesc* Expr)
55 /* If the expression is a function, convert it to pointer to function.
56 * If the expression is an array, convert it to pointer to first element.
59 if (IsTypeFunc (Expr->Type)) {
60 Expr->Type = PointerTo (Expr->Type);
61 } else if (IsTypeArray (Expr->Type)) {
62 Expr->Type = ArrayToPtr (Expr->Type);
68 static int DoConversion (ExprDesc* Expr, int k, type* NewType)
69 /* Emit code to convert the given expression to a new type. */
76 /* Remember the old type */
79 /* If we're converting to void, we're done. Note: This does also cover a
80 * conversion void -> void.
82 if (IsTypeVoid (NewType)) {
83 k = 0; /* Never an lvalue */
87 /* Don't allow casts from void to something else. */
88 if (IsTypeVoid (OldType)) {
89 Error ("Cannot convert from `void' to something else");
93 /* Get the sizes of the types. Since we've excluded void types, checking
94 * for known sizes makes sense here.
96 OldSize = CheckedSizeOf (OldType);
97 NewSize = CheckedSizeOf (NewType);
102 /* We have an lvalue. If the new size is smaller than the new one,
103 * we don't need to do anything. The compiler will generate code
104 * to load only the portion of the value that is actually needed.
105 * This works only on a little endian architecture, but that's
107 * If both sizes are equal, do also leave the value alone.
108 * If the new size is larger, we must convert the value.
110 if (NewSize > OldSize) {
111 /* Load the value into the primary */
112 ExprLoad (CF_NONE, k, Expr);
114 /* Emit typecast code */
115 g_typecast (TypeOf (NewType), TypeOf (OldType));
117 /* Value is now in primary */
118 Expr->Flags = E_MEXPR;
124 /* We have an rvalue. Check for a constant. */
125 if (Expr->Flags == E_MCONST) {
127 /* A cast of a constant to an integer. Be sure to handle sign
128 * extension correctly.
131 /* Get the current and new size of the value */
132 unsigned OldBits = OldSize * 8;
133 unsigned NewBits = NewSize * 8;
135 /* Check if the new datatype will have a smaller range. If it
136 * has a larger range, things are ok, since the value is
137 * internally already represented by a long.
139 if (NewBits <= OldBits) {
141 /* Cut the value to the new size */
142 Expr->ConstVal &= (0xFFFFFFFFUL >> (32 - NewBits));
144 /* If the new type is signed, sign extend the value */
145 if (!IsSignUnsigned (NewType)) {
146 if (Expr->ConstVal & (0x01UL << (NewBits-1))) {
147 Expr->ConstVal |= ((~0L) << NewBits);
154 /* The value is not a constant. If the sizes of the types are
155 * not equal, add conversion code. Be sure to convert chars
158 if (OldSize != NewSize) {
160 /* Load the value into the primary */
161 ExprLoad (CF_NONE, k, Expr);
163 /* Emit typecast code. */
164 g_typecast (TypeOf (NewType) | CF_FORCECHAR, TypeOf (OldType));
166 /* Value is now in primary */
167 Expr->Flags = E_MEXPR;
174 /* The expression has always the new type */
175 ReplaceType (Expr, NewType);
183 int TypeConversion (ExprDesc* Expr, int k, type* NewType)
184 /* Do an automatic conversion of the given expression to the new type. Output
185 * warnings or errors where this automatic conversion is suspicious or
189 /* Get the type of the right hand side. Treat function types as
190 * pointer-to-function
192 DoPtrConversions (Expr);
194 /* First, do some type checking */
195 if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) {
196 /* If one of the sides are of type void, output a more apropriate
199 Error ("Illegal type");
203 /* Handle conversions to int type */
204 if (IsClassInt (NewType)) {
205 if (IsClassPtr (Expr->Type)) {
206 /* Pointer -> int conversion */
207 Warning ("Converting pointer to integer without a cast");
208 } else if (!IsClassInt (Expr->Type)) {
209 Error ("Incompatible types");
212 /* Do a conversion regardless of errors and return the result. */
213 return DoConversion (Expr, k, NewType);
216 /* Handle conversions to pointer type */
217 if (IsClassPtr (NewType)) {
218 if (IsClassPtr (Expr->Type)) {
219 /* Pointer to pointer assignment is valid, if:
220 * - both point to the same types, or
221 * - the rhs pointer is a void pointer, or
222 * - the lhs pointer is a void pointer.
224 if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) {
225 /* Compare the types */
226 switch (TypeCmp (NewType, Expr->Type)) {
228 case TC_INCOMPATIBLE:
229 Error ("Incompatible pointer types");
233 Error ("Pointer types differ in type qualifiers");
241 } else if (IsClassInt (Expr->Type)) {
242 /* Int to pointer assignment is valid only for constant zero */
243 if (Expr->Flags != E_MCONST || Expr->ConstVal != 0) {
244 Warning ("Converting integer to pointer without a cast");
246 } else if (IsTypeFuncPtr (NewType) && IsTypeFunc(Expr->Type)) {
247 /* Assignment of function to function pointer is allowed, provided
248 * that both functions have the same parameter list.
250 if (TypeCmp (Indirect (NewType), Expr->Type) < TC_EQUAL) {
251 Error ("Incompatible types");
254 Error ("Incompatible types");
257 /* Do the conversion even in case of errors */
258 return DoConversion (Expr, k, NewType);
262 /* Invalid automatic conversion */
263 Error ("Incompatible types");
264 return DoConversion (Expr, k, NewType);
269 int TypeCast (ExprDesc* Expr)
270 /* Handle an explicit cast. The function returns true if the resulting
271 * expression is an lvalue and false if not.
275 type NewType[MAXTYPELEN];
277 /* Skip the left paren */
286 /* Read the expression we have to cast */
289 /* Convert functions and arrays to "pointer to" object */
290 DoPtrConversions (Expr);
292 /* Convert the value and return the result. */
293 return DoConversion (Expr, k, NewType);