OSDN Git Service

* g++.dg/parse/parse2.C: New test.
[pf3gnuchains/gcc-fork.git] / gcc / convert.c
1 /* Utility routines for data type conversion for GNU C.
2    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997,
3    1998 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22
23 /* These routines are somewhat language-independent utility function
24    intended to be called by the language-specific convert () functions.  */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "tree.h"
31 #include "flags.h"
32 #include "convert.h"
33 #include "toplev.h"
34 #include "langhooks.h"
35 static tree strip_float_extensions PARAMS ((tree));
36
37 /* Convert EXPR to some pointer or reference type TYPE.
38
39    EXPR must be pointer, reference, integer, enumeral, or literal zero;
40    in other cases error is called.  */
41
42 tree
43 convert_to_pointer (type, expr)
44      tree type, expr;
45 {
46   if (integer_zerop (expr))
47     {
48       expr = build_int_2 (0, 0);
49       TREE_TYPE (expr) = type;
50       return expr;
51     }
52
53   switch (TREE_CODE (TREE_TYPE (expr)))
54     {
55     case POINTER_TYPE:
56     case REFERENCE_TYPE:
57       return build1 (NOP_EXPR, type, expr);
58
59     case INTEGER_TYPE:
60     case ENUMERAL_TYPE:
61     case BOOLEAN_TYPE:
62     case CHAR_TYPE:
63       if (TYPE_PRECISION (TREE_TYPE (expr)) == POINTER_SIZE)
64         return build1 (CONVERT_EXPR, type, expr);
65
66       return
67         convert_to_pointer (type,
68                             convert ((*lang_hooks.types.type_for_size)
69                                      (POINTER_SIZE, 0), expr));
70
71     default:
72       error ("cannot convert to a pointer type");
73       return convert_to_pointer (type, integer_zero_node);
74     }
75 }
76
77 /* Avoid any floating point extensions from EXP.  */
78 static tree
79 strip_float_extensions (exp)
80      tree exp;
81 {
82   tree sub, expt, subt;
83
84   if (TREE_CODE (exp) != NOP_EXPR)
85     return exp;
86
87   sub = TREE_OPERAND (exp, 0);
88   subt = TREE_TYPE (sub);
89   expt = TREE_TYPE (exp);
90
91   if (!FLOAT_TYPE_P (subt))
92     return exp;
93
94   if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
95     return exp;
96
97   return strip_float_extensions (sub);
98 }
99
100
101 /* Convert EXPR to some floating-point type TYPE.
102
103    EXPR must be float, integer, or enumeral;
104    in other cases error is called.  */
105
106 tree
107 convert_to_real (type, expr)
108      tree type, expr;
109 {
110   enum built_in_function fcode = builtin_mathfn_code (expr);
111   tree itype = TREE_TYPE (expr);
112
113   /* Disable until we figure out how to decide whether the functions are
114      present in runtime.  */
115 #if 0
116   /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
117   if ((fcode == BUILT_IN_SQRT
118        || fcode == BUILT_IN_SQRTL
119        || fcode == BUILT_IN_SIN
120        || fcode == BUILT_IN_SINL
121        || fcode == BUILT_IN_COS
122        || fcode == BUILT_IN_COSL
123        || fcode == BUILT_IN_EXP
124        || fcode == BUILT_IN_EXPL)
125       && optimize
126       && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
127           || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
128     {
129       tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
130       tree newtype = type;
131
132       /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
133          the both as the safe type for operation.  */
134       if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
135         newtype = TREE_TYPE (arg0);
136
137       /* Be curefull about integer to fp conversions.
138          These may overflow still.  */
139       if (FLOAT_TYPE_P (TREE_TYPE (arg0))
140           && TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
141           && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
142               || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
143         {
144           tree arglist;
145           if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
146             switch (fcode)
147               {
148               case BUILT_IN_SQRT:
149               case BUILT_IN_SQRTL:
150                 fcode = BUILT_IN_SQRTF;
151                 break;
152               case BUILT_IN_SIN:
153               case BUILT_IN_SINL:
154                 fcode = BUILT_IN_SINF;
155                 break;
156               case BUILT_IN_COS:
157               case BUILT_IN_COSL:
158                 fcode = BUILT_IN_COSF;
159                 break;
160               case BUILT_IN_EXP:
161               case BUILT_IN_EXPL:
162                 fcode = BUILT_IN_EXPF;
163                 break;
164               default:
165                 abort ();
166               }
167           else
168             switch (fcode)
169               {
170               case BUILT_IN_SQRT:
171               case BUILT_IN_SQRTL:
172                 fcode = BUILT_IN_SQRT;
173                 break;
174               case BUILT_IN_SIN:
175               case BUILT_IN_SINL:
176                 fcode = BUILT_IN_SIN;
177                 break;
178               case BUILT_IN_COS:
179               case BUILT_IN_COSL:
180                 fcode = BUILT_IN_COS;
181                 break;
182               case BUILT_IN_EXP:
183               case BUILT_IN_EXPL:
184                 fcode = BUILT_IN_EXP;
185                 break;
186               default:
187                 abort ();
188               }
189
190           /* ??? Fortran frontend does not initialize built_in_decls.
191              For some reason creating the decl using builtin_function does not
192              work as it should.   */
193           if (built_in_decls [fcode])
194             {
195               arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
196               expr = build_function_call_expr (built_in_decls [fcode], arglist);
197               if (newtype == type)
198                 return expr;
199             }
200         }
201     }
202 #endif
203
204   /* Propagate the cast into the operation.  */
205   if (itype != type && FLOAT_TYPE_P (type))
206     switch (TREE_CODE (expr))
207       {
208         /* convert (float)-x into -(float)x.  This is always safe.  */
209         case ABS_EXPR:
210         case NEGATE_EXPR:
211           return build1 (TREE_CODE (expr), type,
212                          fold (convert_to_real (type,
213                                                 TREE_OPERAND (expr, 0))));
214         /* convert (outertype)((innertype0)a+(innertype1)b)
215            into ((newtype)a+(newtype)b) where newtype
216            is the widest mode from all of these.  */
217         case PLUS_EXPR:
218         case MINUS_EXPR:
219         case MULT_EXPR:
220         case RDIV_EXPR:
221            {
222              tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
223              tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
224
225              if (FLOAT_TYPE_P (TREE_TYPE (arg0))
226                  && FLOAT_TYPE_P (TREE_TYPE (arg1)))
227                {
228                   tree newtype = type;
229                   if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
230                     newtype = TREE_TYPE (arg0);
231                   if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
232                     newtype = TREE_TYPE (arg1);
233                   if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
234                     {
235                       expr = build (TREE_CODE (expr), newtype,
236                                     fold (convert_to_real (newtype, arg0)),
237                                     fold (convert_to_real (newtype, arg1)));
238                       if (newtype == type)
239                         return expr;
240                     }
241                }
242            }
243           break;
244         default:
245           break;
246       }
247
248   switch (TREE_CODE (TREE_TYPE (expr)))
249     {
250     case REAL_TYPE:
251       return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
252                      type, expr);
253
254     case INTEGER_TYPE:
255     case ENUMERAL_TYPE:
256     case BOOLEAN_TYPE:
257     case CHAR_TYPE:
258       return build1 (FLOAT_EXPR, type, expr);
259
260     case COMPLEX_TYPE:
261       return convert (type,
262                       fold (build1 (REALPART_EXPR,
263                                     TREE_TYPE (TREE_TYPE (expr)), expr)));
264
265     case POINTER_TYPE:
266     case REFERENCE_TYPE:
267       error ("pointer value used where a floating point value was expected");
268       return convert_to_real (type, integer_zero_node);
269
270     default:
271       error ("aggregate value used where a float was expected");
272       return convert_to_real (type, integer_zero_node);
273     }
274 }
275
276 /* Convert EXPR to some integer (or enum) type TYPE.
277
278    EXPR must be pointer, integer, discrete (enum, char, or bool), float, or
279    vector; in other cases error is called.
280
281    The result of this is always supposed to be a newly created tree node
282    not in use in any existing structure.  */
283
284 tree
285 convert_to_integer (type, expr)
286      tree type, expr;
287 {
288   enum tree_code ex_form = TREE_CODE (expr);
289   tree intype = TREE_TYPE (expr);
290   unsigned int inprec = TYPE_PRECISION (intype);
291   unsigned int outprec = TYPE_PRECISION (type);
292
293   /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
294      be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
295   if (!COMPLETE_TYPE_P (type))
296     {
297       error ("conversion to incomplete type");
298       return error_mark_node;
299     }
300
301   switch (TREE_CODE (intype))
302     {
303     case POINTER_TYPE:
304     case REFERENCE_TYPE:
305       if (integer_zerop (expr))
306         expr = integer_zero_node;
307       else
308         expr = fold (build1 (CONVERT_EXPR, (*lang_hooks.types.type_for_size)
309                              (POINTER_SIZE, 0), expr));
310
311       return convert_to_integer (type, expr);
312
313     case INTEGER_TYPE:
314     case ENUMERAL_TYPE:
315     case BOOLEAN_TYPE:
316     case CHAR_TYPE:
317       /* If this is a logical operation, which just returns 0 or 1, we can
318          change the type of the expression.  For some logical operations,
319          we must also change the types of the operands to maintain type
320          correctness.  */
321
322       if (TREE_CODE_CLASS (ex_form) == '<')
323         {
324           TREE_TYPE (expr) = type;
325           return expr;
326         }
327
328       else if (ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
329                || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
330                || ex_form == TRUTH_XOR_EXPR)
331         {
332           TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
333           TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1));
334           TREE_TYPE (expr) = type;
335           return expr;
336         }
337
338       else if (ex_form == TRUTH_NOT_EXPR)
339         {
340           TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
341           TREE_TYPE (expr) = type;
342           return expr;
343         }
344
345       /* If we are widening the type, put in an explicit conversion.
346          Similarly if we are not changing the width.  After this, we know
347          we are truncating EXPR.  */
348
349       else if (outprec >= inprec)
350         return build1 (NOP_EXPR, type, expr);
351
352       /* If TYPE is an enumeral type or a type with a precision less
353          than the number of bits in its mode, do the conversion to the
354          type corresponding to its mode, then do a nop conversion
355          to TYPE.  */
356       else if (TREE_CODE (type) == ENUMERAL_TYPE
357                || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
358         return build1 (NOP_EXPR, type,
359                        convert ((*lang_hooks.types.type_for_mode)
360                                 (TYPE_MODE (type), TREE_UNSIGNED (type)),
361                                 expr));
362
363       /* Here detect when we can distribute the truncation down past some
364          arithmetic.  For example, if adding two longs and converting to an
365          int, we can equally well convert both to ints and then add.
366          For the operations handled here, such truncation distribution
367          is always safe.
368          It is desirable in these cases:
369          1) when truncating down to full-word from a larger size
370          2) when truncating takes no work.
371          3) when at least one operand of the arithmetic has been extended
372          (as by C's default conversions).  In this case we need two conversions
373          if we do the arithmetic as already requested, so we might as well
374          truncate both and then combine.  Perhaps that way we need only one.
375
376          Note that in general we cannot do the arithmetic in a type
377          shorter than the desired result of conversion, even if the operands
378          are both extended from a shorter type, because they might overflow
379          if combined in that type.  The exceptions to this--the times when
380          two narrow values can be combined in their narrow type even to
381          make a wider result--are handled by "shorten" in build_binary_op.  */
382
383       switch (ex_form)
384         {
385         case RSHIFT_EXPR:
386           /* We can pass truncation down through right shifting
387              when the shift count is a nonpositive constant.  */
388           if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
389               && tree_int_cst_lt (TREE_OPERAND (expr, 1),
390                                   convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
391                                            integer_one_node)))
392             goto trunc1;
393           break;
394
395         case LSHIFT_EXPR:
396           /* We can pass truncation down through left shifting
397              when the shift count is a nonnegative constant and
398              the target type is unsigned.  */
399           if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
400               && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
401               && TREE_UNSIGNED (type)
402               && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
403             {
404               /* If shift count is less than the width of the truncated type,
405                  really shift.  */
406               if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
407                 /* In this case, shifting is like multiplication.  */
408                 goto trunc1;
409               else
410                 {
411                   /* If it is >= that width, result is zero.
412                      Handling this with trunc1 would give the wrong result:
413                      (int) ((long long) a << 32) is well defined (as 0)
414                      but (int) a << 32 is undefined and would get a
415                      warning.  */
416
417                   tree t = convert_to_integer (type, integer_zero_node);
418
419                   /* If the original expression had side-effects, we must
420                      preserve it.  */
421                   if (TREE_SIDE_EFFECTS (expr))
422                     return build (COMPOUND_EXPR, type, expr, t);
423                   else
424                     return t;
425                 }
426             }
427           break;
428
429         case MAX_EXPR:
430         case MIN_EXPR:
431         case MULT_EXPR:
432           {
433             tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
434             tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
435
436             /* Don't distribute unless the output precision is at least as big
437                as the actual inputs.  Otherwise, the comparison of the
438                truncated values will be wrong.  */
439             if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
440                 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
441                 /* If signedness of arg0 and arg1 don't match,
442                    we can't necessarily find a type to compare them in.  */
443                 && (TREE_UNSIGNED (TREE_TYPE (arg0))
444                     == TREE_UNSIGNED (TREE_TYPE (arg1))))
445               goto trunc1;
446             break;
447           }
448
449         case PLUS_EXPR:
450         case MINUS_EXPR:
451         case BIT_AND_EXPR:
452         case BIT_IOR_EXPR:
453         case BIT_XOR_EXPR:
454         case BIT_ANDTC_EXPR:
455         trunc1:
456           {
457             tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
458             tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
459
460             if (outprec >= BITS_PER_WORD
461                 || TRULY_NOOP_TRUNCATION (outprec, inprec)
462                 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
463                 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
464               {
465                 /* Do the arithmetic in type TYPEX,
466                    then convert result to TYPE.  */
467                 tree typex = type;
468
469                 /* Can't do arithmetic in enumeral types
470                    so use an integer type that will hold the values.  */
471                 if (TREE_CODE (typex) == ENUMERAL_TYPE)
472                   typex = (*lang_hooks.types.type_for_size)
473                     (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
474
475                 /* But now perhaps TYPEX is as wide as INPREC.
476                    In that case, do nothing special here.
477                    (Otherwise would recurse infinitely in convert.  */
478                 if (TYPE_PRECISION (typex) != inprec)
479                   {
480                     /* Don't do unsigned arithmetic where signed was wanted,
481                        or vice versa.
482                        Exception: if both of the original operands were
483                        unsigned then we can safely do the work as unsigned.
484                        Exception: shift operations take their type solely
485                        from the first argument.
486                        Exception: the LSHIFT_EXPR case above requires that
487                        we perform this operation unsigned lest we produce
488                        signed-overflow undefinedness.
489                        And we may need to do it as unsigned
490                        if we truncate to the original size.  */
491                     if (TREE_UNSIGNED (TREE_TYPE (expr))
492                         || (TREE_UNSIGNED (TREE_TYPE (arg0))
493                             && (TREE_UNSIGNED (TREE_TYPE (arg1))
494                                 || ex_form == LSHIFT_EXPR
495                                 || ex_form == RSHIFT_EXPR
496                                 || ex_form == LROTATE_EXPR
497                                 || ex_form == RROTATE_EXPR))
498                         || ex_form == LSHIFT_EXPR)
499                       typex = (*lang_hooks.types.unsigned_type) (typex);
500                     else
501                       typex = (*lang_hooks.types.signed_type) (typex);
502                     return convert (type,
503                                     fold (build (ex_form, typex,
504                                                  convert (typex, arg0),
505                                                  convert (typex, arg1),
506                                                  0)));
507                   }
508               }
509           }
510           break;
511
512         case NEGATE_EXPR:
513         case BIT_NOT_EXPR:
514           /* This is not correct for ABS_EXPR,
515              since we must test the sign before truncation.  */
516           {
517             tree typex = type;
518
519             /* Can't do arithmetic in enumeral types
520                so use an integer type that will hold the values.  */
521             if (TREE_CODE (typex) == ENUMERAL_TYPE)
522               typex = (*lang_hooks.types.type_for_size)
523                 (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
524
525             /* But now perhaps TYPEX is as wide as INPREC.
526                In that case, do nothing special here.
527                (Otherwise would recurse infinitely in convert.  */
528             if (TYPE_PRECISION (typex) != inprec)
529               {
530                 /* Don't do unsigned arithmetic where signed was wanted,
531                    or vice versa.  */
532                 if (TREE_UNSIGNED (TREE_TYPE (expr)))
533                   typex = (*lang_hooks.types.unsigned_type) (typex);
534                 else
535                   typex = (*lang_hooks.types.signed_type) (typex);
536                 return convert (type,
537                                 fold (build1 (ex_form, typex,
538                                               convert (typex,
539                                                        TREE_OPERAND (expr, 0)))));
540               }
541           }
542
543         case NOP_EXPR:
544           /* Don't introduce a
545              "can't convert between vector values of different size" error.  */
546           if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
547               && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
548                   != GET_MODE_SIZE (TYPE_MODE (type))))
549             break;
550           /* If truncating after truncating, might as well do all at once.
551              If truncating after extending, we may get rid of wasted work.  */
552           return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
553
554         case COND_EXPR:
555           /* It is sometimes worthwhile to push the narrowing down through
556              the conditional and never loses.  */
557           return fold (build (COND_EXPR, type, TREE_OPERAND (expr, 0),
558                               convert (type, TREE_OPERAND (expr, 1)), 
559                               convert (type, TREE_OPERAND (expr, 2))));
560
561         default:
562           break;
563         }
564
565       return build1 (NOP_EXPR, type, expr);
566
567     case REAL_TYPE:
568       return build1 (FIX_TRUNC_EXPR, type, expr);
569
570     case COMPLEX_TYPE:
571       return convert (type,
572                       fold (build1 (REALPART_EXPR,
573                                     TREE_TYPE (TREE_TYPE (expr)), expr)));
574
575     case VECTOR_TYPE:
576       if (GET_MODE_SIZE (TYPE_MODE (type))
577           != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
578         {
579           error ("can't convert between vector values of different size");
580           return error_mark_node;
581         }
582       return build1 (NOP_EXPR, type, expr);
583
584     default:
585       error ("aggregate value used where an integer was expected");
586       return convert (type, integer_zero_node);
587     }
588 }
589
590 /* Convert EXPR to the complex type TYPE in the usual ways.  */
591
592 tree
593 convert_to_complex (type, expr)
594      tree type, expr;
595 {
596   tree subtype = TREE_TYPE (type);
597   
598   switch (TREE_CODE (TREE_TYPE (expr)))
599     {
600     case REAL_TYPE:
601     case INTEGER_TYPE:
602     case ENUMERAL_TYPE:
603     case BOOLEAN_TYPE:
604     case CHAR_TYPE:
605       return build (COMPLEX_EXPR, type, convert (subtype, expr),
606                     convert (subtype, integer_zero_node));
607
608     case COMPLEX_TYPE:
609       {
610         tree elt_type = TREE_TYPE (TREE_TYPE (expr));
611
612         if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
613           return expr;
614         else if (TREE_CODE (expr) == COMPLEX_EXPR)
615           return fold (build (COMPLEX_EXPR,
616                               type,
617                               convert (subtype, TREE_OPERAND (expr, 0)),
618                               convert (subtype, TREE_OPERAND (expr, 1))));
619         else
620           {
621             expr = save_expr (expr);
622             return
623               fold (build (COMPLEX_EXPR,
624                            type, convert (subtype,
625                                           fold (build1 (REALPART_EXPR,
626                                                         TREE_TYPE (TREE_TYPE (expr)),
627                                                         expr))),
628                            convert (subtype,
629                                     fold (build1 (IMAGPART_EXPR,
630                                                   TREE_TYPE (TREE_TYPE (expr)),
631                                                   expr)))));
632           }
633       }
634
635     case POINTER_TYPE:
636     case REFERENCE_TYPE:
637       error ("pointer value used where a complex was expected");
638       return convert_to_complex (type, integer_zero_node);
639
640     default:
641       error ("aggregate value used where a complex was expected");
642       return convert_to_complex (type, integer_zero_node);
643     }
644 }
645
646 /* Convert EXPR to the vector type TYPE in the usual ways.  */
647
648 tree
649 convert_to_vector (type, expr)
650      tree type, expr;
651 {
652   switch (TREE_CODE (TREE_TYPE (expr)))
653     {
654     case INTEGER_TYPE:
655     case VECTOR_TYPE:
656       if (GET_MODE_SIZE (TYPE_MODE (type))
657           != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
658         {
659           error ("can't convert between vector values of different size");
660           return error_mark_node;
661         }
662       return build1 (NOP_EXPR, type, expr);
663
664     default:
665       error ("can't convert value to a vector");
666       return convert_to_vector (type, integer_zero_node);
667     }
668 }