@@ -1876,6 +1876,7 @@ transform_call(int std, int ast)
18761876 break ;
18771877 }
18781878 }
1879+
18791880 if (is_ent &&
18801881 (
18811882#if DEBUG
@@ -1975,6 +1976,46 @@ transform_call(int std, int ast)
19751976 DESCUSEDP (sptr , 1 );
19761977 NODESCP (sptr , 0 );
19771978
1979+ /* Fix for assumed-shape arrays arguments where callee has the
1980+ * argument marked as target (originally discovered at customer).
1981+ * In this case the whole array is sent, but the callee code
1982+ * still needs to use the address calculation method such that
1983+ * the lower bound is folded into the lbase field of the descriptor
1984+ * to make zero-based offsets work (so-called; in practice
1985+ * usually 1-based with Fortran).
1986+ * [see exp_ftn.c: compute_sdsc_subscr() & add_ptr_subscript()]
1987+ *
1988+ * Since a new section descriptor has not been generated in this
1989+ * case where we send the whole array as an argument we need to
1990+ * create a new, temporary, argument array descriptor which
1991+ * translates bounds to zero-based (per the Fortran standard with
1992+ * assumed-shape arguments) and adjusts the lbase field.
1993+ *
1994+ * NB: The new runtime routine, pgf90_tmp_desc(), used to create the
1995+ * argument desriptor is similar to a pointer assignment (which
1996+ * makes the ptr_assn() call), and which follows the same rules
1997+ * of zero-based array bounds and lbase calculation. Also, this type
1998+ * of lbase fixup can also be found in runtime routines like
1999+ * ptr_fix_assumeshp(), where a whole array, instead of a section,
2000+ * is identified.
2001+ */
2002+ if (XBIT (58 ,0x400000 )&& ASSUMSHPG (inface_arg )&& TARGETG (inface_arg ))
2003+ {
2004+ char nd [50 ]; /* new, substitute, descriptor for this arg */
2005+ static int ndctr = 0 ;
2006+ DTYPE dtype = DTYPEG (sptr );
2007+ SPTR sptrtmp , sptrdesc ;
2008+ sprintf (nd , "ndesc%d_%d" , A_SPTRG (ele ), ndctr ++ );
2009+ sptrtmp = sym_get_array (nd , "" , DDTG (dtype ),
2010+ SHD_NDIM (A_SHAPEG (ele )));
2011+ get_static_descriptor (sptrtmp ); /* add sdsc to sptrtmp; necessary */
2012+ get_all_descriptors (sptrtmp ); /* add desc & bounds in dtype */
2013+ /* generate the runtime call pgf90_tmp_desc) */
2014+ make_temp_descriptor (sptr , sptrtmp , std );
2015+ sptrdesc = DESCRG (sptrtmp );
2016+ ARGT_ARG (newargt , newj ) = check_member (ele , mk_id (sptrdesc ));
2017+ }
2018+ else
19782019 ARGT_ARG (newargt , newj ) = descr ;
19792020 ++ newj ;
19802021 s = memsym_of_ast (descr );
@@ -2027,6 +2068,35 @@ transform_call(int std, int ast)
20272068 ++ newi ;
20282069 if (needdescr ) {
20292070 int s ;
2071+ /* situation where we are sending the whole array using
2072+ * subscript notation, e.g. x(:,:), but semantically
2073+ * equivalent to the above A_ID case of 'x'. We know that
2074+ * the whole array is being passed when the descriptor
2075+ * generated from the call to transform_section_arg()
2076+ * above (descr) is unchanged from the sptr descriptor.
2077+ */
2078+ if (XBIT (58 ,0x400000 ) && ASSUMSHPG (inface_arg ) &&
2079+ TARGETG (inface_arg ) && A_SPTRG (descr ) &&
2080+ (DESCRG (sptr ) == A_SPTRG (descr )) )
2081+ {
2082+ char nsd [50 ]; /* new, substitute, descriptor for this arg */
2083+ static int nsdctr = 0 ;
2084+ DTYPE dtype = DTYPEG (sptr );
2085+ SPTR sptrtmp , sptrdesc ;
2086+ /* In this case ele is an A_SUBSCR, so need to use its A_LOP */
2087+ int lop_ele = A_LOPG (ele );
2088+
2089+ sprintf (nsd , "n2desc%d_%d" , A_SPTRG (lop_ele ), nsdctr ++ );
2090+ sptrtmp = sym_get_array (nsd , "" , DDTG (dtype ),
2091+ SHD_NDIM (A_SHAPEG (lop_ele )));
2092+ get_static_descriptor (sptrtmp ); /* add sdsc to sptrtmp; necessary */
2093+ get_all_descriptors (sptrtmp ); /* add desc & bounds in dtype */
2094+ /* generate the runtime call pgf90_tmp_desc) */
2095+ make_temp_descriptor (sptr , sptrtmp , std );
2096+ sptrdesc = DESCRG (sptrtmp );
2097+ ARGT_ARG (newargt , newj ) = check_member (lop_ele , mk_id (sptrdesc ));
2098+ }
2099+ else
20302100 ARGT_ARG (newargt , newj ) = descr ;
20312101 ++ newj ;
20322102 s = memsym_of_ast (descr );
@@ -2400,10 +2470,12 @@ handle_seq_section(int entry, int arr, int loc, int std, int *retval,
24002470 if (!arrayalign )
24012471 is_seq_pointer = TRUE;
24022472 }
2473+ if (TARGETG (arraysptr ) && XBIT (58 ,0x400000 ))
2474+ is_seq_pointer = TRUE;
24032475 /* for F90, an assumed-shape dummy array looks like
24042476 * a sequential pointer, if copy-ins are removed */
24052477 if (XBIT (57 , 0x10000 ) && ASSUMSHPG (arraysptr ) && SDSCS1G (arraysptr ) &&
2406- !XBIT (54 , 2 ) && !( XBIT ( 58 , 0x400000 ) && TARGETG ( arraysptr )) )
2478+ !XBIT (54 , 2 ))
24072479 is_seq_pointer = TRUE;
24082480 break ;
24092481 case A_SUBSCR :
@@ -3680,7 +3752,7 @@ stride_1_section(int entry, int arr_ast, int pos, int std)
36803752 return FALSE; /* leftmost triplet is not stride 1 */
36813753 }
36823754 sptr = memsym_of_ast (arr_ast );
3683- if (POINTERG (sptr )) {
3755+ if (POINTERG (sptr ) || ( TARGETG ( sptr ) && XBIT ( 58 , 0x400000 )) ) {
36843756 /*
36853757 * Is this a stride-1 pointer array section? If the corresponding
36863758 * dummy is assumed-shape, we cannot omit the copy arg calls. The
0 commit comments