@@ -5621,7 +5621,7 @@ static void doreturn(void)
5621
5621
if ((rettype & uRETVALUE )!= 0 ) {
5622
5622
int retarray = (ident == iARRAY || ident == iREFARRAY );
5623
5623
/* there was an earlier "return" statement in this function */
5624
- if (sub == NULL && retarray || sub != NULL && !retarray )
5624
+ if (( sub == NULL && retarray && sym != NULL ) || sub != NULL && !retarray )
5625
5625
error (79 ); /* mixing "return array;" and "return value;" */
5626
5626
if (retarray && (curfunc -> usage & uPUBLIC )!= 0 )
5627
5627
error (90 ,curfunc -> name ); /* public function may not return array */
@@ -5634,76 +5634,80 @@ static void doreturn(void)
5634
5634
if (ident == iARRAY || ident == iREFARRAY ) {
5635
5635
int dim [sDIMEN_MAX ],numdim ;
5636
5636
cell arraysize ;
5637
- assert (sym != NULL );
5638
- if (sub != NULL ) {
5639
- assert (sub -> ident == iREFARRAY );
5640
- /* this function has an array attached already; check that the current
5641
- * "return" statement returns exactly the same array
5642
- */
5643
- level = sym -> dim .array .level ;
5644
- if (sub -> dim .array .level != level ) {
5645
- error (48 ); /* array dimensions must match */
5637
+ if (sym == NULL ) {
5638
+ /* array literals cannot be returned directly */
5639
+ error (29 ); /* invalid expression, assumed zero */
5640
+ } else {
5641
+ if (sub != NULL ) {
5642
+ assert (sub -> ident == iREFARRAY );
5643
+ /* this function has an array attached already; check that the current
5644
+ * "return" statement returns exactly the same array
5645
+ */
5646
+ level = sym -> dim .array .level ;
5647
+ if (sub -> dim .array .level != level ) {
5648
+ error (48 ); /* array dimensions must match */
5649
+ } else {
5650
+ for (numdim = 0 ; numdim <=level ; numdim ++ ) {
5651
+ dim [numdim ]= (int )sub -> dim .array .length ;
5652
+ if (sym -> dim .array .length != dim [numdim ])
5653
+ error (47 ); /* array sizes must match */
5654
+ if (numdim < level ) {
5655
+ sym = finddepend (sym );
5656
+ sub = finddepend (sub );
5657
+ assert (sym != NULL && sub != NULL );
5658
+ /* ^^^ both arrays have the same dimensions (this was checked
5659
+ * earlier) so the dependend should always be found
5660
+ */
5661
+ } /* if */
5662
+ } /* for */
5663
+ } /* if */
5646
5664
} else {
5665
+ int idxtag [sDIMEN_MAX ];
5666
+ int argcount ;
5667
+ /* this function does not yet have an array attached; clone the
5668
+ * returned symbol beneath the current function
5669
+ */
5670
+ sub = sym ;
5671
+ assert (sub != NULL );
5672
+ level = sub -> dim .array .level ;
5647
5673
for (numdim = 0 ; numdim <=level ; numdim ++ ) {
5648
5674
dim [numdim ]= (int )sub -> dim .array .length ;
5649
- if (sym -> dim .array .length != dim [numdim ])
5650
- error (47 ); /* array sizes must match */
5675
+ idxtag [numdim ]= sub -> x .tags .index ;
5651
5676
if (numdim < level ) {
5652
- sym = finddepend (sym );
5653
5677
sub = finddepend (sub );
5654
- assert (sym != NULL && sub != NULL );
5655
- /* ^^^ both arrays have the same dimensions (this was checked
5656
- * earlier) so the dependend should always be found
5657
- */
5678
+ assert (sub != NULL );
5658
5679
} /* if */
5680
+ /* check that all dimensions are known */
5681
+ if (dim [numdim ]<=0 )
5682
+ error (46 ,sym -> name );
5659
5683
} /* for */
5684
+ /* the address of the array is stored in a hidden parameter; the address
5685
+ * of this parameter is 1 + the number of parameters (times the size of
5686
+ * a cell) + the size of the stack frame and the return address
5687
+ * base + 0*sizeof(cell) == previous "base"
5688
+ * base + 1*sizeof(cell) == function return address
5689
+ * base + 2*sizeof(cell) == number of arguments
5690
+ * base + 3*sizeof(cell) == first argument of the function
5691
+ * ...
5692
+ * base + ((n-1)+3)*sizeof(cell) == last argument of the function
5693
+ * base + (n+3)*sizeof(cell) == hidden parameter with array address
5694
+ */
5695
+ assert (curfunc != NULL );
5696
+ assert (curfunc -> dim .arglist != NULL );
5697
+ for (argcount = 0 ; curfunc -> dim .arglist [argcount ].ident != 0 ; argcount ++ )
5698
+ /* nothing */ ;
5699
+ sub = addvariable (curfunc -> name ,(argcount + 3 )* sizeof (cell ),iREFARRAY ,sGLOBAL ,curfunc -> tag ,dim ,numdim ,idxtag );
5700
+ sub -> parent = curfunc ;
5660
5701
} /* if */
5661
- } else {
5662
- int idxtag [sDIMEN_MAX ];
5663
- int argcount ;
5664
- /* this function does not yet have an array attached; clone the
5665
- * returned symbol beneath the current function
5702
+ /* get the hidden parameter, copy the array (the array is on the heap;
5703
+ * it stays on the heap for the moment, and it is removed -usually- at
5704
+ * the end of the expression/statement, see expression() in SC3.C)
5666
5705
*/
5667
- sub = sym ;
5668
- assert (sub != NULL );
5669
- level = sub -> dim .array .level ;
5670
- for (numdim = 0 ; numdim <=level ; numdim ++ ) {
5671
- dim [numdim ]= (int )sub -> dim .array .length ;
5672
- idxtag [numdim ]= sub -> x .tags .index ;
5673
- if (numdim < level ) {
5674
- sub = finddepend (sub );
5675
- assert (sub != NULL );
5676
- } /* if */
5677
- /* check that all dimensions are known */
5678
- if (dim [numdim ]<=0 )
5679
- error (46 ,sym -> name );
5680
- } /* for */
5681
- /* the address of the array is stored in a hidden parameter; the address
5682
- * of this parameter is 1 + the number of parameters (times the size of
5683
- * a cell) + the size of the stack frame and the return address
5684
- * base + 0*sizeof(cell) == previous "base"
5685
- * base + 1*sizeof(cell) == function return address
5686
- * base + 2*sizeof(cell) == number of arguments
5687
- * base + 3*sizeof(cell) == first argument of the function
5688
- * ...
5689
- * base + ((n-1)+3)*sizeof(cell) == last argument of the function
5690
- * base + (n+3)*sizeof(cell) == hidden parameter with array address
5691
- */
5692
- assert (curfunc != NULL );
5693
- assert (curfunc -> dim .arglist != NULL );
5694
- for (argcount = 0 ; curfunc -> dim .arglist [argcount ].ident != 0 ; argcount ++ )
5695
- /* nothing */ ;
5696
- sub = addvariable (curfunc -> name ,(argcount + 3 )* sizeof (cell ),iREFARRAY ,sGLOBAL ,curfunc -> tag ,dim ,numdim ,idxtag );
5697
- sub -> parent = curfunc ;
5706
+ address (sub ,sALT ); /* ALT = destination */
5707
+ arraysize = calc_arraysize (dim ,numdim ,0 );
5708
+ memcopy (arraysize * sizeof (cell )); /* source already in PRI */
5709
+ /* moveto1(); is not necessary, callfunction() does a popreg() */
5698
5710
} /* if */
5699
- /* get the hidden parameter, copy the array (the array is on the heap;
5700
- * it stays on the heap for the moment, and it is removed -usually- at
5701
- * the end of the expression/statement, see expression() in SC3.C)
5702
- */
5703
- address (sub ,sALT ); /* ALT = destination */
5704
- arraysize = calc_arraysize (dim ,numdim ,0 );
5705
- memcopy (arraysize * sizeof (cell )); /* source already in PRI */
5706
- /* moveto1(); is not necessary, callfunction() does a popreg() */
5707
5711
} /* if */
5708
5712
} else {
5709
5713
/* this return statement contains no expression */
0 commit comments