trans-expr.c 273 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190
  1. /* Expression translation
  2. Copyright (C) 2002-2015 Free Software Foundation, Inc.
  3. Contributed by Paul Brook <paul@nowt.org>
  4. and Steven Bosscher <s.bosscher@student.tudelft.nl>
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU General Public License as published by the Free
  8. Software Foundation; either version 3, or (at your option) any later
  9. version.
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GCC; see the file COPYING3. If not see
  16. <http://www.gnu.org/licenses/>. */
  17. /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
  18. #include "config.h"
  19. #include "system.h"
  20. #include "coretypes.h"
  21. #include "gfortran.h"
  22. #include "hash-set.h"
  23. #include "machmode.h"
  24. #include "vec.h"
  25. #include "double-int.h"
  26. #include "input.h"
  27. #include "alias.h"
  28. #include "symtab.h"
  29. #include "options.h"
  30. #include "wide-int.h"
  31. #include "inchash.h"
  32. #include "tree.h"
  33. #include "fold-const.h"
  34. #include "stringpool.h"
  35. #include "diagnostic-core.h" /* For fatal_error. */
  36. #include "langhooks.h"
  37. #include "flags.h"
  38. #include "arith.h"
  39. #include "constructor.h"
  40. #include "trans.h"
  41. #include "trans-const.h"
  42. #include "trans-types.h"
  43. #include "trans-array.h"
  44. /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
  45. #include "trans-stmt.h"
  46. #include "dependency.h"
  47. #include "gimplify.h"
  48. /* Convert a scalar to an array descriptor. To be used for assumed-rank
  49. arrays. */
  50. static tree
  51. get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
  52. {
  53. enum gfc_array_kind akind;
  54. if (attr.pointer)
  55. akind = GFC_ARRAY_POINTER_CONT;
  56. else if (attr.allocatable)
  57. akind = GFC_ARRAY_ALLOCATABLE;
  58. else
  59. akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
  60. if (POINTER_TYPE_P (TREE_TYPE (scalar)))
  61. scalar = TREE_TYPE (scalar);
  62. return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
  63. akind, !(attr.pointer || attr.target));
  64. }
  65. tree
  66. gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
  67. {
  68. tree desc, type;
  69. type = get_scalar_to_descriptor_type (scalar, attr);
  70. desc = gfc_create_var (type, "desc");
  71. DECL_ARTIFICIAL (desc) = 1;
  72. if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
  73. scalar = gfc_build_addr_expr (NULL_TREE, scalar);
  74. gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
  75. gfc_get_dtype (type));
  76. gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
  77. /* Copy pointer address back - but only if it could have changed and
  78. if the actual argument is a pointer and not, e.g., NULL(). */
  79. if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
  80. gfc_add_modify (&se->post, scalar,
  81. fold_convert (TREE_TYPE (scalar),
  82. gfc_conv_descriptor_data_get (desc)));
  83. return desc;
  84. }
  85. /* This is the seed for an eventual trans-class.c
  86. The following parameters should not be used directly since they might
  87. in future implementations. Use the corresponding APIs. */
  88. #define CLASS_DATA_FIELD 0
  89. #define CLASS_VPTR_FIELD 1
  90. #define CLASS_LEN_FIELD 2
  91. #define VTABLE_HASH_FIELD 0
  92. #define VTABLE_SIZE_FIELD 1
  93. #define VTABLE_EXTENDS_FIELD 2
  94. #define VTABLE_DEF_INIT_FIELD 3
  95. #define VTABLE_COPY_FIELD 4
  96. #define VTABLE_FINAL_FIELD 5
  97. tree
  98. gfc_class_set_static_fields (tree decl, tree vptr, tree data)
  99. {
  100. tree tmp;
  101. tree field;
  102. vec<constructor_elt, va_gc> *init = NULL;
  103. field = TYPE_FIELDS (TREE_TYPE (decl));
  104. tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
  105. CONSTRUCTOR_APPEND_ELT (init, tmp, data);
  106. tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
  107. CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
  108. return build_constructor (TREE_TYPE (decl), init);
  109. }
  110. tree
  111. gfc_class_data_get (tree decl)
  112. {
  113. tree data;
  114. if (POINTER_TYPE_P (TREE_TYPE (decl)))
  115. decl = build_fold_indirect_ref_loc (input_location, decl);
  116. data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
  117. CLASS_DATA_FIELD);
  118. return fold_build3_loc (input_location, COMPONENT_REF,
  119. TREE_TYPE (data), decl, data,
  120. NULL_TREE);
  121. }
  122. tree
  123. gfc_class_vptr_get (tree decl)
  124. {
  125. tree vptr;
  126. if (POINTER_TYPE_P (TREE_TYPE (decl)))
  127. decl = build_fold_indirect_ref_loc (input_location, decl);
  128. vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
  129. CLASS_VPTR_FIELD);
  130. return fold_build3_loc (input_location, COMPONENT_REF,
  131. TREE_TYPE (vptr), decl, vptr,
  132. NULL_TREE);
  133. }
  134. tree
  135. gfc_class_len_get (tree decl)
  136. {
  137. tree len;
  138. if (POINTER_TYPE_P (TREE_TYPE (decl)))
  139. decl = build_fold_indirect_ref_loc (input_location, decl);
  140. len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
  141. CLASS_LEN_FIELD);
  142. return fold_build3_loc (input_location, COMPONENT_REF,
  143. TREE_TYPE (len), decl, len,
  144. NULL_TREE);
  145. }
  146. /* Get the specified FIELD from the VPTR. */
  147. static tree
  148. vptr_field_get (tree vptr, int fieldno)
  149. {
  150. tree field;
  151. vptr = build_fold_indirect_ref_loc (input_location, vptr);
  152. field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
  153. fieldno);
  154. field = fold_build3_loc (input_location, COMPONENT_REF,
  155. TREE_TYPE (field), vptr, field,
  156. NULL_TREE);
  157. gcc_assert (field);
  158. return field;
  159. }
  160. /* Get the field from the class' vptr. */
  161. static tree
  162. class_vtab_field_get (tree decl, int fieldno)
  163. {
  164. tree vptr;
  165. vptr = gfc_class_vptr_get (decl);
  166. return vptr_field_get (vptr, fieldno);
  167. }
  168. /* Define a macro for creating the class_vtab_* and vptr_* accessors in
  169. unison. */
  170. #define VTAB_GET_FIELD_GEN(name, field) tree \
  171. gfc_class_vtab_## name ##_get (tree cl) \
  172. { \
  173. return class_vtab_field_get (cl, field); \
  174. } \
  175. \
  176. tree \
  177. gfc_vptr_## name ##_get (tree vptr) \
  178. { \
  179. return vptr_field_get (vptr, field); \
  180. }
  181. VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
  182. VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
  183. VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
  184. VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
  185. VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
  186. /* The size field is returned as an array index type. Therefore treat
  187. it and only it specially. */
  188. tree
  189. gfc_class_vtab_size_get (tree cl)
  190. {
  191. tree size;
  192. size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
  193. /* Always return size as an array index type. */
  194. size = fold_convert (gfc_array_index_type, size);
  195. gcc_assert (size);
  196. return size;
  197. }
  198. tree
  199. gfc_vptr_size_get (tree vptr)
  200. {
  201. tree size;
  202. size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
  203. /* Always return size as an array index type. */
  204. size = fold_convert (gfc_array_index_type, size);
  205. gcc_assert (size);
  206. return size;
  207. }
  208. #undef CLASS_DATA_FIELD
  209. #undef CLASS_VPTR_FIELD
  210. #undef VTABLE_HASH_FIELD
  211. #undef VTABLE_SIZE_FIELD
  212. #undef VTABLE_EXTENDS_FIELD
  213. #undef VTABLE_DEF_INIT_FIELD
  214. #undef VTABLE_COPY_FIELD
  215. #undef VTABLE_FINAL_FIELD
  216. /* Search for the last _class ref in the chain of references of this
  217. expression and cut the chain there. Albeit this routine is similiar
  218. to class.c::gfc_add_component_ref (), is there a significant
  219. difference: gfc_add_component_ref () concentrates on an array ref to
  220. be the last ref in the chain. This routine is oblivious to the kind
  221. of refs following. */
  222. gfc_expr *
  223. gfc_find_and_cut_at_last_class_ref (gfc_expr *e)
  224. {
  225. gfc_expr *base_expr;
  226. gfc_ref *ref, *class_ref, *tail;
  227. /* Find the last class reference. */
  228. class_ref = NULL;
  229. for (ref = e->ref; ref; ref = ref->next)
  230. {
  231. if (ref->type == REF_COMPONENT
  232. && ref->u.c.component->ts.type == BT_CLASS)
  233. class_ref = ref;
  234. if (ref->next == NULL)
  235. break;
  236. }
  237. /* Remove and store all subsequent references after the
  238. CLASS reference. */
  239. if (class_ref)
  240. {
  241. tail = class_ref->next;
  242. class_ref->next = NULL;
  243. }
  244. else
  245. {
  246. tail = e->ref;
  247. e->ref = NULL;
  248. }
  249. base_expr = gfc_expr_to_initialize (e);
  250. /* Restore the original tail expression. */
  251. if (class_ref)
  252. {
  253. gfc_free_ref_list (class_ref->next);
  254. class_ref->next = tail;
  255. }
  256. else
  257. {
  258. gfc_free_ref_list (e->ref);
  259. e->ref = tail;
  260. }
  261. return base_expr;
  262. }
  263. /* Reset the vptr to the declared type, e.g. after deallocation. */
  264. void
  265. gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
  266. {
  267. gfc_expr *rhs, *lhs = gfc_copy_expr (e);
  268. gfc_symbol *vtab;
  269. tree tmp;
  270. gfc_ref *ref;
  271. /* If we have a class array, we need go back to the class
  272. container. */
  273. if (lhs->ref && lhs->ref->next && !lhs->ref->next->next
  274. && lhs->ref->next->type == REF_ARRAY
  275. && lhs->ref->next->u.ar.type == AR_FULL
  276. && lhs->ref->type == REF_COMPONENT
  277. && strcmp (lhs->ref->u.c.component->name, "_data") == 0)
  278. {
  279. gfc_free_ref_list (lhs->ref);
  280. lhs->ref = NULL;
  281. }
  282. else
  283. for (ref = lhs->ref; ref; ref = ref->next)
  284. if (ref->next && ref->next->next && !ref->next->next->next
  285. && ref->next->next->type == REF_ARRAY
  286. && ref->next->next->u.ar.type == AR_FULL
  287. && ref->next->type == REF_COMPONENT
  288. && strcmp (ref->next->u.c.component->name, "_data") == 0)
  289. {
  290. gfc_free_ref_list (ref->next);
  291. ref->next = NULL;
  292. }
  293. gfc_add_vptr_component (lhs);
  294. if (UNLIMITED_POLY (e))
  295. rhs = gfc_get_null_expr (NULL);
  296. else
  297. {
  298. vtab = gfc_find_derived_vtab (e->ts.u.derived);
  299. rhs = gfc_lval_expr_from_sym (vtab);
  300. }
  301. tmp = gfc_trans_pointer_assignment (lhs, rhs);
  302. gfc_add_expr_to_block (block, tmp);
  303. gfc_free_expr (lhs);
  304. gfc_free_expr (rhs);
  305. }
  306. /* Reset the len for unlimited polymorphic objects. */
  307. void
  308. gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
  309. {
  310. gfc_expr *e;
  311. gfc_se se_len;
  312. e = gfc_find_and_cut_at_last_class_ref (expr);
  313. gfc_add_len_component (e);
  314. gfc_init_se (&se_len, NULL);
  315. gfc_conv_expr (&se_len, e);
  316. gfc_add_modify (block, se_len.expr,
  317. fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
  318. gfc_free_expr (e);
  319. }
  320. /* Obtain the vptr of the last class reference in an expression.
  321. Return NULL_TREE if no class reference is found. */
  322. tree
  323. gfc_get_vptr_from_expr (tree expr)
  324. {
  325. tree tmp;
  326. tree type;
  327. for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
  328. {
  329. type = TREE_TYPE (tmp);
  330. while (type)
  331. {
  332. if (GFC_CLASS_TYPE_P (type))
  333. return gfc_class_vptr_get (tmp);
  334. if (type != TYPE_CANONICAL (type))
  335. type = TYPE_CANONICAL (type);
  336. else
  337. type = NULL_TREE;
  338. }
  339. if (TREE_CODE (tmp) == VAR_DECL)
  340. break;
  341. }
  342. return NULL_TREE;
  343. }
  344. static void
  345. class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
  346. bool lhs_type)
  347. {
  348. tree tmp, tmp2, type;
  349. gfc_conv_descriptor_data_set (block, lhs_desc,
  350. gfc_conv_descriptor_data_get (rhs_desc));
  351. gfc_conv_descriptor_offset_set (block, lhs_desc,
  352. gfc_conv_descriptor_offset_get (rhs_desc));
  353. gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
  354. gfc_conv_descriptor_dtype (rhs_desc));
  355. /* Assign the dimension as range-ref. */
  356. tmp = gfc_get_descriptor_dimension (lhs_desc);
  357. tmp2 = gfc_get_descriptor_dimension (rhs_desc);
  358. type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
  359. tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
  360. gfc_index_zero_node, NULL_TREE, NULL_TREE);
  361. tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
  362. gfc_index_zero_node, NULL_TREE, NULL_TREE);
  363. gfc_add_modify (block, tmp, tmp2);
  364. }
  365. /* Takes a derived type expression and returns the address of a temporary
  366. class object of the 'declared' type. If vptr is not NULL, this is
  367. used for the temporary class object.
  368. optional_alloc_ptr is false when the dummy is neither allocatable
  369. nor a pointer; that's only relevant for the optional handling. */
  370. void
  371. gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
  372. gfc_typespec class_ts, tree vptr, bool optional,
  373. bool optional_alloc_ptr)
  374. {
  375. gfc_symbol *vtab;
  376. tree cond_optional = NULL_TREE;
  377. gfc_ss *ss;
  378. tree ctree;
  379. tree var;
  380. tree tmp;
  381. /* The derived type needs to be converted to a temporary
  382. CLASS object. */
  383. tmp = gfc_typenode_for_spec (&class_ts);
  384. var = gfc_create_var (tmp, "class");
  385. /* Set the vptr. */
  386. ctree = gfc_class_vptr_get (var);
  387. if (vptr != NULL_TREE)
  388. {
  389. /* Use the dynamic vptr. */
  390. tmp = vptr;
  391. }
  392. else
  393. {
  394. /* In this case the vtab corresponds to the derived type and the
  395. vptr must point to it. */
  396. vtab = gfc_find_derived_vtab (e->ts.u.derived);
  397. gcc_assert (vtab);
  398. tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
  399. }
  400. gfc_add_modify (&parmse->pre, ctree,
  401. fold_convert (TREE_TYPE (ctree), tmp));
  402. /* Now set the data field. */
  403. ctree = gfc_class_data_get (var);
  404. if (optional)
  405. cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
  406. if (parmse->ss && parmse->ss->info->useflags)
  407. {
  408. /* For an array reference in an elemental procedure call we need
  409. to retain the ss to provide the scalarized array reference. */
  410. gfc_conv_expr_reference (parmse, e);
  411. tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
  412. if (optional)
  413. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
  414. cond_optional, tmp,
  415. fold_convert (TREE_TYPE (tmp), null_pointer_node));
  416. gfc_add_modify (&parmse->pre, ctree, tmp);
  417. }
  418. else
  419. {
  420. ss = gfc_walk_expr (e);
  421. if (ss == gfc_ss_terminator)
  422. {
  423. parmse->ss = NULL;
  424. gfc_conv_expr_reference (parmse, e);
  425. /* Scalar to an assumed-rank array. */
  426. if (class_ts.u.derived->components->as)
  427. {
  428. tree type;
  429. type = get_scalar_to_descriptor_type (parmse->expr,
  430. gfc_expr_attr (e));
  431. gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
  432. gfc_get_dtype (type));
  433. if (optional)
  434. parmse->expr = build3_loc (input_location, COND_EXPR,
  435. TREE_TYPE (parmse->expr),
  436. cond_optional, parmse->expr,
  437. fold_convert (TREE_TYPE (parmse->expr),
  438. null_pointer_node));
  439. gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
  440. }
  441. else
  442. {
  443. tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
  444. if (optional)
  445. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
  446. cond_optional, tmp,
  447. fold_convert (TREE_TYPE (tmp),
  448. null_pointer_node));
  449. gfc_add_modify (&parmse->pre, ctree, tmp);
  450. }
  451. }
  452. else
  453. {
  454. stmtblock_t block;
  455. gfc_init_block (&block);
  456. parmse->ss = ss;
  457. gfc_conv_expr_descriptor (parmse, e);
  458. if (e->rank != class_ts.u.derived->components->as->rank)
  459. {
  460. gcc_assert (class_ts.u.derived->components->as->type
  461. == AS_ASSUMED_RANK);
  462. class_array_data_assign (&block, ctree, parmse->expr, false);
  463. }
  464. else
  465. {
  466. if (gfc_expr_attr (e).codimension)
  467. parmse->expr = fold_build1_loc (input_location,
  468. VIEW_CONVERT_EXPR,
  469. TREE_TYPE (ctree),
  470. parmse->expr);
  471. gfc_add_modify (&block, ctree, parmse->expr);
  472. }
  473. if (optional)
  474. {
  475. tmp = gfc_finish_block (&block);
  476. gfc_init_block (&block);
  477. gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
  478. tmp = build3_v (COND_EXPR, cond_optional, tmp,
  479. gfc_finish_block (&block));
  480. gfc_add_expr_to_block (&parmse->pre, tmp);
  481. }
  482. else
  483. gfc_add_block_to_block (&parmse->pre, &block);
  484. }
  485. }
  486. if (class_ts.u.derived->components->ts.type == BT_DERIVED
  487. && class_ts.u.derived->components->ts.u.derived
  488. ->attr.unlimited_polymorphic)
  489. {
  490. /* Take care about initializing the _len component correctly. */
  491. ctree = gfc_class_len_get (var);
  492. if (UNLIMITED_POLY (e))
  493. {
  494. gfc_expr *len;
  495. gfc_se se;
  496. len = gfc_copy_expr (e);
  497. gfc_add_len_component (len);
  498. gfc_init_se (&se, NULL);
  499. gfc_conv_expr (&se, len);
  500. if (optional)
  501. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
  502. cond_optional, se.expr,
  503. fold_convert (TREE_TYPE (se.expr),
  504. integer_zero_node));
  505. else
  506. tmp = se.expr;
  507. }
  508. else
  509. tmp = integer_zero_node;
  510. gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
  511. tmp));
  512. }
  513. /* Pass the address of the class object. */
  514. parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
  515. if (optional && optional_alloc_ptr)
  516. parmse->expr = build3_loc (input_location, COND_EXPR,
  517. TREE_TYPE (parmse->expr),
  518. cond_optional, parmse->expr,
  519. fold_convert (TREE_TYPE (parmse->expr),
  520. null_pointer_node));
  521. }
  522. /* Create a new class container, which is required as scalar coarrays
  523. have an array descriptor while normal scalars haven't. Optionally,
  524. NULL pointer checks are added if the argument is OPTIONAL. */
  525. static void
  526. class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
  527. gfc_typespec class_ts, bool optional)
  528. {
  529. tree var, ctree, tmp;
  530. stmtblock_t block;
  531. gfc_ref *ref;
  532. gfc_ref *class_ref;
  533. gfc_init_block (&block);
  534. class_ref = NULL;
  535. for (ref = e->ref; ref; ref = ref->next)
  536. {
  537. if (ref->type == REF_COMPONENT
  538. && ref->u.c.component->ts.type == BT_CLASS)
  539. class_ref = ref;
  540. }
  541. if (class_ref == NULL
  542. && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
  543. tmp = e->symtree->n.sym->backend_decl;
  544. else
  545. {
  546. /* Remove everything after the last class reference, convert the
  547. expression and then recover its tailend once more. */
  548. gfc_se tmpse;
  549. ref = class_ref->next;
  550. class_ref->next = NULL;
  551. gfc_init_se (&tmpse, NULL);
  552. gfc_conv_expr (&tmpse, e);
  553. class_ref->next = ref;
  554. tmp = tmpse.expr;
  555. }
  556. var = gfc_typenode_for_spec (&class_ts);
  557. var = gfc_create_var (var, "class");
  558. ctree = gfc_class_vptr_get (var);
  559. gfc_add_modify (&block, ctree,
  560. fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
  561. ctree = gfc_class_data_get (var);
  562. tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
  563. gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
  564. /* Pass the address of the class object. */
  565. parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
  566. if (optional)
  567. {
  568. tree cond = gfc_conv_expr_present (e->symtree->n.sym);
  569. tree tmp2;
  570. tmp = gfc_finish_block (&block);
  571. gfc_init_block (&block);
  572. tmp2 = gfc_class_data_get (var);
  573. gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
  574. null_pointer_node));
  575. tmp2 = gfc_finish_block (&block);
  576. tmp = build3_loc (input_location, COND_EXPR, void_type_node,
  577. cond, tmp, tmp2);
  578. gfc_add_expr_to_block (&parmse->pre, tmp);
  579. }
  580. else
  581. gfc_add_block_to_block (&parmse->pre, &block);
  582. }
  583. /* Takes an intrinsic type expression and returns the address of a temporary
  584. class object of the 'declared' type. */
  585. void
  586. gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
  587. gfc_typespec class_ts)
  588. {
  589. gfc_symbol *vtab;
  590. gfc_ss *ss;
  591. tree ctree;
  592. tree var;
  593. tree tmp;
  594. /* The intrinsic type needs to be converted to a temporary
  595. CLASS object. */
  596. tmp = gfc_typenode_for_spec (&class_ts);
  597. var = gfc_create_var (tmp, "class");
  598. /* Set the vptr. */
  599. ctree = gfc_class_vptr_get (var);
  600. vtab = gfc_find_vtab (&e->ts);
  601. gcc_assert (vtab);
  602. tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
  603. gfc_add_modify (&parmse->pre, ctree,
  604. fold_convert (TREE_TYPE (ctree), tmp));
  605. /* Now set the data field. */
  606. ctree = gfc_class_data_get (var);
  607. if (parmse->ss && parmse->ss->info->useflags)
  608. {
  609. /* For an array reference in an elemental procedure call we need
  610. to retain the ss to provide the scalarized array reference. */
  611. gfc_conv_expr_reference (parmse, e);
  612. tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
  613. gfc_add_modify (&parmse->pre, ctree, tmp);
  614. }
  615. else
  616. {
  617. ss = gfc_walk_expr (e);
  618. if (ss == gfc_ss_terminator)
  619. {
  620. parmse->ss = NULL;
  621. gfc_conv_expr_reference (parmse, e);
  622. if (class_ts.u.derived->components->as
  623. && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
  624. {
  625. tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
  626. gfc_expr_attr (e));
  627. tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
  628. TREE_TYPE (ctree), tmp);
  629. }
  630. else
  631. tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
  632. gfc_add_modify (&parmse->pre, ctree, tmp);
  633. }
  634. else
  635. {
  636. parmse->ss = ss;
  637. parmse->use_offset = 1;
  638. gfc_conv_expr_descriptor (parmse, e);
  639. if (class_ts.u.derived->components->as->rank != e->rank)
  640. {
  641. tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
  642. TREE_TYPE (ctree), parmse->expr);
  643. gfc_add_modify (&parmse->pre, ctree, tmp);
  644. }
  645. else
  646. gfc_add_modify (&parmse->pre, ctree, parmse->expr);
  647. }
  648. }
  649. gcc_assert (class_ts.type == BT_CLASS);
  650. if (class_ts.u.derived->components->ts.type == BT_DERIVED
  651. && class_ts.u.derived->components->ts.u.derived
  652. ->attr.unlimited_polymorphic)
  653. {
  654. ctree = gfc_class_len_get (var);
  655. /* When the actual arg is a char array, then set the _len component of the
  656. unlimited polymorphic entity, too. */
  657. if (e->ts.type == BT_CHARACTER)
  658. {
  659. /* Start with parmse->string_length because this seems to be set to a
  660. correct value more often. */
  661. if (parmse->string_length)
  662. tmp = parmse->string_length;
  663. /* When the string_length is not yet set, then try the backend_decl of
  664. the cl. */
  665. else if (e->ts.u.cl->backend_decl)
  666. tmp = e->ts.u.cl->backend_decl;
  667. /* If both of the above approaches fail, then try to generate an
  668. expression from the input, which is only feasible currently, when the
  669. expression can be evaluated to a constant one. */
  670. else
  671. {
  672. /* Try to simplify the expression. */
  673. gfc_simplify_expr (e, 0);
  674. if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
  675. {
  676. /* Amazingly all data is present to compute the length of a
  677. constant string, but the expression is not yet there. */
  678. e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER, 4,
  679. &e->where);
  680. mpz_set_ui (e->ts.u.cl->length->value.integer,
  681. e->value.character.length);
  682. gfc_conv_const_charlen (e->ts.u.cl);
  683. e->ts.u.cl->resolved = 1;
  684. tmp = e->ts.u.cl->backend_decl;
  685. }
  686. else
  687. {
  688. gfc_error ("Can't compute the length of the char array at %L.",
  689. &e->where);
  690. }
  691. }
  692. }
  693. else
  694. tmp = integer_zero_node;
  695. gfc_add_modify (&parmse->pre, ctree, tmp);
  696. }
  697. /* Pass the address of the class object. */
  698. parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
  699. }
  700. /* Takes a scalarized class array expression and returns the
  701. address of a temporary scalar class object of the 'declared'
  702. type.
  703. OOP-TODO: This could be improved by adding code that branched on
  704. the dynamic type being the same as the declared type. In this case
  705. the original class expression can be passed directly.
  706. optional_alloc_ptr is false when the dummy is neither allocatable
  707. nor a pointer; that's relevant for the optional handling.
  708. Set copyback to true if class container's _data and _vtab pointers
  709. might get modified. */
  710. void
  711. gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
  712. bool elemental, bool copyback, bool optional,
  713. bool optional_alloc_ptr)
  714. {
  715. tree ctree;
  716. tree var;
  717. tree tmp;
  718. tree vptr;
  719. tree cond = NULL_TREE;
  720. gfc_ref *ref;
  721. gfc_ref *class_ref;
  722. stmtblock_t block;
  723. bool full_array = false;
  724. gfc_init_block (&block);
  725. class_ref = NULL;
  726. for (ref = e->ref; ref; ref = ref->next)
  727. {
  728. if (ref->type == REF_COMPONENT
  729. && ref->u.c.component->ts.type == BT_CLASS)
  730. class_ref = ref;
  731. if (ref->next == NULL)
  732. break;
  733. }
  734. if ((ref == NULL || class_ref == ref)
  735. && (!class_ts.u.derived->components->as
  736. || class_ts.u.derived->components->as->rank != -1))
  737. return;
  738. /* Test for FULL_ARRAY. */
  739. if (e->rank == 0 && gfc_expr_attr (e).codimension
  740. && gfc_expr_attr (e).dimension)
  741. full_array = true;
  742. else
  743. gfc_is_class_array_ref (e, &full_array);
  744. /* The derived type needs to be converted to a temporary
  745. CLASS object. */
  746. tmp = gfc_typenode_for_spec (&class_ts);
  747. var = gfc_create_var (tmp, "class");
  748. /* Set the data. */
  749. ctree = gfc_class_data_get (var);
  750. if (class_ts.u.derived->components->as
  751. && e->rank != class_ts.u.derived->components->as->rank)
  752. {
  753. if (e->rank == 0)
  754. {
  755. tree type = get_scalar_to_descriptor_type (parmse->expr,
  756. gfc_expr_attr (e));
  757. gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
  758. gfc_get_dtype (type));
  759. tmp = gfc_class_data_get (parmse->expr);
  760. if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
  761. tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  762. gfc_conv_descriptor_data_set (&block, ctree, tmp);
  763. }
  764. else
  765. class_array_data_assign (&block, ctree, parmse->expr, false);
  766. }
  767. else
  768. {
  769. if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
  770. parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
  771. TREE_TYPE (ctree), parmse->expr);
  772. gfc_add_modify (&block, ctree, parmse->expr);
  773. }
  774. /* Return the data component, except in the case of scalarized array
  775. references, where nullification of the cannot occur and so there
  776. is no need. */
  777. if (!elemental && full_array && copyback)
  778. {
  779. if (class_ts.u.derived->components->as
  780. && e->rank != class_ts.u.derived->components->as->rank)
  781. {
  782. if (e->rank == 0)
  783. gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
  784. gfc_conv_descriptor_data_get (ctree));
  785. else
  786. class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
  787. }
  788. else
  789. gfc_add_modify (&parmse->post, parmse->expr, ctree);
  790. }
  791. /* Set the vptr. */
  792. ctree = gfc_class_vptr_get (var);
  793. /* The vptr is the second field of the actual argument.
  794. First we have to find the corresponding class reference. */
  795. tmp = NULL_TREE;
  796. if (class_ref == NULL
  797. && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
  798. tmp = e->symtree->n.sym->backend_decl;
  799. else
  800. {
  801. /* Remove everything after the last class reference, convert the
  802. expression and then recover its tailend once more. */
  803. gfc_se tmpse;
  804. ref = class_ref->next;
  805. class_ref->next = NULL;
  806. gfc_init_se (&tmpse, NULL);
  807. gfc_conv_expr (&tmpse, e);
  808. class_ref->next = ref;
  809. tmp = tmpse.expr;
  810. }
  811. gcc_assert (tmp != NULL_TREE);
  812. /* Dereference if needs be. */
  813. if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
  814. tmp = build_fold_indirect_ref_loc (input_location, tmp);
  815. vptr = gfc_class_vptr_get (tmp);
  816. gfc_add_modify (&block, ctree,
  817. fold_convert (TREE_TYPE (ctree), vptr));
  818. /* Return the vptr component, except in the case of scalarized array
  819. references, where the dynamic type cannot change. */
  820. if (!elemental && full_array && copyback)
  821. gfc_add_modify (&parmse->post, vptr,
  822. fold_convert (TREE_TYPE (vptr), ctree));
  823. if (optional)
  824. {
  825. tree tmp2;
  826. cond = gfc_conv_expr_present (e->symtree->n.sym);
  827. tmp = gfc_finish_block (&block);
  828. if (optional_alloc_ptr)
  829. tmp2 = build_empty_stmt (input_location);
  830. else
  831. {
  832. gfc_init_block (&block);
  833. tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
  834. gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
  835. null_pointer_node));
  836. tmp2 = gfc_finish_block (&block);
  837. }
  838. tmp = build3_loc (input_location, COND_EXPR, void_type_node,
  839. cond, tmp, tmp2);
  840. gfc_add_expr_to_block (&parmse->pre, tmp);
  841. }
  842. else
  843. gfc_add_block_to_block (&parmse->pre, &block);
  844. /* Pass the address of the class object. */
  845. parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
  846. if (optional && optional_alloc_ptr)
  847. parmse->expr = build3_loc (input_location, COND_EXPR,
  848. TREE_TYPE (parmse->expr),
  849. cond, parmse->expr,
  850. fold_convert (TREE_TYPE (parmse->expr),
  851. null_pointer_node));
  852. }
  853. /* Given a class array declaration and an index, returns the address
  854. of the referenced element. */
  855. tree
  856. gfc_get_class_array_ref (tree index, tree class_decl)
  857. {
  858. tree data = gfc_class_data_get (class_decl);
  859. tree size = gfc_class_vtab_size_get (class_decl);
  860. tree offset = fold_build2_loc (input_location, MULT_EXPR,
  861. gfc_array_index_type,
  862. index, size);
  863. tree ptr;
  864. data = gfc_conv_descriptor_data_get (data);
  865. ptr = fold_convert (pvoid_type_node, data);
  866. ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
  867. return fold_convert (TREE_TYPE (data), ptr);
  868. }
  869. /* Copies one class expression to another, assuming that if either
  870. 'to' or 'from' are arrays they are packed. Should 'from' be
  871. NULL_TREE, the initialization expression for 'to' is used, assuming
  872. that the _vptr is set. */
  873. tree
  874. gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
  875. {
  876. tree fcn;
  877. tree fcn_type;
  878. tree from_data;
  879. tree from_len;
  880. tree to_data;
  881. tree to_len;
  882. tree to_ref;
  883. tree from_ref;
  884. vec<tree, va_gc> *args;
  885. tree tmp;
  886. tree stdcopy;
  887. tree extcopy;
  888. tree index;
  889. args = NULL;
  890. /* To prevent warnings on uninitialized variables. */
  891. from_len = to_len = NULL_TREE;
  892. if (from != NULL_TREE)
  893. fcn = gfc_class_vtab_copy_get (from);
  894. else
  895. fcn = gfc_class_vtab_copy_get (to);
  896. fcn_type = TREE_TYPE (TREE_TYPE (fcn));
  897. if (from != NULL_TREE)
  898. from_data = gfc_class_data_get (from);
  899. else
  900. from_data = gfc_class_vtab_def_init_get (to);
  901. if (unlimited)
  902. {
  903. if (from != NULL_TREE && unlimited)
  904. from_len = gfc_class_len_get (from);
  905. else
  906. from_len = integer_zero_node;
  907. }
  908. to_data = gfc_class_data_get (to);
  909. if (unlimited)
  910. to_len = gfc_class_len_get (to);
  911. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
  912. {
  913. stmtblock_t loopbody;
  914. stmtblock_t body;
  915. stmtblock_t ifbody;
  916. gfc_loopinfo loop;
  917. gfc_init_block (&body);
  918. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  919. gfc_array_index_type, nelems,
  920. gfc_index_one_node);
  921. nelems = gfc_evaluate_now (tmp, &body);
  922. index = gfc_create_var (gfc_array_index_type, "S");
  923. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
  924. {
  925. from_ref = gfc_get_class_array_ref (index, from);
  926. vec_safe_push (args, from_ref);
  927. }
  928. else
  929. vec_safe_push (args, from_data);
  930. to_ref = gfc_get_class_array_ref (index, to);
  931. vec_safe_push (args, to_ref);
  932. tmp = build_call_vec (fcn_type, fcn, args);
  933. /* Build the body of the loop. */
  934. gfc_init_block (&loopbody);
  935. gfc_add_expr_to_block (&loopbody, tmp);
  936. /* Build the loop and return. */
  937. gfc_init_loopinfo (&loop);
  938. loop.dimen = 1;
  939. loop.from[0] = gfc_index_zero_node;
  940. loop.loopvar[0] = index;
  941. loop.to[0] = nelems;
  942. gfc_trans_scalarizing_loops (&loop, &loopbody);
  943. gfc_init_block (&ifbody);
  944. gfc_add_block_to_block (&ifbody, &loop.pre);
  945. stdcopy = gfc_finish_block (&ifbody);
  946. if (unlimited)
  947. {
  948. vec_safe_push (args, from_len);
  949. vec_safe_push (args, to_len);
  950. tmp = build_call_vec (fcn_type, fcn, args);
  951. /* Build the body of the loop. */
  952. gfc_init_block (&loopbody);
  953. gfc_add_expr_to_block (&loopbody, tmp);
  954. /* Build the loop and return. */
  955. gfc_init_loopinfo (&loop);
  956. loop.dimen = 1;
  957. loop.from[0] = gfc_index_zero_node;
  958. loop.loopvar[0] = index;
  959. loop.to[0] = nelems;
  960. gfc_trans_scalarizing_loops (&loop, &loopbody);
  961. gfc_init_block (&ifbody);
  962. gfc_add_block_to_block (&ifbody, &loop.pre);
  963. extcopy = gfc_finish_block (&ifbody);
  964. tmp = fold_build2_loc (input_location, GT_EXPR,
  965. boolean_type_node, from_len,
  966. integer_zero_node);
  967. tmp = fold_build3_loc (input_location, COND_EXPR,
  968. void_type_node, tmp, extcopy, stdcopy);
  969. gfc_add_expr_to_block (&body, tmp);
  970. tmp = gfc_finish_block (&body);
  971. }
  972. else
  973. {
  974. gfc_add_expr_to_block (&body, stdcopy);
  975. tmp = gfc_finish_block (&body);
  976. }
  977. gfc_cleanup_loop (&loop);
  978. }
  979. else
  980. {
  981. gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
  982. vec_safe_push (args, from_data);
  983. vec_safe_push (args, to_data);
  984. stdcopy = build_call_vec (fcn_type, fcn, args);
  985. if (unlimited)
  986. {
  987. vec_safe_push (args, from_len);
  988. vec_safe_push (args, to_len);
  989. extcopy = build_call_vec (fcn_type, fcn, args);
  990. tmp = fold_build2_loc (input_location, GT_EXPR,
  991. boolean_type_node, from_len,
  992. integer_zero_node);
  993. tmp = fold_build3_loc (input_location, COND_EXPR,
  994. void_type_node, tmp, extcopy, stdcopy);
  995. }
  996. else
  997. tmp = stdcopy;
  998. }
  999. return tmp;
  1000. }
  1001. static tree
  1002. gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
  1003. {
  1004. gfc_actual_arglist *actual;
  1005. gfc_expr *ppc;
  1006. gfc_code *ppc_code;
  1007. tree res;
  1008. actual = gfc_get_actual_arglist ();
  1009. actual->expr = gfc_copy_expr (rhs);
  1010. actual->next = gfc_get_actual_arglist ();
  1011. actual->next->expr = gfc_copy_expr (lhs);
  1012. ppc = gfc_copy_expr (obj);
  1013. gfc_add_vptr_component (ppc);
  1014. gfc_add_component_ref (ppc, "_copy");
  1015. ppc_code = gfc_get_code (EXEC_CALL);
  1016. ppc_code->resolved_sym = ppc->symtree->n.sym;
  1017. /* Although '_copy' is set to be elemental in class.c, it is
  1018. not staying that way. Find out why, sometime.... */
  1019. ppc_code->resolved_sym->attr.elemental = 1;
  1020. ppc_code->ext.actual = actual;
  1021. ppc_code->expr1 = ppc;
  1022. /* Since '_copy' is elemental, the scalarizer will take care
  1023. of arrays in gfc_trans_call. */
  1024. res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
  1025. gfc_free_statements (ppc_code);
  1026. if (UNLIMITED_POLY(obj))
  1027. {
  1028. /* Check if rhs is non-NULL. */
  1029. gfc_se src;
  1030. gfc_init_se (&src, NULL);
  1031. gfc_conv_expr (&src, rhs);
  1032. src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
  1033. tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  1034. src.expr, fold_convert (TREE_TYPE (src.expr),
  1035. null_pointer_node));
  1036. res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
  1037. build_empty_stmt (input_location));
  1038. }
  1039. return res;
  1040. }
  1041. /* Special case for initializing a polymorphic dummy with INTENT(OUT).
  1042. A MEMCPY is needed to copy the full data from the default initializer
  1043. of the dynamic type. */
  1044. tree
  1045. gfc_trans_class_init_assign (gfc_code *code)
  1046. {
  1047. stmtblock_t block;
  1048. tree tmp;
  1049. gfc_se dst,src,memsz;
  1050. gfc_expr *lhs, *rhs, *sz;
  1051. gfc_start_block (&block);
  1052. lhs = gfc_copy_expr (code->expr1);
  1053. gfc_add_data_component (lhs);
  1054. rhs = gfc_copy_expr (code->expr1);
  1055. gfc_add_vptr_component (rhs);
  1056. /* Make sure that the component backend_decls have been built, which
  1057. will not have happened if the derived types concerned have not
  1058. been referenced. */
  1059. gfc_get_derived_type (rhs->ts.u.derived);
  1060. gfc_add_def_init_component (rhs);
  1061. if (code->expr1->ts.type == BT_CLASS
  1062. && CLASS_DATA (code->expr1)->attr.dimension)
  1063. tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
  1064. else
  1065. {
  1066. sz = gfc_copy_expr (code->expr1);
  1067. gfc_add_vptr_component (sz);
  1068. gfc_add_size_component (sz);
  1069. gfc_init_se (&dst, NULL);
  1070. gfc_init_se (&src, NULL);
  1071. gfc_init_se (&memsz, NULL);
  1072. gfc_conv_expr (&dst, lhs);
  1073. gfc_conv_expr (&src, rhs);
  1074. gfc_conv_expr (&memsz, sz);
  1075. gfc_add_block_to_block (&block, &src.pre);
  1076. src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
  1077. tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
  1078. if (UNLIMITED_POLY(code->expr1))
  1079. {
  1080. /* Check if _def_init is non-NULL. */
  1081. tree cond = fold_build2_loc (input_location, NE_EXPR,
  1082. boolean_type_node, src.expr,
  1083. fold_convert (TREE_TYPE (src.expr),
  1084. null_pointer_node));
  1085. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
  1086. tmp, build_empty_stmt (input_location));
  1087. }
  1088. }
  1089. if (code->expr1->symtree->n.sym->attr.optional
  1090. || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
  1091. {
  1092. tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
  1093. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
  1094. present, tmp,
  1095. build_empty_stmt (input_location));
  1096. }
  1097. gfc_add_expr_to_block (&block, tmp);
  1098. return gfc_finish_block (&block);
  1099. }
  1100. /* Translate an assignment to a CLASS object
  1101. (pointer or ordinary assignment). */
  1102. tree
  1103. gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
  1104. {
  1105. stmtblock_t block;
  1106. tree tmp;
  1107. gfc_expr *lhs;
  1108. gfc_expr *rhs;
  1109. gfc_ref *ref;
  1110. gfc_start_block (&block);
  1111. ref = expr1->ref;
  1112. while (ref && ref->next)
  1113. ref = ref->next;
  1114. /* Class valued proc_pointer assignments do not need any further
  1115. preparation. */
  1116. if (ref && ref->type == REF_COMPONENT
  1117. && ref->u.c.component->attr.proc_pointer
  1118. && expr2->expr_type == EXPR_VARIABLE
  1119. && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
  1120. && op == EXEC_POINTER_ASSIGN)
  1121. goto assign;
  1122. if (expr2->ts.type != BT_CLASS)
  1123. {
  1124. /* Insert an additional assignment which sets the '_vptr' field. */
  1125. gfc_symbol *vtab = NULL;
  1126. gfc_symtree *st;
  1127. lhs = gfc_copy_expr (expr1);
  1128. gfc_add_vptr_component (lhs);
  1129. if (UNLIMITED_POLY (expr1)
  1130. && expr2->expr_type == EXPR_NULL && expr2->ts.type == BT_UNKNOWN)
  1131. {
  1132. rhs = gfc_get_null_expr (&expr2->where);
  1133. goto assign_vptr;
  1134. }
  1135. if (expr2->expr_type == EXPR_NULL)
  1136. vtab = gfc_find_vtab (&expr1->ts);
  1137. else
  1138. vtab = gfc_find_vtab (&expr2->ts);
  1139. gcc_assert (vtab);
  1140. rhs = gfc_get_expr ();
  1141. rhs->expr_type = EXPR_VARIABLE;
  1142. gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
  1143. rhs->symtree = st;
  1144. rhs->ts = vtab->ts;
  1145. assign_vptr:
  1146. tmp = gfc_trans_pointer_assignment (lhs, rhs);
  1147. gfc_add_expr_to_block (&block, tmp);
  1148. gfc_free_expr (lhs);
  1149. gfc_free_expr (rhs);
  1150. }
  1151. else if (expr1->ts.type == BT_DERIVED && UNLIMITED_POLY (expr2))
  1152. {
  1153. /* F2003:C717 only sequence and bind-C types can come here. */
  1154. gcc_assert (expr1->ts.u.derived->attr.sequence
  1155. || expr1->ts.u.derived->attr.is_bind_c);
  1156. gfc_add_data_component (expr2);
  1157. goto assign;
  1158. }
  1159. else if (CLASS_DATA (expr2)->attr.dimension && expr2->expr_type != EXPR_FUNCTION)
  1160. {
  1161. /* Insert an additional assignment which sets the '_vptr' field. */
  1162. lhs = gfc_copy_expr (expr1);
  1163. gfc_add_vptr_component (lhs);
  1164. rhs = gfc_copy_expr (expr2);
  1165. gfc_add_vptr_component (rhs);
  1166. tmp = gfc_trans_pointer_assignment (lhs, rhs);
  1167. gfc_add_expr_to_block (&block, tmp);
  1168. gfc_free_expr (lhs);
  1169. gfc_free_expr (rhs);
  1170. }
  1171. /* Do the actual CLASS assignment. */
  1172. if (expr2->ts.type == BT_CLASS
  1173. && !CLASS_DATA (expr2)->attr.dimension)
  1174. op = EXEC_ASSIGN;
  1175. else if (expr2->expr_type != EXPR_FUNCTION || expr2->ts.type != BT_CLASS
  1176. || !CLASS_DATA (expr2)->attr.dimension)
  1177. gfc_add_data_component (expr1);
  1178. assign:
  1179. if (op == EXEC_ASSIGN)
  1180. tmp = gfc_trans_assignment (expr1, expr2, false, true);
  1181. else if (op == EXEC_POINTER_ASSIGN)
  1182. tmp = gfc_trans_pointer_assignment (expr1, expr2);
  1183. else
  1184. gcc_unreachable();
  1185. gfc_add_expr_to_block (&block, tmp);
  1186. return gfc_finish_block (&block);
  1187. }
  1188. /* End of prototype trans-class.c */
  1189. static void
  1190. realloc_lhs_warning (bt type, bool array, locus *where)
  1191. {
  1192. if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
  1193. gfc_warning (OPT_Wrealloc_lhs,
  1194. "Code for reallocating the allocatable array at %L will "
  1195. "be added", where);
  1196. else if (warn_realloc_lhs_all)
  1197. gfc_warning (OPT_Wrealloc_lhs_all,
  1198. "Code for reallocating the allocatable variable at %L "
  1199. "will be added", where);
  1200. }
  1201. static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init);
  1202. static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
  1203. gfc_expr *);
  1204. /* Copy the scalarization loop variables. */
  1205. static void
  1206. gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
  1207. {
  1208. dest->ss = src->ss;
  1209. dest->loop = src->loop;
  1210. }
  1211. /* Initialize a simple expression holder.
  1212. Care must be taken when multiple se are created with the same parent.
  1213. The child se must be kept in sync. The easiest way is to delay creation
  1214. of a child se until after after the previous se has been translated. */
  1215. void
  1216. gfc_init_se (gfc_se * se, gfc_se * parent)
  1217. {
  1218. memset (se, 0, sizeof (gfc_se));
  1219. gfc_init_block (&se->pre);
  1220. gfc_init_block (&se->post);
  1221. se->parent = parent;
  1222. if (parent)
  1223. gfc_copy_se_loopvars (se, parent);
  1224. }
  1225. /* Advances to the next SS in the chain. Use this rather than setting
  1226. se->ss = se->ss->next because all the parents needs to be kept in sync.
  1227. See gfc_init_se. */
  1228. void
  1229. gfc_advance_se_ss_chain (gfc_se * se)
  1230. {
  1231. gfc_se *p;
  1232. gfc_ss *ss;
  1233. gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
  1234. p = se;
  1235. /* Walk down the parent chain. */
  1236. while (p != NULL)
  1237. {
  1238. /* Simple consistency check. */
  1239. gcc_assert (p->parent == NULL || p->parent->ss == p->ss
  1240. || p->parent->ss->nested_ss == p->ss);
  1241. /* If we were in a nested loop, the next scalarized expression can be
  1242. on the parent ss' next pointer. Thus we should not take the next
  1243. pointer blindly, but rather go up one nest level as long as next
  1244. is the end of chain. */
  1245. ss = p->ss;
  1246. while (ss->next == gfc_ss_terminator && ss->parent != NULL)
  1247. ss = ss->parent;
  1248. p->ss = ss->next;
  1249. p = p->parent;
  1250. }
  1251. }
  1252. /* Ensures the result of the expression as either a temporary variable
  1253. or a constant so that it can be used repeatedly. */
  1254. void
  1255. gfc_make_safe_expr (gfc_se * se)
  1256. {
  1257. tree var;
  1258. if (CONSTANT_CLASS_P (se->expr))
  1259. return;
  1260. /* We need a temporary for this result. */
  1261. var = gfc_create_var (TREE_TYPE (se->expr), NULL);
  1262. gfc_add_modify (&se->pre, var, se->expr);
  1263. se->expr = var;
  1264. }
  1265. /* Return an expression which determines if a dummy parameter is present.
  1266. Also used for arguments to procedures with multiple entry points. */
  1267. tree
  1268. gfc_conv_expr_present (gfc_symbol * sym)
  1269. {
  1270. tree decl, cond;
  1271. gcc_assert (sym->attr.dummy);
  1272. decl = gfc_get_symbol_decl (sym);
  1273. /* Intrinsic scalars with VALUE attribute which are passed by value
  1274. use a hidden argument to denote the present status. */
  1275. if (sym->attr.value && sym->ts.type != BT_CHARACTER
  1276. && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
  1277. && !sym->attr.dimension)
  1278. {
  1279. char name[GFC_MAX_SYMBOL_LEN + 2];
  1280. tree tree_name;
  1281. gcc_assert (TREE_CODE (decl) == PARM_DECL);
  1282. name[0] = '_';
  1283. strcpy (&name[1], sym->name);
  1284. tree_name = get_identifier (name);
  1285. /* Walk function argument list to find hidden arg. */
  1286. cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
  1287. for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
  1288. if (DECL_NAME (cond) == tree_name)
  1289. break;
  1290. gcc_assert (cond);
  1291. return cond;
  1292. }
  1293. if (TREE_CODE (decl) != PARM_DECL)
  1294. {
  1295. /* Array parameters use a temporary descriptor, we want the real
  1296. parameter. */
  1297. gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
  1298. || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
  1299. decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
  1300. }
  1301. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
  1302. fold_convert (TREE_TYPE (decl), null_pointer_node));
  1303. /* Fortran 2008 allows to pass null pointers and non-associated pointers
  1304. as actual argument to denote absent dummies. For array descriptors,
  1305. we thus also need to check the array descriptor. For BT_CLASS, it
  1306. can also occur for scalars and F2003 due to type->class wrapping and
  1307. class->class wrapping. Note further that BT_CLASS always uses an
  1308. array descriptor for arrays, also for explicit-shape/assumed-size. */
  1309. if (!sym->attr.allocatable
  1310. && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
  1311. || (sym->ts.type == BT_CLASS
  1312. && !CLASS_DATA (sym)->attr.allocatable
  1313. && !CLASS_DATA (sym)->attr.class_pointer))
  1314. && ((gfc_option.allow_std & GFC_STD_F2008) != 0
  1315. || sym->ts.type == BT_CLASS))
  1316. {
  1317. tree tmp;
  1318. if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
  1319. || sym->as->type == AS_ASSUMED_RANK
  1320. || sym->attr.codimension))
  1321. || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
  1322. {
  1323. tmp = build_fold_indirect_ref_loc (input_location, decl);
  1324. if (sym->ts.type == BT_CLASS)
  1325. tmp = gfc_class_data_get (tmp);
  1326. tmp = gfc_conv_array_data (tmp);
  1327. }
  1328. else if (sym->ts.type == BT_CLASS)
  1329. tmp = gfc_class_data_get (decl);
  1330. else
  1331. tmp = NULL_TREE;
  1332. if (tmp != NULL_TREE)
  1333. {
  1334. tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
  1335. fold_convert (TREE_TYPE (tmp), null_pointer_node));
  1336. cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
  1337. boolean_type_node, cond, tmp);
  1338. }
  1339. }
  1340. return cond;
  1341. }
  1342. /* Converts a missing, dummy argument into a null or zero. */
  1343. void
  1344. gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
  1345. {
  1346. tree present;
  1347. tree tmp;
  1348. present = gfc_conv_expr_present (arg->symtree->n.sym);
  1349. if (kind > 0)
  1350. {
  1351. /* Create a temporary and convert it to the correct type. */
  1352. tmp = gfc_get_int_type (kind);
  1353. tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
  1354. se->expr));
  1355. /* Test for a NULL value. */
  1356. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
  1357. tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
  1358. tmp = gfc_evaluate_now (tmp, &se->pre);
  1359. se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
  1360. }
  1361. else
  1362. {
  1363. tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
  1364. present, se->expr,
  1365. build_zero_cst (TREE_TYPE (se->expr)));
  1366. tmp = gfc_evaluate_now (tmp, &se->pre);
  1367. se->expr = tmp;
  1368. }
  1369. if (ts.type == BT_CHARACTER)
  1370. {
  1371. tmp = build_int_cst (gfc_charlen_type_node, 0);
  1372. tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
  1373. present, se->string_length, tmp);
  1374. tmp = gfc_evaluate_now (tmp, &se->pre);
  1375. se->string_length = tmp;
  1376. }
  1377. return;
  1378. }
  1379. /* Get the character length of an expression, looking through gfc_refs
  1380. if necessary. */
  1381. tree
  1382. gfc_get_expr_charlen (gfc_expr *e)
  1383. {
  1384. gfc_ref *r;
  1385. tree length;
  1386. gcc_assert (e->expr_type == EXPR_VARIABLE
  1387. && e->ts.type == BT_CHARACTER);
  1388. length = NULL; /* To silence compiler warning. */
  1389. if (is_subref_array (e) && e->ts.u.cl->length)
  1390. {
  1391. gfc_se tmpse;
  1392. gfc_init_se (&tmpse, NULL);
  1393. gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
  1394. e->ts.u.cl->backend_decl = tmpse.expr;
  1395. return tmpse.expr;
  1396. }
  1397. /* First candidate: if the variable is of type CHARACTER, the
  1398. expression's length could be the length of the character
  1399. variable. */
  1400. if (e->symtree->n.sym->ts.type == BT_CHARACTER)
  1401. length = e->symtree->n.sym->ts.u.cl->backend_decl;
  1402. /* Look through the reference chain for component references. */
  1403. for (r = e->ref; r; r = r->next)
  1404. {
  1405. switch (r->type)
  1406. {
  1407. case REF_COMPONENT:
  1408. if (r->u.c.component->ts.type == BT_CHARACTER)
  1409. length = r->u.c.component->ts.u.cl->backend_decl;
  1410. break;
  1411. case REF_ARRAY:
  1412. /* Do nothing. */
  1413. break;
  1414. default:
  1415. /* We should never got substring references here. These will be
  1416. broken down by the scalarizer. */
  1417. gcc_unreachable ();
  1418. break;
  1419. }
  1420. }
  1421. gcc_assert (length != NULL);
  1422. return length;
  1423. }
  1424. /* Return for an expression the backend decl of the coarray. */
  1425. tree
  1426. gfc_get_tree_for_caf_expr (gfc_expr *expr)
  1427. {
  1428. tree caf_decl;
  1429. bool found = false;
  1430. gfc_ref *ref, *comp_ref = NULL;
  1431. gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
  1432. /* Not-implemented diagnostic. */
  1433. for (ref = expr->ref; ref; ref = ref->next)
  1434. if (ref->type == REF_COMPONENT)
  1435. {
  1436. comp_ref = ref;
  1437. if ((ref->u.c.component->ts.type == BT_CLASS
  1438. && !CLASS_DATA (ref->u.c.component)->attr.codimension
  1439. && (CLASS_DATA (ref->u.c.component)->attr.pointer
  1440. || CLASS_DATA (ref->u.c.component)->attr.allocatable))
  1441. || (ref->u.c.component->ts.type != BT_CLASS
  1442. && !ref->u.c.component->attr.codimension
  1443. && (ref->u.c.component->attr.pointer
  1444. || ref->u.c.component->attr.allocatable)))
  1445. gfc_error ("Sorry, coindexed access to a pointer or allocatable "
  1446. "component of the coindexed coarray at %L is not yet "
  1447. "supported", &expr->where);
  1448. }
  1449. if ((!comp_ref
  1450. && ((expr->symtree->n.sym->ts.type == BT_CLASS
  1451. && CLASS_DATA (expr->symtree->n.sym)->attr.alloc_comp)
  1452. || (expr->symtree->n.sym->ts.type == BT_DERIVED
  1453. && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)))
  1454. || (comp_ref
  1455. && ((comp_ref->u.c.component->ts.type == BT_CLASS
  1456. && CLASS_DATA (comp_ref->u.c.component)->attr.alloc_comp)
  1457. || (comp_ref->u.c.component->ts.type == BT_DERIVED
  1458. && comp_ref->u.c.component->ts.u.derived->attr.alloc_comp))))
  1459. gfc_error ("Sorry, coindexed coarray at %L with allocatable component is "
  1460. "not yet supported", &expr->where);
  1461. if (expr->rank)
  1462. {
  1463. /* Without the new array descriptor, access like "caf[i]%a(:)%b" is in
  1464. general not possible as the required stride multiplier might be not
  1465. a multiple of c_sizeof(b). In case of noncoindexed access, the
  1466. scalarizer often takes care of it - for coarrays, it always fails. */
  1467. for (ref = expr->ref; ref; ref = ref->next)
  1468. if (ref->type == REF_COMPONENT
  1469. && ((ref->u.c.component->ts.type == BT_CLASS
  1470. && CLASS_DATA (ref->u.c.component)->attr.codimension)
  1471. || (ref->u.c.component->ts.type != BT_CLASS
  1472. && ref->u.c.component->attr.codimension)))
  1473. break;
  1474. if (ref == NULL)
  1475. ref = expr->ref;
  1476. for ( ; ref; ref = ref->next)
  1477. if (ref->type == REF_ARRAY && ref->u.ar.dimen)
  1478. break;
  1479. for ( ; ref; ref = ref->next)
  1480. if (ref->type == REF_COMPONENT)
  1481. gfc_error ("Sorry, coindexed access at %L to a scalar component "
  1482. "with an array partref is not yet supported",
  1483. &expr->where);
  1484. }
  1485. caf_decl = expr->symtree->n.sym->backend_decl;
  1486. gcc_assert (caf_decl);
  1487. if (expr->symtree->n.sym->ts.type == BT_CLASS)
  1488. caf_decl = gfc_class_data_get (caf_decl);
  1489. if (expr->symtree->n.sym->attr.codimension)
  1490. return caf_decl;
  1491. /* The following code assumes that the coarray is a component reachable via
  1492. only scalar components/variables; the Fortran standard guarantees this. */
  1493. for (ref = expr->ref; ref; ref = ref->next)
  1494. if (ref->type == REF_COMPONENT)
  1495. {
  1496. gfc_component *comp = ref->u.c.component;
  1497. if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
  1498. caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
  1499. caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
  1500. TREE_TYPE (comp->backend_decl), caf_decl,
  1501. comp->backend_decl, NULL_TREE);
  1502. if (comp->ts.type == BT_CLASS)
  1503. caf_decl = gfc_class_data_get (caf_decl);
  1504. if (comp->attr.codimension)
  1505. {
  1506. found = true;
  1507. break;
  1508. }
  1509. }
  1510. gcc_assert (found && caf_decl);
  1511. return caf_decl;
  1512. }
  1513. /* Obtain the Coarray token - and optionally also the offset. */
  1514. void
  1515. gfc_get_caf_token_offset (tree *token, tree *offset, tree caf_decl, tree se_expr,
  1516. gfc_expr *expr)
  1517. {
  1518. tree tmp;
  1519. /* Coarray token. */
  1520. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
  1521. {
  1522. gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
  1523. == GFC_ARRAY_ALLOCATABLE
  1524. || expr->symtree->n.sym->attr.select_type_temporary);
  1525. *token = gfc_conv_descriptor_token (caf_decl);
  1526. }
  1527. else if (DECL_LANG_SPECIFIC (caf_decl)
  1528. && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
  1529. *token = GFC_DECL_TOKEN (caf_decl);
  1530. else
  1531. {
  1532. gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
  1533. && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
  1534. *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
  1535. }
  1536. if (offset == NULL)
  1537. return;
  1538. /* Offset between the coarray base address and the address wanted. */
  1539. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
  1540. && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
  1541. || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
  1542. *offset = build_int_cst (gfc_array_index_type, 0);
  1543. else if (DECL_LANG_SPECIFIC (caf_decl)
  1544. && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
  1545. *offset = GFC_DECL_CAF_OFFSET (caf_decl);
  1546. else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
  1547. *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
  1548. else
  1549. *offset = build_int_cst (gfc_array_index_type, 0);
  1550. if (POINTER_TYPE_P (TREE_TYPE (se_expr))
  1551. && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
  1552. {
  1553. tmp = build_fold_indirect_ref_loc (input_location, se_expr);
  1554. tmp = gfc_conv_descriptor_data_get (tmp);
  1555. }
  1556. else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
  1557. tmp = gfc_conv_descriptor_data_get (se_expr);
  1558. else
  1559. {
  1560. gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
  1561. tmp = se_expr;
  1562. }
  1563. *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  1564. *offset, fold_convert (gfc_array_index_type, tmp));
  1565. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
  1566. tmp = gfc_conv_descriptor_data_get (caf_decl);
  1567. else
  1568. {
  1569. gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
  1570. tmp = caf_decl;
  1571. }
  1572. *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  1573. fold_convert (gfc_array_index_type, *offset),
  1574. fold_convert (gfc_array_index_type, tmp));
  1575. }
  1576. /* Convert the coindex of a coarray into an image index; the result is
  1577. image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
  1578. + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
  1579. tree
  1580. gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
  1581. {
  1582. gfc_ref *ref;
  1583. tree lbound, ubound, extent, tmp, img_idx;
  1584. gfc_se se;
  1585. int i;
  1586. for (ref = e->ref; ref; ref = ref->next)
  1587. if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
  1588. break;
  1589. gcc_assert (ref != NULL);
  1590. img_idx = integer_zero_node;
  1591. extent = integer_one_node;
  1592. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
  1593. for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
  1594. {
  1595. gfc_init_se (&se, NULL);
  1596. gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
  1597. gfc_add_block_to_block (block, &se.pre);
  1598. lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
  1599. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  1600. integer_type_node, se.expr,
  1601. fold_convert(integer_type_node, lbound));
  1602. tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
  1603. extent, tmp);
  1604. img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
  1605. img_idx, tmp);
  1606. if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
  1607. {
  1608. ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
  1609. tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
  1610. tmp = fold_convert (integer_type_node, tmp);
  1611. extent = fold_build2_loc (input_location, MULT_EXPR,
  1612. integer_type_node, extent, tmp);
  1613. }
  1614. }
  1615. else
  1616. for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
  1617. {
  1618. gfc_init_se (&se, NULL);
  1619. gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
  1620. gfc_add_block_to_block (block, &se.pre);
  1621. lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
  1622. lbound = fold_convert (integer_type_node, lbound);
  1623. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  1624. integer_type_node, se.expr, lbound);
  1625. tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
  1626. extent, tmp);
  1627. img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
  1628. img_idx, tmp);
  1629. if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
  1630. {
  1631. ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
  1632. ubound = fold_convert (integer_type_node, ubound);
  1633. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  1634. integer_type_node, ubound, lbound);
  1635. tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
  1636. tmp, integer_one_node);
  1637. extent = fold_build2_loc (input_location, MULT_EXPR,
  1638. integer_type_node, extent, tmp);
  1639. }
  1640. }
  1641. img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
  1642. img_idx, integer_one_node);
  1643. return img_idx;
  1644. }
  1645. /* For each character array constructor subexpression without a ts.u.cl->length,
  1646. replace it by its first element (if there aren't any elements, the length
  1647. should already be set to zero). */
  1648. static void
  1649. flatten_array_ctors_without_strlen (gfc_expr* e)
  1650. {
  1651. gfc_actual_arglist* arg;
  1652. gfc_constructor* c;
  1653. if (!e)
  1654. return;
  1655. switch (e->expr_type)
  1656. {
  1657. case EXPR_OP:
  1658. flatten_array_ctors_without_strlen (e->value.op.op1);
  1659. flatten_array_ctors_without_strlen (e->value.op.op2);
  1660. break;
  1661. case EXPR_COMPCALL:
  1662. /* TODO: Implement as with EXPR_FUNCTION when needed. */
  1663. gcc_unreachable ();
  1664. case EXPR_FUNCTION:
  1665. for (arg = e->value.function.actual; arg; arg = arg->next)
  1666. flatten_array_ctors_without_strlen (arg->expr);
  1667. break;
  1668. case EXPR_ARRAY:
  1669. /* We've found what we're looking for. */
  1670. if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
  1671. {
  1672. gfc_constructor *c;
  1673. gfc_expr* new_expr;
  1674. gcc_assert (e->value.constructor);
  1675. c = gfc_constructor_first (e->value.constructor);
  1676. new_expr = c->expr;
  1677. c->expr = NULL;
  1678. flatten_array_ctors_without_strlen (new_expr);
  1679. gfc_replace_expr (e, new_expr);
  1680. break;
  1681. }
  1682. /* Otherwise, fall through to handle constructor elements. */
  1683. case EXPR_STRUCTURE:
  1684. for (c = gfc_constructor_first (e->value.constructor);
  1685. c; c = gfc_constructor_next (c))
  1686. flatten_array_ctors_without_strlen (c->expr);
  1687. break;
  1688. default:
  1689. break;
  1690. }
  1691. }
  1692. /* Generate code to initialize a string length variable. Returns the
  1693. value. For array constructors, cl->length might be NULL and in this case,
  1694. the first element of the constructor is needed. expr is the original
  1695. expression so we can access it but can be NULL if this is not needed. */
  1696. void
  1697. gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
  1698. {
  1699. gfc_se se;
  1700. gfc_init_se (&se, NULL);
  1701. if (!cl->length
  1702. && cl->backend_decl
  1703. && TREE_CODE (cl->backend_decl) == VAR_DECL)
  1704. return;
  1705. /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
  1706. "flatten" array constructors by taking their first element; all elements
  1707. should be the same length or a cl->length should be present. */
  1708. if (!cl->length)
  1709. {
  1710. gfc_expr* expr_flat;
  1711. gcc_assert (expr);
  1712. expr_flat = gfc_copy_expr (expr);
  1713. flatten_array_ctors_without_strlen (expr_flat);
  1714. gfc_resolve_expr (expr_flat);
  1715. gfc_conv_expr (&se, expr_flat);
  1716. gfc_add_block_to_block (pblock, &se.pre);
  1717. cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
  1718. gfc_free_expr (expr_flat);
  1719. return;
  1720. }
  1721. /* Convert cl->length. */
  1722. gcc_assert (cl->length);
  1723. gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
  1724. se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
  1725. se.expr, build_int_cst (gfc_charlen_type_node, 0));
  1726. gfc_add_block_to_block (pblock, &se.pre);
  1727. if (cl->backend_decl)
  1728. gfc_add_modify (pblock, cl->backend_decl, se.expr);
  1729. else
  1730. cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
  1731. }
  1732. static void
  1733. gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
  1734. const char *name, locus *where)
  1735. {
  1736. tree tmp;
  1737. tree type;
  1738. tree fault;
  1739. gfc_se start;
  1740. gfc_se end;
  1741. char *msg;
  1742. mpz_t length;
  1743. type = gfc_get_character_type (kind, ref->u.ss.length);
  1744. type = build_pointer_type (type);
  1745. gfc_init_se (&start, se);
  1746. gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
  1747. gfc_add_block_to_block (&se->pre, &start.pre);
  1748. if (integer_onep (start.expr))
  1749. gfc_conv_string_parameter (se);
  1750. else
  1751. {
  1752. tmp = start.expr;
  1753. STRIP_NOPS (tmp);
  1754. /* Avoid multiple evaluation of substring start. */
  1755. if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
  1756. start.expr = gfc_evaluate_now (start.expr, &se->pre);
  1757. /* Change the start of the string. */
  1758. if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
  1759. tmp = se->expr;
  1760. else
  1761. tmp = build_fold_indirect_ref_loc (input_location,
  1762. se->expr);
  1763. tmp = gfc_build_array_ref (tmp, start.expr, NULL);
  1764. se->expr = gfc_build_addr_expr (type, tmp);
  1765. }
  1766. /* Length = end + 1 - start. */
  1767. gfc_init_se (&end, se);
  1768. if (ref->u.ss.end == NULL)
  1769. end.expr = se->string_length;
  1770. else
  1771. {
  1772. gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
  1773. gfc_add_block_to_block (&se->pre, &end.pre);
  1774. }
  1775. tmp = end.expr;
  1776. STRIP_NOPS (tmp);
  1777. if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
  1778. end.expr = gfc_evaluate_now (end.expr, &se->pre);
  1779. if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
  1780. {
  1781. tree nonempty = fold_build2_loc (input_location, LE_EXPR,
  1782. boolean_type_node, start.expr,
  1783. end.expr);
  1784. /* Check lower bound. */
  1785. fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
  1786. start.expr,
  1787. build_int_cst (gfc_charlen_type_node, 1));
  1788. fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
  1789. boolean_type_node, nonempty, fault);
  1790. if (name)
  1791. msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
  1792. "is less than one", name);
  1793. else
  1794. msg = xasprintf ("Substring out of bounds: lower bound (%%ld)"
  1795. "is less than one");
  1796. gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
  1797. fold_convert (long_integer_type_node,
  1798. start.expr));
  1799. free (msg);
  1800. /* Check upper bound. */
  1801. fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
  1802. end.expr, se->string_length);
  1803. fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
  1804. boolean_type_node, nonempty, fault);
  1805. if (name)
  1806. msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
  1807. "exceeds string length (%%ld)", name);
  1808. else
  1809. msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
  1810. "exceeds string length (%%ld)");
  1811. gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
  1812. fold_convert (long_integer_type_node, end.expr),
  1813. fold_convert (long_integer_type_node,
  1814. se->string_length));
  1815. free (msg);
  1816. }
  1817. /* Try to calculate the length from the start and end expressions. */
  1818. if (ref->u.ss.end
  1819. && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
  1820. {
  1821. int i_len;
  1822. i_len = mpz_get_si (length) + 1;
  1823. if (i_len < 0)
  1824. i_len = 0;
  1825. tmp = build_int_cst (gfc_charlen_type_node, i_len);
  1826. mpz_clear (length); /* Was initialized by gfc_dep_difference. */
  1827. }
  1828. else
  1829. {
  1830. tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
  1831. end.expr, start.expr);
  1832. tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
  1833. build_int_cst (gfc_charlen_type_node, 1), tmp);
  1834. tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
  1835. tmp, build_int_cst (gfc_charlen_type_node, 0));
  1836. }
  1837. se->string_length = tmp;
  1838. }
  1839. /* Convert a derived type component reference. */
  1840. static void
  1841. gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
  1842. {
  1843. gfc_component *c;
  1844. tree tmp;
  1845. tree decl;
  1846. tree field;
  1847. c = ref->u.c.component;
  1848. if (c->backend_decl == NULL_TREE
  1849. && ref->u.c.sym != NULL)
  1850. gfc_get_derived_type (ref->u.c.sym);
  1851. field = c->backend_decl;
  1852. gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
  1853. decl = se->expr;
  1854. /* Components can correspond to fields of different containing
  1855. types, as components are created without context, whereas
  1856. a concrete use of a component has the type of decl as context.
  1857. So, if the type doesn't match, we search the corresponding
  1858. FIELD_DECL in the parent type. To not waste too much time
  1859. we cache this result in norestrict_decl. */
  1860. if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
  1861. {
  1862. tree f2 = c->norestrict_decl;
  1863. if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
  1864. for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
  1865. if (TREE_CODE (f2) == FIELD_DECL
  1866. && DECL_NAME (f2) == DECL_NAME (field))
  1867. break;
  1868. gcc_assert (f2);
  1869. c->norestrict_decl = f2;
  1870. field = f2;
  1871. }
  1872. tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
  1873. decl, field, NULL_TREE);
  1874. se->expr = tmp;
  1875. /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
  1876. strlen () conditional below. */
  1877. if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
  1878. && !(c->attr.allocatable && c->ts.deferred))
  1879. {
  1880. tmp = c->ts.u.cl->backend_decl;
  1881. /* Components must always be constant length. */
  1882. gcc_assert (tmp && INTEGER_CST_P (tmp));
  1883. se->string_length = tmp;
  1884. }
  1885. if (gfc_deferred_strlen (c, &field))
  1886. {
  1887. tmp = fold_build3_loc (input_location, COMPONENT_REF,
  1888. TREE_TYPE (field),
  1889. decl, field, NULL_TREE);
  1890. se->string_length = tmp;
  1891. }
  1892. if (((c->attr.pointer || c->attr.allocatable)
  1893. && (!c->attr.dimension && !c->attr.codimension)
  1894. && c->ts.type != BT_CHARACTER)
  1895. || c->attr.proc_pointer)
  1896. se->expr = build_fold_indirect_ref_loc (input_location,
  1897. se->expr);
  1898. }
  1899. /* This function deals with component references to components of the
  1900. parent type for derived type extensions. */
  1901. static void
  1902. conv_parent_component_references (gfc_se * se, gfc_ref * ref)
  1903. {
  1904. gfc_component *c;
  1905. gfc_component *cmp;
  1906. gfc_symbol *dt;
  1907. gfc_ref parent;
  1908. dt = ref->u.c.sym;
  1909. c = ref->u.c.component;
  1910. /* Return if the component is in the parent type. */
  1911. for (cmp = dt->components; cmp; cmp = cmp->next)
  1912. if (strcmp (c->name, cmp->name) == 0)
  1913. return;
  1914. /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
  1915. parent.type = REF_COMPONENT;
  1916. parent.next = NULL;
  1917. parent.u.c.sym = dt;
  1918. parent.u.c.component = dt->components;
  1919. if (dt->backend_decl == NULL)
  1920. gfc_get_derived_type (dt);
  1921. /* Build the reference and call self. */
  1922. gfc_conv_component_ref (se, &parent);
  1923. parent.u.c.sym = dt->components->ts.u.derived;
  1924. parent.u.c.component = c;
  1925. conv_parent_component_references (se, &parent);
  1926. }
  1927. /* Return the contents of a variable. Also handles reference/pointer
  1928. variables (all Fortran pointer references are implicit). */
  1929. static void
  1930. gfc_conv_variable (gfc_se * se, gfc_expr * expr)
  1931. {
  1932. gfc_ss *ss;
  1933. gfc_ref *ref;
  1934. gfc_symbol *sym;
  1935. tree parent_decl = NULL_TREE;
  1936. int parent_flag;
  1937. bool return_value;
  1938. bool alternate_entry;
  1939. bool entry_master;
  1940. sym = expr->symtree->n.sym;
  1941. ss = se->ss;
  1942. if (ss != NULL)
  1943. {
  1944. gfc_ss_info *ss_info = ss->info;
  1945. /* Check that something hasn't gone horribly wrong. */
  1946. gcc_assert (ss != gfc_ss_terminator);
  1947. gcc_assert (ss_info->expr == expr);
  1948. /* A scalarized term. We already know the descriptor. */
  1949. se->expr = ss_info->data.array.descriptor;
  1950. se->string_length = ss_info->string_length;
  1951. ref = ss_info->data.array.ref;
  1952. if (ref)
  1953. gcc_assert (ref->type == REF_ARRAY
  1954. && ref->u.ar.type != AR_ELEMENT);
  1955. else
  1956. gfc_conv_tmp_array_ref (se);
  1957. }
  1958. else
  1959. {
  1960. tree se_expr = NULL_TREE;
  1961. se->expr = gfc_get_symbol_decl (sym);
  1962. /* Deal with references to a parent results or entries by storing
  1963. the current_function_decl and moving to the parent_decl. */
  1964. return_value = sym->attr.function && sym->result == sym;
  1965. alternate_entry = sym->attr.function && sym->attr.entry
  1966. && sym->result == sym;
  1967. entry_master = sym->attr.result
  1968. && sym->ns->proc_name->attr.entry_master
  1969. && !gfc_return_by_reference (sym->ns->proc_name);
  1970. if (current_function_decl)
  1971. parent_decl = DECL_CONTEXT (current_function_decl);
  1972. if ((se->expr == parent_decl && return_value)
  1973. || (sym->ns && sym->ns->proc_name
  1974. && parent_decl
  1975. && sym->ns->proc_name->backend_decl == parent_decl
  1976. && (alternate_entry || entry_master)))
  1977. parent_flag = 1;
  1978. else
  1979. parent_flag = 0;
  1980. /* Special case for assigning the return value of a function.
  1981. Self recursive functions must have an explicit return value. */
  1982. if (return_value && (se->expr == current_function_decl || parent_flag))
  1983. se_expr = gfc_get_fake_result_decl (sym, parent_flag);
  1984. /* Similarly for alternate entry points. */
  1985. else if (alternate_entry
  1986. && (sym->ns->proc_name->backend_decl == current_function_decl
  1987. || parent_flag))
  1988. {
  1989. gfc_entry_list *el = NULL;
  1990. for (el = sym->ns->entries; el; el = el->next)
  1991. if (sym == el->sym)
  1992. {
  1993. se_expr = gfc_get_fake_result_decl (sym, parent_flag);
  1994. break;
  1995. }
  1996. }
  1997. else if (entry_master
  1998. && (sym->ns->proc_name->backend_decl == current_function_decl
  1999. || parent_flag))
  2000. se_expr = gfc_get_fake_result_decl (sym, parent_flag);
  2001. if (se_expr)
  2002. se->expr = se_expr;
  2003. /* Procedure actual arguments. */
  2004. else if (sym->attr.flavor == FL_PROCEDURE
  2005. && se->expr != current_function_decl)
  2006. {
  2007. if (!sym->attr.dummy && !sym->attr.proc_pointer)
  2008. {
  2009. gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
  2010. se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
  2011. }
  2012. return;
  2013. }
  2014. /* Dereference the expression, where needed. Since characters
  2015. are entirely different from other types, they are treated
  2016. separately. */
  2017. if (sym->ts.type == BT_CHARACTER)
  2018. {
  2019. /* Dereference character pointer dummy arguments
  2020. or results. */
  2021. if ((sym->attr.pointer || sym->attr.allocatable)
  2022. && (sym->attr.dummy
  2023. || sym->attr.function
  2024. || sym->attr.result))
  2025. se->expr = build_fold_indirect_ref_loc (input_location,
  2026. se->expr);
  2027. }
  2028. else if (!sym->attr.value)
  2029. {
  2030. /* Dereference non-character scalar dummy arguments. */
  2031. if (sym->attr.dummy && !sym->attr.dimension
  2032. && !(sym->attr.codimension && sym->attr.allocatable))
  2033. se->expr = build_fold_indirect_ref_loc (input_location,
  2034. se->expr);
  2035. /* Dereference scalar hidden result. */
  2036. if (flag_f2c && sym->ts.type == BT_COMPLEX
  2037. && (sym->attr.function || sym->attr.result)
  2038. && !sym->attr.dimension && !sym->attr.pointer
  2039. && !sym->attr.always_explicit)
  2040. se->expr = build_fold_indirect_ref_loc (input_location,
  2041. se->expr);
  2042. /* Dereference non-character pointer variables.
  2043. These must be dummies, results, or scalars. */
  2044. if ((sym->attr.pointer || sym->attr.allocatable
  2045. || gfc_is_associate_pointer (sym)
  2046. || (sym->as && sym->as->type == AS_ASSUMED_RANK))
  2047. && (sym->attr.dummy
  2048. || sym->attr.function
  2049. || sym->attr.result
  2050. || (!sym->attr.dimension
  2051. && (!sym->attr.codimension || !sym->attr.allocatable))))
  2052. se->expr = build_fold_indirect_ref_loc (input_location,
  2053. se->expr);
  2054. }
  2055. ref = expr->ref;
  2056. }
  2057. /* For character variables, also get the length. */
  2058. if (sym->ts.type == BT_CHARACTER)
  2059. {
  2060. /* If the character length of an entry isn't set, get the length from
  2061. the master function instead. */
  2062. if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
  2063. se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
  2064. else
  2065. se->string_length = sym->ts.u.cl->backend_decl;
  2066. gcc_assert (se->string_length);
  2067. }
  2068. while (ref)
  2069. {
  2070. switch (ref->type)
  2071. {
  2072. case REF_ARRAY:
  2073. /* Return the descriptor if that's what we want and this is an array
  2074. section reference. */
  2075. if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
  2076. return;
  2077. /* TODO: Pointers to single elements of array sections, eg elemental subs. */
  2078. /* Return the descriptor for array pointers and allocations. */
  2079. if (se->want_pointer
  2080. && ref->next == NULL && (se->descriptor_only))
  2081. return;
  2082. gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
  2083. /* Return a pointer to an element. */
  2084. break;
  2085. case REF_COMPONENT:
  2086. if (ref->u.c.sym->attr.extension)
  2087. conv_parent_component_references (se, ref);
  2088. gfc_conv_component_ref (se, ref);
  2089. if (!ref->next && ref->u.c.sym->attr.codimension
  2090. && se->want_pointer && se->descriptor_only)
  2091. return;
  2092. break;
  2093. case REF_SUBSTRING:
  2094. gfc_conv_substring (se, ref, expr->ts.kind,
  2095. expr->symtree->name, &expr->where);
  2096. break;
  2097. default:
  2098. gcc_unreachable ();
  2099. break;
  2100. }
  2101. ref = ref->next;
  2102. }
  2103. /* Pointer assignment, allocation or pass by reference. Arrays are handled
  2104. separately. */
  2105. if (se->want_pointer)
  2106. {
  2107. if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
  2108. gfc_conv_string_parameter (se);
  2109. else
  2110. se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
  2111. }
  2112. }
  2113. /* Unary ops are easy... Or they would be if ! was a valid op. */
  2114. static void
  2115. gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
  2116. {
  2117. gfc_se operand;
  2118. tree type;
  2119. gcc_assert (expr->ts.type != BT_CHARACTER);
  2120. /* Initialize the operand. */
  2121. gfc_init_se (&operand, se);
  2122. gfc_conv_expr_val (&operand, expr->value.op.op1);
  2123. gfc_add_block_to_block (&se->pre, &operand.pre);
  2124. type = gfc_typenode_for_spec (&expr->ts);
  2125. /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
  2126. We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
  2127. All other unary operators have an equivalent GIMPLE unary operator. */
  2128. if (code == TRUTH_NOT_EXPR)
  2129. se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
  2130. build_int_cst (type, 0));
  2131. else
  2132. se->expr = fold_build1_loc (input_location, code, type, operand.expr);
  2133. }
  2134. /* Expand power operator to optimal multiplications when a value is raised
  2135. to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
  2136. Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
  2137. Programming", 3rd Edition, 1998. */
  2138. /* This code is mostly duplicated from expand_powi in the backend.
  2139. We establish the "optimal power tree" lookup table with the defined size.
  2140. The items in the table are the exponents used to calculate the index
  2141. exponents. Any integer n less than the value can get an "addition chain",
  2142. with the first node being one. */
  2143. #define POWI_TABLE_SIZE 256
  2144. /* The table is from builtins.c. */
  2145. static const unsigned char powi_table[POWI_TABLE_SIZE] =
  2146. {
  2147. 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
  2148. 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
  2149. 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
  2150. 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
  2151. 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
  2152. 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
  2153. 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
  2154. 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
  2155. 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
  2156. 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
  2157. 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
  2158. 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
  2159. 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
  2160. 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
  2161. 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
  2162. 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
  2163. 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
  2164. 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
  2165. 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
  2166. 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
  2167. 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
  2168. 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
  2169. 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
  2170. 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
  2171. 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
  2172. 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
  2173. 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
  2174. 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
  2175. 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
  2176. 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
  2177. 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
  2178. 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
  2179. };
  2180. /* If n is larger than lookup table's max index, we use the "window
  2181. method". */
  2182. #define POWI_WINDOW_SIZE 3
  2183. /* Recursive function to expand the power operator. The temporary
  2184. values are put in tmpvar. The function returns tmpvar[1] ** n. */
  2185. static tree
  2186. gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
  2187. {
  2188. tree op0;
  2189. tree op1;
  2190. tree tmp;
  2191. int digit;
  2192. if (n < POWI_TABLE_SIZE)
  2193. {
  2194. if (tmpvar[n])
  2195. return tmpvar[n];
  2196. op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
  2197. op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
  2198. }
  2199. else if (n & 1)
  2200. {
  2201. digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
  2202. op0 = gfc_conv_powi (se, n - digit, tmpvar);
  2203. op1 = gfc_conv_powi (se, digit, tmpvar);
  2204. }
  2205. else
  2206. {
  2207. op0 = gfc_conv_powi (se, n >> 1, tmpvar);
  2208. op1 = op0;
  2209. }
  2210. tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
  2211. tmp = gfc_evaluate_now (tmp, &se->pre);
  2212. if (n < POWI_TABLE_SIZE)
  2213. tmpvar[n] = tmp;
  2214. return tmp;
  2215. }
  2216. /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
  2217. return 1. Else return 0 and a call to runtime library functions
  2218. will have to be built. */
  2219. static int
  2220. gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
  2221. {
  2222. tree cond;
  2223. tree tmp;
  2224. tree type;
  2225. tree vartmp[POWI_TABLE_SIZE];
  2226. HOST_WIDE_INT m;
  2227. unsigned HOST_WIDE_INT n;
  2228. int sgn;
  2229. wide_int wrhs = rhs;
  2230. /* If exponent is too large, we won't expand it anyway, so don't bother
  2231. with large integer values. */
  2232. if (!wi::fits_shwi_p (wrhs))
  2233. return 0;
  2234. m = wrhs.to_shwi ();
  2235. /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
  2236. of the asymmetric range of the integer type. */
  2237. n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
  2238. type = TREE_TYPE (lhs);
  2239. sgn = tree_int_cst_sgn (rhs);
  2240. if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
  2241. || optimize_size) && (m > 2 || m < -1))
  2242. return 0;
  2243. /* rhs == 0 */
  2244. if (sgn == 0)
  2245. {
  2246. se->expr = gfc_build_const (type, integer_one_node);
  2247. return 1;
  2248. }
  2249. /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
  2250. if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
  2251. {
  2252. tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  2253. lhs, build_int_cst (TREE_TYPE (lhs), -1));
  2254. cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  2255. lhs, build_int_cst (TREE_TYPE (lhs), 1));
  2256. /* If rhs is even,
  2257. result = (lhs == 1 || lhs == -1) ? 1 : 0. */
  2258. if ((n & 1) == 0)
  2259. {
  2260. tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
  2261. boolean_type_node, tmp, cond);
  2262. se->expr = fold_build3_loc (input_location, COND_EXPR, type,
  2263. tmp, build_int_cst (type, 1),
  2264. build_int_cst (type, 0));
  2265. return 1;
  2266. }
  2267. /* If rhs is odd,
  2268. result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
  2269. tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
  2270. build_int_cst (type, -1),
  2271. build_int_cst (type, 0));
  2272. se->expr = fold_build3_loc (input_location, COND_EXPR, type,
  2273. cond, build_int_cst (type, 1), tmp);
  2274. return 1;
  2275. }
  2276. memset (vartmp, 0, sizeof (vartmp));
  2277. vartmp[1] = lhs;
  2278. if (sgn == -1)
  2279. {
  2280. tmp = gfc_build_const (type, integer_one_node);
  2281. vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
  2282. vartmp[1]);
  2283. }
  2284. se->expr = gfc_conv_powi (se, n, vartmp);
  2285. return 1;
  2286. }
  2287. /* Power op (**). Constant integer exponent has special handling. */
  2288. static void
  2289. gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
  2290. {
  2291. tree gfc_int4_type_node;
  2292. int kind;
  2293. int ikind;
  2294. int res_ikind_1, res_ikind_2;
  2295. gfc_se lse;
  2296. gfc_se rse;
  2297. tree fndecl = NULL;
  2298. gfc_init_se (&lse, se);
  2299. gfc_conv_expr_val (&lse, expr->value.op.op1);
  2300. lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
  2301. gfc_add_block_to_block (&se->pre, &lse.pre);
  2302. gfc_init_se (&rse, se);
  2303. gfc_conv_expr_val (&rse, expr->value.op.op2);
  2304. gfc_add_block_to_block (&se->pre, &rse.pre);
  2305. if (expr->value.op.op2->ts.type == BT_INTEGER
  2306. && expr->value.op.op2->expr_type == EXPR_CONSTANT)
  2307. if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
  2308. return;
  2309. gfc_int4_type_node = gfc_get_int_type (4);
  2310. /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
  2311. library routine. But in the end, we have to convert the result back
  2312. if this case applies -- with res_ikind_K, we keep track whether operand K
  2313. falls into this case. */
  2314. res_ikind_1 = -1;
  2315. res_ikind_2 = -1;
  2316. kind = expr->value.op.op1->ts.kind;
  2317. switch (expr->value.op.op2->ts.type)
  2318. {
  2319. case BT_INTEGER:
  2320. ikind = expr->value.op.op2->ts.kind;
  2321. switch (ikind)
  2322. {
  2323. case 1:
  2324. case 2:
  2325. rse.expr = convert (gfc_int4_type_node, rse.expr);
  2326. res_ikind_2 = ikind;
  2327. /* Fall through. */
  2328. case 4:
  2329. ikind = 0;
  2330. break;
  2331. case 8:
  2332. ikind = 1;
  2333. break;
  2334. case 16:
  2335. ikind = 2;
  2336. break;
  2337. default:
  2338. gcc_unreachable ();
  2339. }
  2340. switch (kind)
  2341. {
  2342. case 1:
  2343. case 2:
  2344. if (expr->value.op.op1->ts.type == BT_INTEGER)
  2345. {
  2346. lse.expr = convert (gfc_int4_type_node, lse.expr);
  2347. res_ikind_1 = kind;
  2348. }
  2349. else
  2350. gcc_unreachable ();
  2351. /* Fall through. */
  2352. case 4:
  2353. kind = 0;
  2354. break;
  2355. case 8:
  2356. kind = 1;
  2357. break;
  2358. case 10:
  2359. kind = 2;
  2360. break;
  2361. case 16:
  2362. kind = 3;
  2363. break;
  2364. default:
  2365. gcc_unreachable ();
  2366. }
  2367. switch (expr->value.op.op1->ts.type)
  2368. {
  2369. case BT_INTEGER:
  2370. if (kind == 3) /* Case 16 was not handled properly above. */
  2371. kind = 2;
  2372. fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
  2373. break;
  2374. case BT_REAL:
  2375. /* Use builtins for real ** int4. */
  2376. if (ikind == 0)
  2377. {
  2378. switch (kind)
  2379. {
  2380. case 0:
  2381. fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
  2382. break;
  2383. case 1:
  2384. fndecl = builtin_decl_explicit (BUILT_IN_POWI);
  2385. break;
  2386. case 2:
  2387. fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
  2388. break;
  2389. case 3:
  2390. /* Use the __builtin_powil() only if real(kind=16) is
  2391. actually the C long double type. */
  2392. if (!gfc_real16_is_float128)
  2393. fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
  2394. break;
  2395. default:
  2396. gcc_unreachable ();
  2397. }
  2398. }
  2399. /* If we don't have a good builtin for this, go for the
  2400. library function. */
  2401. if (!fndecl)
  2402. fndecl = gfor_fndecl_math_powi[kind][ikind].real;
  2403. break;
  2404. case BT_COMPLEX:
  2405. fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
  2406. break;
  2407. default:
  2408. gcc_unreachable ();
  2409. }
  2410. break;
  2411. case BT_REAL:
  2412. fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
  2413. break;
  2414. case BT_COMPLEX:
  2415. fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
  2416. break;
  2417. default:
  2418. gcc_unreachable ();
  2419. break;
  2420. }
  2421. se->expr = build_call_expr_loc (input_location,
  2422. fndecl, 2, lse.expr, rse.expr);
  2423. /* Convert the result back if it is of wrong integer kind. */
  2424. if (res_ikind_1 != -1 && res_ikind_2 != -1)
  2425. {
  2426. /* We want the maximum of both operand kinds as result. */
  2427. if (res_ikind_1 < res_ikind_2)
  2428. res_ikind_1 = res_ikind_2;
  2429. se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
  2430. }
  2431. }
  2432. /* Generate code to allocate a string temporary. */
  2433. tree
  2434. gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
  2435. {
  2436. tree var;
  2437. tree tmp;
  2438. if (gfc_can_put_var_on_stack (len))
  2439. {
  2440. /* Create a temporary variable to hold the result. */
  2441. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  2442. gfc_charlen_type_node, len,
  2443. build_int_cst (gfc_charlen_type_node, 1));
  2444. tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
  2445. if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
  2446. tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
  2447. else
  2448. tmp = build_array_type (TREE_TYPE (type), tmp);
  2449. var = gfc_create_var (tmp, "str");
  2450. var = gfc_build_addr_expr (type, var);
  2451. }
  2452. else
  2453. {
  2454. /* Allocate a temporary to hold the result. */
  2455. var = gfc_create_var (type, "pstr");
  2456. gcc_assert (POINTER_TYPE_P (type));
  2457. tmp = TREE_TYPE (type);
  2458. if (TREE_CODE (tmp) == ARRAY_TYPE)
  2459. tmp = TREE_TYPE (tmp);
  2460. tmp = TYPE_SIZE_UNIT (tmp);
  2461. tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
  2462. fold_convert (size_type_node, len),
  2463. fold_convert (size_type_node, tmp));
  2464. tmp = gfc_call_malloc (&se->pre, type, tmp);
  2465. gfc_add_modify (&se->pre, var, tmp);
  2466. /* Free the temporary afterwards. */
  2467. tmp = gfc_call_free (convert (pvoid_type_node, var));
  2468. gfc_add_expr_to_block (&se->post, tmp);
  2469. }
  2470. return var;
  2471. }
  2472. /* Handle a string concatenation operation. A temporary will be allocated to
  2473. hold the result. */
  2474. static void
  2475. gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
  2476. {
  2477. gfc_se lse, rse;
  2478. tree len, type, var, tmp, fndecl;
  2479. gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
  2480. && expr->value.op.op2->ts.type == BT_CHARACTER);
  2481. gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
  2482. gfc_init_se (&lse, se);
  2483. gfc_conv_expr (&lse, expr->value.op.op1);
  2484. gfc_conv_string_parameter (&lse);
  2485. gfc_init_se (&rse, se);
  2486. gfc_conv_expr (&rse, expr->value.op.op2);
  2487. gfc_conv_string_parameter (&rse);
  2488. gfc_add_block_to_block (&se->pre, &lse.pre);
  2489. gfc_add_block_to_block (&se->pre, &rse.pre);
  2490. type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
  2491. len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
  2492. if (len == NULL_TREE)
  2493. {
  2494. len = fold_build2_loc (input_location, PLUS_EXPR,
  2495. TREE_TYPE (lse.string_length),
  2496. lse.string_length, rse.string_length);
  2497. }
  2498. type = build_pointer_type (type);
  2499. var = gfc_conv_string_tmp (se, type, len);
  2500. /* Do the actual concatenation. */
  2501. if (expr->ts.kind == 1)
  2502. fndecl = gfor_fndecl_concat_string;
  2503. else if (expr->ts.kind == 4)
  2504. fndecl = gfor_fndecl_concat_string_char4;
  2505. else
  2506. gcc_unreachable ();
  2507. tmp = build_call_expr_loc (input_location,
  2508. fndecl, 6, len, var, lse.string_length, lse.expr,
  2509. rse.string_length, rse.expr);
  2510. gfc_add_expr_to_block (&se->pre, tmp);
  2511. /* Add the cleanup for the operands. */
  2512. gfc_add_block_to_block (&se->pre, &rse.post);
  2513. gfc_add_block_to_block (&se->pre, &lse.post);
  2514. se->expr = var;
  2515. se->string_length = len;
  2516. }
  2517. /* Translates an op expression. Common (binary) cases are handled by this
  2518. function, others are passed on. Recursion is used in either case.
  2519. We use the fact that (op1.ts == op2.ts) (except for the power
  2520. operator **).
  2521. Operators need no special handling for scalarized expressions as long as
  2522. they call gfc_conv_simple_val to get their operands.
  2523. Character strings get special handling. */
  2524. static void
  2525. gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
  2526. {
  2527. enum tree_code code;
  2528. gfc_se lse;
  2529. gfc_se rse;
  2530. tree tmp, type;
  2531. int lop;
  2532. int checkstring;
  2533. checkstring = 0;
  2534. lop = 0;
  2535. switch (expr->value.op.op)
  2536. {
  2537. case INTRINSIC_PARENTHESES:
  2538. if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
  2539. && flag_protect_parens)
  2540. {
  2541. gfc_conv_unary_op (PAREN_EXPR, se, expr);
  2542. gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
  2543. return;
  2544. }
  2545. /* Fallthrough. */
  2546. case INTRINSIC_UPLUS:
  2547. gfc_conv_expr (se, expr->value.op.op1);
  2548. return;
  2549. case INTRINSIC_UMINUS:
  2550. gfc_conv_unary_op (NEGATE_EXPR, se, expr);
  2551. return;
  2552. case INTRINSIC_NOT:
  2553. gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
  2554. return;
  2555. case INTRINSIC_PLUS:
  2556. code = PLUS_EXPR;
  2557. break;
  2558. case INTRINSIC_MINUS:
  2559. code = MINUS_EXPR;
  2560. break;
  2561. case INTRINSIC_TIMES:
  2562. code = MULT_EXPR;
  2563. break;
  2564. case INTRINSIC_DIVIDE:
  2565. /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
  2566. an integer, we must round towards zero, so we use a
  2567. TRUNC_DIV_EXPR. */
  2568. if (expr->ts.type == BT_INTEGER)
  2569. code = TRUNC_DIV_EXPR;
  2570. else
  2571. code = RDIV_EXPR;
  2572. break;
  2573. case INTRINSIC_POWER:
  2574. gfc_conv_power_op (se, expr);
  2575. return;
  2576. case INTRINSIC_CONCAT:
  2577. gfc_conv_concat_op (se, expr);
  2578. return;
  2579. case INTRINSIC_AND:
  2580. code = TRUTH_ANDIF_EXPR;
  2581. lop = 1;
  2582. break;
  2583. case INTRINSIC_OR:
  2584. code = TRUTH_ORIF_EXPR;
  2585. lop = 1;
  2586. break;
  2587. /* EQV and NEQV only work on logicals, but since we represent them
  2588. as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
  2589. case INTRINSIC_EQ:
  2590. case INTRINSIC_EQ_OS:
  2591. case INTRINSIC_EQV:
  2592. code = EQ_EXPR;
  2593. checkstring = 1;
  2594. lop = 1;
  2595. break;
  2596. case INTRINSIC_NE:
  2597. case INTRINSIC_NE_OS:
  2598. case INTRINSIC_NEQV:
  2599. code = NE_EXPR;
  2600. checkstring = 1;
  2601. lop = 1;
  2602. break;
  2603. case INTRINSIC_GT:
  2604. case INTRINSIC_GT_OS:
  2605. code = GT_EXPR;
  2606. checkstring = 1;
  2607. lop = 1;
  2608. break;
  2609. case INTRINSIC_GE:
  2610. case INTRINSIC_GE_OS:
  2611. code = GE_EXPR;
  2612. checkstring = 1;
  2613. lop = 1;
  2614. break;
  2615. case INTRINSIC_LT:
  2616. case INTRINSIC_LT_OS:
  2617. code = LT_EXPR;
  2618. checkstring = 1;
  2619. lop = 1;
  2620. break;
  2621. case INTRINSIC_LE:
  2622. case INTRINSIC_LE_OS:
  2623. code = LE_EXPR;
  2624. checkstring = 1;
  2625. lop = 1;
  2626. break;
  2627. case INTRINSIC_USER:
  2628. case INTRINSIC_ASSIGN:
  2629. /* These should be converted into function calls by the frontend. */
  2630. gcc_unreachable ();
  2631. default:
  2632. fatal_error (input_location, "Unknown intrinsic op");
  2633. return;
  2634. }
  2635. /* The only exception to this is **, which is handled separately anyway. */
  2636. gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
  2637. if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
  2638. checkstring = 0;
  2639. /* lhs */
  2640. gfc_init_se (&lse, se);
  2641. gfc_conv_expr (&lse, expr->value.op.op1);
  2642. gfc_add_block_to_block (&se->pre, &lse.pre);
  2643. /* rhs */
  2644. gfc_init_se (&rse, se);
  2645. gfc_conv_expr (&rse, expr->value.op.op2);
  2646. gfc_add_block_to_block (&se->pre, &rse.pre);
  2647. if (checkstring)
  2648. {
  2649. gfc_conv_string_parameter (&lse);
  2650. gfc_conv_string_parameter (&rse);
  2651. lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
  2652. rse.string_length, rse.expr,
  2653. expr->value.op.op1->ts.kind,
  2654. code);
  2655. rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
  2656. gfc_add_block_to_block (&lse.post, &rse.post);
  2657. }
  2658. type = gfc_typenode_for_spec (&expr->ts);
  2659. if (lop)
  2660. {
  2661. /* The result of logical ops is always boolean_type_node. */
  2662. tmp = fold_build2_loc (input_location, code, boolean_type_node,
  2663. lse.expr, rse.expr);
  2664. se->expr = convert (type, tmp);
  2665. }
  2666. else
  2667. se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
  2668. /* Add the post blocks. */
  2669. gfc_add_block_to_block (&se->post, &rse.post);
  2670. gfc_add_block_to_block (&se->post, &lse.post);
  2671. }
  2672. /* If a string's length is one, we convert it to a single character. */
  2673. tree
  2674. gfc_string_to_single_character (tree len, tree str, int kind)
  2675. {
  2676. if (len == NULL
  2677. || !tree_fits_uhwi_p (len)
  2678. || !POINTER_TYPE_P (TREE_TYPE (str)))
  2679. return NULL_TREE;
  2680. if (TREE_INT_CST_LOW (len) == 1)
  2681. {
  2682. str = fold_convert (gfc_get_pchar_type (kind), str);
  2683. return build_fold_indirect_ref_loc (input_location, str);
  2684. }
  2685. if (kind == 1
  2686. && TREE_CODE (str) == ADDR_EXPR
  2687. && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
  2688. && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
  2689. && array_ref_low_bound (TREE_OPERAND (str, 0))
  2690. == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
  2691. && TREE_INT_CST_LOW (len) > 1
  2692. && TREE_INT_CST_LOW (len)
  2693. == (unsigned HOST_WIDE_INT)
  2694. TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
  2695. {
  2696. tree ret = fold_convert (gfc_get_pchar_type (kind), str);
  2697. ret = build_fold_indirect_ref_loc (input_location, ret);
  2698. if (TREE_CODE (ret) == INTEGER_CST)
  2699. {
  2700. tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
  2701. int i, length = TREE_STRING_LENGTH (string_cst);
  2702. const char *ptr = TREE_STRING_POINTER (string_cst);
  2703. for (i = 1; i < length; i++)
  2704. if (ptr[i] != ' ')
  2705. return NULL_TREE;
  2706. return ret;
  2707. }
  2708. }
  2709. return NULL_TREE;
  2710. }
  2711. void
  2712. gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
  2713. {
  2714. if (sym->backend_decl)
  2715. {
  2716. /* This becomes the nominal_type in
  2717. function.c:assign_parm_find_data_types. */
  2718. TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
  2719. /* This becomes the passed_type in
  2720. function.c:assign_parm_find_data_types. C promotes char to
  2721. integer for argument passing. */
  2722. DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
  2723. DECL_BY_REFERENCE (sym->backend_decl) = 0;
  2724. }
  2725. if (expr != NULL)
  2726. {
  2727. /* If we have a constant character expression, make it into an
  2728. integer. */
  2729. if ((*expr)->expr_type == EXPR_CONSTANT)
  2730. {
  2731. gfc_typespec ts;
  2732. gfc_clear_ts (&ts);
  2733. *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
  2734. (int)(*expr)->value.character.string[0]);
  2735. if ((*expr)->ts.kind != gfc_c_int_kind)
  2736. {
  2737. /* The expr needs to be compatible with a C int. If the
  2738. conversion fails, then the 2 causes an ICE. */
  2739. ts.type = BT_INTEGER;
  2740. ts.kind = gfc_c_int_kind;
  2741. gfc_convert_type (*expr, &ts, 2);
  2742. }
  2743. }
  2744. else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
  2745. {
  2746. if ((*expr)->ref == NULL)
  2747. {
  2748. se->expr = gfc_string_to_single_character
  2749. (build_int_cst (integer_type_node, 1),
  2750. gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
  2751. gfc_get_symbol_decl
  2752. ((*expr)->symtree->n.sym)),
  2753. (*expr)->ts.kind);
  2754. }
  2755. else
  2756. {
  2757. gfc_conv_variable (se, *expr);
  2758. se->expr = gfc_string_to_single_character
  2759. (build_int_cst (integer_type_node, 1),
  2760. gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
  2761. se->expr),
  2762. (*expr)->ts.kind);
  2763. }
  2764. }
  2765. }
  2766. }
  2767. /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
  2768. if STR is a string literal, otherwise return -1. */
  2769. static int
  2770. gfc_optimize_len_trim (tree len, tree str, int kind)
  2771. {
  2772. if (kind == 1
  2773. && TREE_CODE (str) == ADDR_EXPR
  2774. && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
  2775. && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
  2776. && array_ref_low_bound (TREE_OPERAND (str, 0))
  2777. == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
  2778. && tree_fits_uhwi_p (len)
  2779. && tree_to_uhwi (len) >= 1
  2780. && tree_to_uhwi (len)
  2781. == (unsigned HOST_WIDE_INT)
  2782. TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
  2783. {
  2784. tree folded = fold_convert (gfc_get_pchar_type (kind), str);
  2785. folded = build_fold_indirect_ref_loc (input_location, folded);
  2786. if (TREE_CODE (folded) == INTEGER_CST)
  2787. {
  2788. tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
  2789. int length = TREE_STRING_LENGTH (string_cst);
  2790. const char *ptr = TREE_STRING_POINTER (string_cst);
  2791. for (; length > 0; length--)
  2792. if (ptr[length - 1] != ' ')
  2793. break;
  2794. return length;
  2795. }
  2796. }
  2797. return -1;
  2798. }
  2799. /* Helper to build a call to memcmp. */
  2800. static tree
  2801. build_memcmp_call (tree s1, tree s2, tree n)
  2802. {
  2803. tree tmp;
  2804. if (!POINTER_TYPE_P (TREE_TYPE (s1)))
  2805. s1 = gfc_build_addr_expr (pvoid_type_node, s1);
  2806. else
  2807. s1 = fold_convert (pvoid_type_node, s1);
  2808. if (!POINTER_TYPE_P (TREE_TYPE (s2)))
  2809. s2 = gfc_build_addr_expr (pvoid_type_node, s2);
  2810. else
  2811. s2 = fold_convert (pvoid_type_node, s2);
  2812. n = fold_convert (size_type_node, n);
  2813. tmp = build_call_expr_loc (input_location,
  2814. builtin_decl_explicit (BUILT_IN_MEMCMP),
  2815. 3, s1, s2, n);
  2816. return fold_convert (integer_type_node, tmp);
  2817. }
  2818. /* Compare two strings. If they are all single characters, the result is the
  2819. subtraction of them. Otherwise, we build a library call. */
  2820. tree
  2821. gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
  2822. enum tree_code code)
  2823. {
  2824. tree sc1;
  2825. tree sc2;
  2826. tree fndecl;
  2827. gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
  2828. gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
  2829. sc1 = gfc_string_to_single_character (len1, str1, kind);
  2830. sc2 = gfc_string_to_single_character (len2, str2, kind);
  2831. if (sc1 != NULL_TREE && sc2 != NULL_TREE)
  2832. {
  2833. /* Deal with single character specially. */
  2834. sc1 = fold_convert (integer_type_node, sc1);
  2835. sc2 = fold_convert (integer_type_node, sc2);
  2836. return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
  2837. sc1, sc2);
  2838. }
  2839. if ((code == EQ_EXPR || code == NE_EXPR)
  2840. && optimize
  2841. && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
  2842. {
  2843. /* If one string is a string literal with LEN_TRIM longer
  2844. than the length of the second string, the strings
  2845. compare unequal. */
  2846. int len = gfc_optimize_len_trim (len1, str1, kind);
  2847. if (len > 0 && compare_tree_int (len2, len) < 0)
  2848. return integer_one_node;
  2849. len = gfc_optimize_len_trim (len2, str2, kind);
  2850. if (len > 0 && compare_tree_int (len1, len) < 0)
  2851. return integer_one_node;
  2852. }
  2853. /* We can compare via memcpy if the strings are known to be equal
  2854. in length and they are
  2855. - kind=1
  2856. - kind=4 and the comparison is for (in)equality. */
  2857. if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
  2858. && tree_int_cst_equal (len1, len2)
  2859. && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
  2860. {
  2861. tree tmp;
  2862. tree chartype;
  2863. chartype = gfc_get_char_type (kind);
  2864. tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
  2865. fold_convert (TREE_TYPE(len1),
  2866. TYPE_SIZE_UNIT(chartype)),
  2867. len1);
  2868. return build_memcmp_call (str1, str2, tmp);
  2869. }
  2870. /* Build a call for the comparison. */
  2871. if (kind == 1)
  2872. fndecl = gfor_fndecl_compare_string;
  2873. else if (kind == 4)
  2874. fndecl = gfor_fndecl_compare_string_char4;
  2875. else
  2876. gcc_unreachable ();
  2877. return build_call_expr_loc (input_location, fndecl, 4,
  2878. len1, str1, len2, str2);
  2879. }
  2880. /* Return the backend_decl for a procedure pointer component. */
  2881. static tree
  2882. get_proc_ptr_comp (gfc_expr *e)
  2883. {
  2884. gfc_se comp_se;
  2885. gfc_expr *e2;
  2886. expr_t old_type;
  2887. gfc_init_se (&comp_se, NULL);
  2888. e2 = gfc_copy_expr (e);
  2889. /* We have to restore the expr type later so that gfc_free_expr frees
  2890. the exact same thing that was allocated.
  2891. TODO: This is ugly. */
  2892. old_type = e2->expr_type;
  2893. e2->expr_type = EXPR_VARIABLE;
  2894. gfc_conv_expr (&comp_se, e2);
  2895. e2->expr_type = old_type;
  2896. gfc_free_expr (e2);
  2897. return build_fold_addr_expr_loc (input_location, comp_se.expr);
  2898. }
  2899. /* Convert a typebound function reference from a class object. */
  2900. static void
  2901. conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
  2902. {
  2903. gfc_ref *ref;
  2904. tree var;
  2905. if (TREE_CODE (base_object) != VAR_DECL)
  2906. {
  2907. var = gfc_create_var (TREE_TYPE (base_object), NULL);
  2908. gfc_add_modify (&se->pre, var, base_object);
  2909. }
  2910. se->expr = gfc_class_vptr_get (base_object);
  2911. se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
  2912. ref = expr->ref;
  2913. while (ref && ref->next)
  2914. ref = ref->next;
  2915. gcc_assert (ref && ref->type == REF_COMPONENT);
  2916. if (ref->u.c.sym->attr.extension)
  2917. conv_parent_component_references (se, ref);
  2918. gfc_conv_component_ref (se, ref);
  2919. se->expr = build_fold_addr_expr_loc (input_location, se->expr);
  2920. }
  2921. static void
  2922. conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
  2923. {
  2924. tree tmp;
  2925. if (gfc_is_proc_ptr_comp (expr))
  2926. tmp = get_proc_ptr_comp (expr);
  2927. else if (sym->attr.dummy)
  2928. {
  2929. tmp = gfc_get_symbol_decl (sym);
  2930. if (sym->attr.proc_pointer)
  2931. tmp = build_fold_indirect_ref_loc (input_location,
  2932. tmp);
  2933. gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
  2934. && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
  2935. }
  2936. else
  2937. {
  2938. if (!sym->backend_decl)
  2939. sym->backend_decl = gfc_get_extern_function_decl (sym);
  2940. TREE_USED (sym->backend_decl) = 1;
  2941. tmp = sym->backend_decl;
  2942. if (sym->attr.cray_pointee)
  2943. {
  2944. /* TODO - make the cray pointee a pointer to a procedure,
  2945. assign the pointer to it and use it for the call. This
  2946. will do for now! */
  2947. tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
  2948. gfc_get_symbol_decl (sym->cp_pointer));
  2949. tmp = gfc_evaluate_now (tmp, &se->pre);
  2950. }
  2951. if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
  2952. {
  2953. gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
  2954. tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  2955. }
  2956. }
  2957. se->expr = tmp;
  2958. }
  2959. /* Initialize MAPPING. */
  2960. void
  2961. gfc_init_interface_mapping (gfc_interface_mapping * mapping)
  2962. {
  2963. mapping->syms = NULL;
  2964. mapping->charlens = NULL;
  2965. }
  2966. /* Free all memory held by MAPPING (but not MAPPING itself). */
  2967. void
  2968. gfc_free_interface_mapping (gfc_interface_mapping * mapping)
  2969. {
  2970. gfc_interface_sym_mapping *sym;
  2971. gfc_interface_sym_mapping *nextsym;
  2972. gfc_charlen *cl;
  2973. gfc_charlen *nextcl;
  2974. for (sym = mapping->syms; sym; sym = nextsym)
  2975. {
  2976. nextsym = sym->next;
  2977. sym->new_sym->n.sym->formal = NULL;
  2978. gfc_free_symbol (sym->new_sym->n.sym);
  2979. gfc_free_expr (sym->expr);
  2980. free (sym->new_sym);
  2981. free (sym);
  2982. }
  2983. for (cl = mapping->charlens; cl; cl = nextcl)
  2984. {
  2985. nextcl = cl->next;
  2986. gfc_free_expr (cl->length);
  2987. free (cl);
  2988. }
  2989. }
  2990. /* Return a copy of gfc_charlen CL. Add the returned structure to
  2991. MAPPING so that it will be freed by gfc_free_interface_mapping. */
  2992. static gfc_charlen *
  2993. gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
  2994. gfc_charlen * cl)
  2995. {
  2996. gfc_charlen *new_charlen;
  2997. new_charlen = gfc_get_charlen ();
  2998. new_charlen->next = mapping->charlens;
  2999. new_charlen->length = gfc_copy_expr (cl->length);
  3000. mapping->charlens = new_charlen;
  3001. return new_charlen;
  3002. }
  3003. /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
  3004. array variable that can be used as the actual argument for dummy
  3005. argument SYM. Add any initialization code to BLOCK. PACKED is as
  3006. for gfc_get_nodesc_array_type and DATA points to the first element
  3007. in the passed array. */
  3008. static tree
  3009. gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
  3010. gfc_packed packed, tree data)
  3011. {
  3012. tree type;
  3013. tree var;
  3014. type = gfc_typenode_for_spec (&sym->ts);
  3015. type = gfc_get_nodesc_array_type (type, sym->as, packed,
  3016. !sym->attr.target && !sym->attr.pointer
  3017. && !sym->attr.proc_pointer);
  3018. var = gfc_create_var (type, "ifm");
  3019. gfc_add_modify (block, var, fold_convert (type, data));
  3020. return var;
  3021. }
  3022. /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
  3023. and offset of descriptorless array type TYPE given that it has the same
  3024. size as DESC. Add any set-up code to BLOCK. */
  3025. static void
  3026. gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
  3027. {
  3028. int n;
  3029. tree dim;
  3030. tree offset;
  3031. tree tmp;
  3032. offset = gfc_index_zero_node;
  3033. for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
  3034. {
  3035. dim = gfc_rank_cst[n];
  3036. GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
  3037. if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
  3038. {
  3039. GFC_TYPE_ARRAY_LBOUND (type, n)
  3040. = gfc_conv_descriptor_lbound_get (desc, dim);
  3041. GFC_TYPE_ARRAY_UBOUND (type, n)
  3042. = gfc_conv_descriptor_ubound_get (desc, dim);
  3043. }
  3044. else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
  3045. {
  3046. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  3047. gfc_array_index_type,
  3048. gfc_conv_descriptor_ubound_get (desc, dim),
  3049. gfc_conv_descriptor_lbound_get (desc, dim));
  3050. tmp = fold_build2_loc (input_location, PLUS_EXPR,
  3051. gfc_array_index_type,
  3052. GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
  3053. tmp = gfc_evaluate_now (tmp, block);
  3054. GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
  3055. }
  3056. tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  3057. GFC_TYPE_ARRAY_LBOUND (type, n),
  3058. GFC_TYPE_ARRAY_STRIDE (type, n));
  3059. offset = fold_build2_loc (input_location, MINUS_EXPR,
  3060. gfc_array_index_type, offset, tmp);
  3061. }
  3062. offset = gfc_evaluate_now (offset, block);
  3063. GFC_TYPE_ARRAY_OFFSET (type) = offset;
  3064. }
  3065. /* Extend MAPPING so that it maps dummy argument SYM to the value stored
  3066. in SE. The caller may still use se->expr and se->string_length after
  3067. calling this function. */
  3068. void
  3069. gfc_add_interface_mapping (gfc_interface_mapping * mapping,
  3070. gfc_symbol * sym, gfc_se * se,
  3071. gfc_expr *expr)
  3072. {
  3073. gfc_interface_sym_mapping *sm;
  3074. tree desc;
  3075. tree tmp;
  3076. tree value;
  3077. gfc_symbol *new_sym;
  3078. gfc_symtree *root;
  3079. gfc_symtree *new_symtree;
  3080. /* Create a new symbol to represent the actual argument. */
  3081. new_sym = gfc_new_symbol (sym->name, NULL);
  3082. new_sym->ts = sym->ts;
  3083. new_sym->as = gfc_copy_array_spec (sym->as);
  3084. new_sym->attr.referenced = 1;
  3085. new_sym->attr.dimension = sym->attr.dimension;
  3086. new_sym->attr.contiguous = sym->attr.contiguous;
  3087. new_sym->attr.codimension = sym->attr.codimension;
  3088. new_sym->attr.pointer = sym->attr.pointer;
  3089. new_sym->attr.allocatable = sym->attr.allocatable;
  3090. new_sym->attr.flavor = sym->attr.flavor;
  3091. new_sym->attr.function = sym->attr.function;
  3092. /* Ensure that the interface is available and that
  3093. descriptors are passed for array actual arguments. */
  3094. if (sym->attr.flavor == FL_PROCEDURE)
  3095. {
  3096. new_sym->formal = expr->symtree->n.sym->formal;
  3097. new_sym->attr.always_explicit
  3098. = expr->symtree->n.sym->attr.always_explicit;
  3099. }
  3100. /* Create a fake symtree for it. */
  3101. root = NULL;
  3102. new_symtree = gfc_new_symtree (&root, sym->name);
  3103. new_symtree->n.sym = new_sym;
  3104. gcc_assert (new_symtree == root);
  3105. /* Create a dummy->actual mapping. */
  3106. sm = XCNEW (gfc_interface_sym_mapping);
  3107. sm->next = mapping->syms;
  3108. sm->old = sym;
  3109. sm->new_sym = new_symtree;
  3110. sm->expr = gfc_copy_expr (expr);
  3111. mapping->syms = sm;
  3112. /* Stabilize the argument's value. */
  3113. if (!sym->attr.function && se)
  3114. se->expr = gfc_evaluate_now (se->expr, &se->pre);
  3115. if (sym->ts.type == BT_CHARACTER)
  3116. {
  3117. /* Create a copy of the dummy argument's length. */
  3118. new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
  3119. sm->expr->ts.u.cl = new_sym->ts.u.cl;
  3120. /* If the length is specified as "*", record the length that
  3121. the caller is passing. We should use the callee's length
  3122. in all other cases. */
  3123. if (!new_sym->ts.u.cl->length && se)
  3124. {
  3125. se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
  3126. new_sym->ts.u.cl->backend_decl = se->string_length;
  3127. }
  3128. }
  3129. if (!se)
  3130. return;
  3131. /* Use the passed value as-is if the argument is a function. */
  3132. if (sym->attr.flavor == FL_PROCEDURE)
  3133. value = se->expr;
  3134. /* If the argument is either a string or a pointer to a string,
  3135. convert it to a boundless character type. */
  3136. else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
  3137. {
  3138. tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
  3139. tmp = build_pointer_type (tmp);
  3140. if (sym->attr.pointer)
  3141. value = build_fold_indirect_ref_loc (input_location,
  3142. se->expr);
  3143. else
  3144. value = se->expr;
  3145. value = fold_convert (tmp, value);
  3146. }
  3147. /* If the argument is a scalar, a pointer to an array or an allocatable,
  3148. dereference it. */
  3149. else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
  3150. value = build_fold_indirect_ref_loc (input_location,
  3151. se->expr);
  3152. /* For character(*), use the actual argument's descriptor. */
  3153. else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
  3154. value = build_fold_indirect_ref_loc (input_location,
  3155. se->expr);
  3156. /* If the argument is an array descriptor, use it to determine
  3157. information about the actual argument's shape. */
  3158. else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
  3159. && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
  3160. {
  3161. /* Get the actual argument's descriptor. */
  3162. desc = build_fold_indirect_ref_loc (input_location,
  3163. se->expr);
  3164. /* Create the replacement variable. */
  3165. tmp = gfc_conv_descriptor_data_get (desc);
  3166. value = gfc_get_interface_mapping_array (&se->pre, sym,
  3167. PACKED_NO, tmp);
  3168. /* Use DESC to work out the upper bounds, strides and offset. */
  3169. gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
  3170. }
  3171. else
  3172. /* Otherwise we have a packed array. */
  3173. value = gfc_get_interface_mapping_array (&se->pre, sym,
  3174. PACKED_FULL, se->expr);
  3175. new_sym->backend_decl = value;
  3176. }
  3177. /* Called once all dummy argument mappings have been added to MAPPING,
  3178. but before the mapping is used to evaluate expressions. Pre-evaluate
  3179. the length of each argument, adding any initialization code to PRE and
  3180. any finalization code to POST. */
  3181. void
  3182. gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
  3183. stmtblock_t * pre, stmtblock_t * post)
  3184. {
  3185. gfc_interface_sym_mapping *sym;
  3186. gfc_expr *expr;
  3187. gfc_se se;
  3188. for (sym = mapping->syms; sym; sym = sym->next)
  3189. if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
  3190. && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
  3191. {
  3192. expr = sym->new_sym->n.sym->ts.u.cl->length;
  3193. gfc_apply_interface_mapping_to_expr (mapping, expr);
  3194. gfc_init_se (&se, NULL);
  3195. gfc_conv_expr (&se, expr);
  3196. se.expr = fold_convert (gfc_charlen_type_node, se.expr);
  3197. se.expr = gfc_evaluate_now (se.expr, &se.pre);
  3198. gfc_add_block_to_block (pre, &se.pre);
  3199. gfc_add_block_to_block (post, &se.post);
  3200. sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
  3201. }
  3202. }
  3203. /* Like gfc_apply_interface_mapping_to_expr, but applied to
  3204. constructor C. */
  3205. static void
  3206. gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
  3207. gfc_constructor_base base)
  3208. {
  3209. gfc_constructor *c;
  3210. for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
  3211. {
  3212. gfc_apply_interface_mapping_to_expr (mapping, c->expr);
  3213. if (c->iterator)
  3214. {
  3215. gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
  3216. gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
  3217. gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
  3218. }
  3219. }
  3220. }
  3221. /* Like gfc_apply_interface_mapping_to_expr, but applied to
  3222. reference REF. */
  3223. static void
  3224. gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
  3225. gfc_ref * ref)
  3226. {
  3227. int n;
  3228. for (; ref; ref = ref->next)
  3229. switch (ref->type)
  3230. {
  3231. case REF_ARRAY:
  3232. for (n = 0; n < ref->u.ar.dimen; n++)
  3233. {
  3234. gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
  3235. gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
  3236. gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
  3237. }
  3238. break;
  3239. case REF_COMPONENT:
  3240. break;
  3241. case REF_SUBSTRING:
  3242. gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
  3243. gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
  3244. break;
  3245. }
  3246. }
  3247. /* Convert intrinsic function calls into result expressions. */
  3248. static bool
  3249. gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
  3250. {
  3251. gfc_symbol *sym;
  3252. gfc_expr *new_expr;
  3253. gfc_expr *arg1;
  3254. gfc_expr *arg2;
  3255. int d, dup;
  3256. arg1 = expr->value.function.actual->expr;
  3257. if (expr->value.function.actual->next)
  3258. arg2 = expr->value.function.actual->next->expr;
  3259. else
  3260. arg2 = NULL;
  3261. sym = arg1->symtree->n.sym;
  3262. if (sym->attr.dummy)
  3263. return false;
  3264. new_expr = NULL;
  3265. switch (expr->value.function.isym->id)
  3266. {
  3267. case GFC_ISYM_LEN:
  3268. /* TODO figure out why this condition is necessary. */
  3269. if (sym->attr.function
  3270. && (arg1->ts.u.cl->length == NULL
  3271. || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
  3272. && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
  3273. return false;
  3274. new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
  3275. break;
  3276. case GFC_ISYM_SIZE:
  3277. if (!sym->as || sym->as->rank == 0)
  3278. return false;
  3279. if (arg2 && arg2->expr_type == EXPR_CONSTANT)
  3280. {
  3281. dup = mpz_get_si (arg2->value.integer);
  3282. d = dup - 1;
  3283. }
  3284. else
  3285. {
  3286. dup = sym->as->rank;
  3287. d = 0;
  3288. }
  3289. for (; d < dup; d++)
  3290. {
  3291. gfc_expr *tmp;
  3292. if (!sym->as->upper[d] || !sym->as->lower[d])
  3293. {
  3294. gfc_free_expr (new_expr);
  3295. return false;
  3296. }
  3297. tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
  3298. gfc_get_int_expr (gfc_default_integer_kind,
  3299. NULL, 1));
  3300. tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
  3301. if (new_expr)
  3302. new_expr = gfc_multiply (new_expr, tmp);
  3303. else
  3304. new_expr = tmp;
  3305. }
  3306. break;
  3307. case GFC_ISYM_LBOUND:
  3308. case GFC_ISYM_UBOUND:
  3309. /* TODO These implementations of lbound and ubound do not limit if
  3310. the size < 0, according to F95's 13.14.53 and 13.14.113. */
  3311. if (!sym->as || sym->as->rank == 0)
  3312. return false;
  3313. if (arg2 && arg2->expr_type == EXPR_CONSTANT)
  3314. d = mpz_get_si (arg2->value.integer) - 1;
  3315. else
  3316. /* TODO: If the need arises, this could produce an array of
  3317. ubound/lbounds. */
  3318. gcc_unreachable ();
  3319. if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
  3320. {
  3321. if (sym->as->lower[d])
  3322. new_expr = gfc_copy_expr (sym->as->lower[d]);
  3323. }
  3324. else
  3325. {
  3326. if (sym->as->upper[d])
  3327. new_expr = gfc_copy_expr (sym->as->upper[d]);
  3328. }
  3329. break;
  3330. default:
  3331. break;
  3332. }
  3333. gfc_apply_interface_mapping_to_expr (mapping, new_expr);
  3334. if (!new_expr)
  3335. return false;
  3336. gfc_replace_expr (expr, new_expr);
  3337. return true;
  3338. }
  3339. static void
  3340. gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
  3341. gfc_interface_mapping * mapping)
  3342. {
  3343. gfc_formal_arglist *f;
  3344. gfc_actual_arglist *actual;
  3345. actual = expr->value.function.actual;
  3346. f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
  3347. for (; f && actual; f = f->next, actual = actual->next)
  3348. {
  3349. if (!actual->expr)
  3350. continue;
  3351. gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
  3352. }
  3353. if (map_expr->symtree->n.sym->attr.dimension)
  3354. {
  3355. int d;
  3356. gfc_array_spec *as;
  3357. as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
  3358. for (d = 0; d < as->rank; d++)
  3359. {
  3360. gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
  3361. gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
  3362. }
  3363. expr->value.function.esym->as = as;
  3364. }
  3365. if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
  3366. {
  3367. expr->value.function.esym->ts.u.cl->length
  3368. = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
  3369. gfc_apply_interface_mapping_to_expr (mapping,
  3370. expr->value.function.esym->ts.u.cl->length);
  3371. }
  3372. }
  3373. /* EXPR is a copy of an expression that appeared in the interface
  3374. associated with MAPPING. Walk it recursively looking for references to
  3375. dummy arguments that MAPPING maps to actual arguments. Replace each such
  3376. reference with a reference to the associated actual argument. */
  3377. static void
  3378. gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
  3379. gfc_expr * expr)
  3380. {
  3381. gfc_interface_sym_mapping *sym;
  3382. gfc_actual_arglist *actual;
  3383. if (!expr)
  3384. return;
  3385. /* Copying an expression does not copy its length, so do that here. */
  3386. if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
  3387. {
  3388. expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
  3389. gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
  3390. }
  3391. /* Apply the mapping to any references. */
  3392. gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
  3393. /* ...and to the expression's symbol, if it has one. */
  3394. /* TODO Find out why the condition on expr->symtree had to be moved into
  3395. the loop rather than being outside it, as originally. */
  3396. for (sym = mapping->syms; sym; sym = sym->next)
  3397. if (expr->symtree && sym->old == expr->symtree->n.sym)
  3398. {
  3399. if (sym->new_sym->n.sym->backend_decl)
  3400. expr->symtree = sym->new_sym;
  3401. else if (sym->expr)
  3402. gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
  3403. }
  3404. /* ...and to subexpressions in expr->value. */
  3405. switch (expr->expr_type)
  3406. {
  3407. case EXPR_VARIABLE:
  3408. case EXPR_CONSTANT:
  3409. case EXPR_NULL:
  3410. case EXPR_SUBSTRING:
  3411. break;
  3412. case EXPR_OP:
  3413. gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
  3414. gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
  3415. break;
  3416. case EXPR_FUNCTION:
  3417. for (actual = expr->value.function.actual; actual; actual = actual->next)
  3418. gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
  3419. if (expr->value.function.esym == NULL
  3420. && expr->value.function.isym != NULL
  3421. && expr->value.function.actual->expr->symtree
  3422. && gfc_map_intrinsic_function (expr, mapping))
  3423. break;
  3424. for (sym = mapping->syms; sym; sym = sym->next)
  3425. if (sym->old == expr->value.function.esym)
  3426. {
  3427. expr->value.function.esym = sym->new_sym->n.sym;
  3428. gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
  3429. expr->value.function.esym->result = sym->new_sym->n.sym;
  3430. }
  3431. break;
  3432. case EXPR_ARRAY:
  3433. case EXPR_STRUCTURE:
  3434. gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
  3435. break;
  3436. case EXPR_COMPCALL:
  3437. case EXPR_PPC:
  3438. gcc_unreachable ();
  3439. break;
  3440. }
  3441. return;
  3442. }
  3443. /* Evaluate interface expression EXPR using MAPPING. Store the result
  3444. in SE. */
  3445. void
  3446. gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
  3447. gfc_se * se, gfc_expr * expr)
  3448. {
  3449. expr = gfc_copy_expr (expr);
  3450. gfc_apply_interface_mapping_to_expr (mapping, expr);
  3451. gfc_conv_expr (se, expr);
  3452. se->expr = gfc_evaluate_now (se->expr, &se->pre);
  3453. gfc_free_expr (expr);
  3454. }
  3455. /* Returns a reference to a temporary array into which a component of
  3456. an actual argument derived type array is copied and then returned
  3457. after the function call. */
  3458. void
  3459. gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
  3460. sym_intent intent, bool formal_ptr)
  3461. {
  3462. gfc_se lse;
  3463. gfc_se rse;
  3464. gfc_ss *lss;
  3465. gfc_ss *rss;
  3466. gfc_loopinfo loop;
  3467. gfc_loopinfo loop2;
  3468. gfc_array_info *info;
  3469. tree offset;
  3470. tree tmp_index;
  3471. tree tmp;
  3472. tree base_type;
  3473. tree size;
  3474. stmtblock_t body;
  3475. int n;
  3476. int dimen;
  3477. gfc_init_se (&lse, NULL);
  3478. gfc_init_se (&rse, NULL);
  3479. /* Walk the argument expression. */
  3480. rss = gfc_walk_expr (expr);
  3481. gcc_assert (rss != gfc_ss_terminator);
  3482. /* Initialize the scalarizer. */
  3483. gfc_init_loopinfo (&loop);
  3484. gfc_add_ss_to_loop (&loop, rss);
  3485. /* Calculate the bounds of the scalarization. */
  3486. gfc_conv_ss_startstride (&loop);
  3487. /* Build an ss for the temporary. */
  3488. if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
  3489. gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
  3490. base_type = gfc_typenode_for_spec (&expr->ts);
  3491. if (GFC_ARRAY_TYPE_P (base_type)
  3492. || GFC_DESCRIPTOR_TYPE_P (base_type))
  3493. base_type = gfc_get_element_type (base_type);
  3494. if (expr->ts.type == BT_CLASS)
  3495. base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
  3496. loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
  3497. ? expr->ts.u.cl->backend_decl
  3498. : NULL),
  3499. loop.dimen);
  3500. parmse->string_length = loop.temp_ss->info->string_length;
  3501. /* Associate the SS with the loop. */
  3502. gfc_add_ss_to_loop (&loop, loop.temp_ss);
  3503. /* Setup the scalarizing loops. */
  3504. gfc_conv_loop_setup (&loop, &expr->where);
  3505. /* Pass the temporary descriptor back to the caller. */
  3506. info = &loop.temp_ss->info->data.array;
  3507. parmse->expr = info->descriptor;
  3508. /* Setup the gfc_se structures. */
  3509. gfc_copy_loopinfo_to_se (&lse, &loop);
  3510. gfc_copy_loopinfo_to_se (&rse, &loop);
  3511. rse.ss = rss;
  3512. lse.ss = loop.temp_ss;
  3513. gfc_mark_ss_chain_used (rss, 1);
  3514. gfc_mark_ss_chain_used (loop.temp_ss, 1);
  3515. /* Start the scalarized loop body. */
  3516. gfc_start_scalarized_body (&loop, &body);
  3517. /* Translate the expression. */
  3518. gfc_conv_expr (&rse, expr);
  3519. /* Reset the offset for the function call since the loop
  3520. is zero based on the data pointer. Note that the temp
  3521. comes first in the loop chain since it is added second. */
  3522. if (gfc_is_alloc_class_array_function (expr))
  3523. {
  3524. tmp = loop.ss->loop_chain->info->data.array.descriptor;
  3525. gfc_conv_descriptor_offset_set (&loop.pre, tmp,
  3526. gfc_index_zero_node);
  3527. }
  3528. gfc_conv_tmp_array_ref (&lse);
  3529. if (intent != INTENT_OUT)
  3530. {
  3531. tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
  3532. gfc_add_expr_to_block (&body, tmp);
  3533. gcc_assert (rse.ss == gfc_ss_terminator);
  3534. gfc_trans_scalarizing_loops (&loop, &body);
  3535. }
  3536. else
  3537. {
  3538. /* Make sure that the temporary declaration survives by merging
  3539. all the loop declarations into the current context. */
  3540. for (n = 0; n < loop.dimen; n++)
  3541. {
  3542. gfc_merge_block_scope (&body);
  3543. body = loop.code[loop.order[n]];
  3544. }
  3545. gfc_merge_block_scope (&body);
  3546. }
  3547. /* Add the post block after the second loop, so that any
  3548. freeing of allocated memory is done at the right time. */
  3549. gfc_add_block_to_block (&parmse->pre, &loop.pre);
  3550. /**********Copy the temporary back again.*********/
  3551. gfc_init_se (&lse, NULL);
  3552. gfc_init_se (&rse, NULL);
  3553. /* Walk the argument expression. */
  3554. lss = gfc_walk_expr (expr);
  3555. rse.ss = loop.temp_ss;
  3556. lse.ss = lss;
  3557. /* Initialize the scalarizer. */
  3558. gfc_init_loopinfo (&loop2);
  3559. gfc_add_ss_to_loop (&loop2, lss);
  3560. dimen = rse.ss->dimen;
  3561. /* Skip the write-out loop for this case. */
  3562. if (gfc_is_alloc_class_array_function (expr))
  3563. goto class_array_fcn;
  3564. /* Calculate the bounds of the scalarization. */
  3565. gfc_conv_ss_startstride (&loop2);
  3566. /* Setup the scalarizing loops. */
  3567. gfc_conv_loop_setup (&loop2, &expr->where);
  3568. gfc_copy_loopinfo_to_se (&lse, &loop2);
  3569. gfc_copy_loopinfo_to_se (&rse, &loop2);
  3570. gfc_mark_ss_chain_used (lss, 1);
  3571. gfc_mark_ss_chain_used (loop.temp_ss, 1);
  3572. /* Declare the variable to hold the temporary offset and start the
  3573. scalarized loop body. */
  3574. offset = gfc_create_var (gfc_array_index_type, NULL);
  3575. gfc_start_scalarized_body (&loop2, &body);
  3576. /* Build the offsets for the temporary from the loop variables. The
  3577. temporary array has lbounds of zero and strides of one in all
  3578. dimensions, so this is very simple. The offset is only computed
  3579. outside the innermost loop, so the overall transfer could be
  3580. optimized further. */
  3581. info = &rse.ss->info->data.array;
  3582. tmp_index = gfc_index_zero_node;
  3583. for (n = dimen - 1; n > 0; n--)
  3584. {
  3585. tree tmp_str;
  3586. tmp = rse.loop->loopvar[n];
  3587. tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  3588. tmp, rse.loop->from[n]);
  3589. tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  3590. tmp, tmp_index);
  3591. tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
  3592. gfc_array_index_type,
  3593. rse.loop->to[n-1], rse.loop->from[n-1]);
  3594. tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
  3595. gfc_array_index_type,
  3596. tmp_str, gfc_index_one_node);
  3597. tmp_index = fold_build2_loc (input_location, MULT_EXPR,
  3598. gfc_array_index_type, tmp, tmp_str);
  3599. }
  3600. tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
  3601. gfc_array_index_type,
  3602. tmp_index, rse.loop->from[0]);
  3603. gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
  3604. tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
  3605. gfc_array_index_type,
  3606. rse.loop->loopvar[0], offset);
  3607. /* Now use the offset for the reference. */
  3608. tmp = build_fold_indirect_ref_loc (input_location,
  3609. info->data);
  3610. rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
  3611. if (expr->ts.type == BT_CHARACTER)
  3612. rse.string_length = expr->ts.u.cl->backend_decl;
  3613. gfc_conv_expr (&lse, expr);
  3614. gcc_assert (lse.ss == gfc_ss_terminator);
  3615. tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
  3616. gfc_add_expr_to_block (&body, tmp);
  3617. /* Generate the copying loops. */
  3618. gfc_trans_scalarizing_loops (&loop2, &body);
  3619. /* Wrap the whole thing up by adding the second loop to the post-block
  3620. and following it by the post-block of the first loop. In this way,
  3621. if the temporary needs freeing, it is done after use! */
  3622. if (intent != INTENT_IN)
  3623. {
  3624. gfc_add_block_to_block (&parmse->post, &loop2.pre);
  3625. gfc_add_block_to_block (&parmse->post, &loop2.post);
  3626. }
  3627. class_array_fcn:
  3628. gfc_add_block_to_block (&parmse->post, &loop.post);
  3629. gfc_cleanup_loop (&loop);
  3630. gfc_cleanup_loop (&loop2);
  3631. /* Pass the string length to the argument expression. */
  3632. if (expr->ts.type == BT_CHARACTER)
  3633. parmse->string_length = expr->ts.u.cl->backend_decl;
  3634. /* Determine the offset for pointer formal arguments and set the
  3635. lbounds to one. */
  3636. if (formal_ptr)
  3637. {
  3638. size = gfc_index_one_node;
  3639. offset = gfc_index_zero_node;
  3640. for (n = 0; n < dimen; n++)
  3641. {
  3642. tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
  3643. gfc_rank_cst[n]);
  3644. tmp = fold_build2_loc (input_location, PLUS_EXPR,
  3645. gfc_array_index_type, tmp,
  3646. gfc_index_one_node);
  3647. gfc_conv_descriptor_ubound_set (&parmse->pre,
  3648. parmse->expr,
  3649. gfc_rank_cst[n],
  3650. tmp);
  3651. gfc_conv_descriptor_lbound_set (&parmse->pre,
  3652. parmse->expr,
  3653. gfc_rank_cst[n],
  3654. gfc_index_one_node);
  3655. size = gfc_evaluate_now (size, &parmse->pre);
  3656. offset = fold_build2_loc (input_location, MINUS_EXPR,
  3657. gfc_array_index_type,
  3658. offset, size);
  3659. offset = gfc_evaluate_now (offset, &parmse->pre);
  3660. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  3661. gfc_array_index_type,
  3662. rse.loop->to[n], rse.loop->from[n]);
  3663. tmp = fold_build2_loc (input_location, PLUS_EXPR,
  3664. gfc_array_index_type,
  3665. tmp, gfc_index_one_node);
  3666. size = fold_build2_loc (input_location, MULT_EXPR,
  3667. gfc_array_index_type, size, tmp);
  3668. }
  3669. gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
  3670. offset);
  3671. }
  3672. /* We want either the address for the data or the address of the descriptor,
  3673. depending on the mode of passing array arguments. */
  3674. if (g77)
  3675. parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
  3676. else
  3677. parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
  3678. return;
  3679. }
  3680. /* Generate the code for argument list functions. */
  3681. static void
  3682. conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
  3683. {
  3684. /* Pass by value for g77 %VAL(arg), pass the address
  3685. indirectly for %LOC, else by reference. Thus %REF
  3686. is a "do-nothing" and %LOC is the same as an F95
  3687. pointer. */
  3688. if (strncmp (name, "%VAL", 4) == 0)
  3689. gfc_conv_expr (se, expr);
  3690. else if (strncmp (name, "%LOC", 4) == 0)
  3691. {
  3692. gfc_conv_expr_reference (se, expr);
  3693. se->expr = gfc_build_addr_expr (NULL, se->expr);
  3694. }
  3695. else if (strncmp (name, "%REF", 4) == 0)
  3696. gfc_conv_expr_reference (se, expr);
  3697. else
  3698. gfc_error ("Unknown argument list function at %L", &expr->where);
  3699. }
  3700. /* Generate code for a procedure call. Note can return se->post != NULL.
  3701. If se->direct_byref is set then se->expr contains the return parameter.
  3702. Return nonzero, if the call has alternate specifiers.
  3703. 'expr' is only needed for procedure pointer components. */
  3704. int
  3705. gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
  3706. gfc_actual_arglist * args, gfc_expr * expr,
  3707. vec<tree, va_gc> *append_args)
  3708. {
  3709. gfc_interface_mapping mapping;
  3710. vec<tree, va_gc> *arglist;
  3711. vec<tree, va_gc> *retargs;
  3712. tree tmp;
  3713. tree fntype;
  3714. gfc_se parmse;
  3715. gfc_array_info *info;
  3716. int byref;
  3717. int parm_kind;
  3718. tree type;
  3719. tree var;
  3720. tree len;
  3721. tree base_object;
  3722. vec<tree, va_gc> *stringargs;
  3723. vec<tree, va_gc> *optionalargs;
  3724. tree result = NULL;
  3725. gfc_formal_arglist *formal;
  3726. gfc_actual_arglist *arg;
  3727. int has_alternate_specifier = 0;
  3728. bool need_interface_mapping;
  3729. bool callee_alloc;
  3730. gfc_typespec ts;
  3731. gfc_charlen cl;
  3732. gfc_expr *e;
  3733. gfc_symbol *fsym;
  3734. stmtblock_t post;
  3735. enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
  3736. gfc_component *comp = NULL;
  3737. int arglen;
  3738. arglist = NULL;
  3739. retargs = NULL;
  3740. stringargs = NULL;
  3741. optionalargs = NULL;
  3742. var = NULL_TREE;
  3743. len = NULL_TREE;
  3744. gfc_clear_ts (&ts);
  3745. comp = gfc_get_proc_ptr_comp (expr);
  3746. if (se->ss != NULL)
  3747. {
  3748. if (!sym->attr.elemental && !(comp && comp->attr.elemental))
  3749. {
  3750. gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
  3751. if (se->ss->info->useflags)
  3752. {
  3753. gcc_assert ((!comp && gfc_return_by_reference (sym)
  3754. && sym->result->attr.dimension)
  3755. || (comp && comp->attr.dimension)
  3756. || gfc_is_alloc_class_array_function (expr));
  3757. gcc_assert (se->loop != NULL);
  3758. /* Access the previously obtained result. */
  3759. gfc_conv_tmp_array_ref (se);
  3760. return 0;
  3761. }
  3762. }
  3763. info = &se->ss->info->data.array;
  3764. }
  3765. else
  3766. info = NULL;
  3767. gfc_init_block (&post);
  3768. gfc_init_interface_mapping (&mapping);
  3769. if (!comp)
  3770. {
  3771. formal = gfc_sym_get_dummy_args (sym);
  3772. need_interface_mapping = sym->attr.dimension ||
  3773. (sym->ts.type == BT_CHARACTER
  3774. && sym->ts.u.cl->length
  3775. && sym->ts.u.cl->length->expr_type
  3776. != EXPR_CONSTANT);
  3777. }
  3778. else
  3779. {
  3780. formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
  3781. need_interface_mapping = comp->attr.dimension ||
  3782. (comp->ts.type == BT_CHARACTER
  3783. && comp->ts.u.cl->length
  3784. && comp->ts.u.cl->length->expr_type
  3785. != EXPR_CONSTANT);
  3786. }
  3787. base_object = NULL_TREE;
  3788. /* Evaluate the arguments. */
  3789. for (arg = args; arg != NULL;
  3790. arg = arg->next, formal = formal ? formal->next : NULL)
  3791. {
  3792. e = arg->expr;
  3793. fsym = formal ? formal->sym : NULL;
  3794. parm_kind = MISSING;
  3795. /* Class array expressions are sometimes coming completely unadorned
  3796. with either arrayspec or _data component. Correct that here.
  3797. OOP-TODO: Move this to the frontend. */
  3798. if (e && e->expr_type == EXPR_VARIABLE
  3799. && !e->ref
  3800. && e->ts.type == BT_CLASS
  3801. && (CLASS_DATA (e)->attr.codimension
  3802. || CLASS_DATA (e)->attr.dimension))
  3803. {
  3804. gfc_typespec temp_ts = e->ts;
  3805. gfc_add_class_array_ref (e);
  3806. e->ts = temp_ts;
  3807. }
  3808. if (e == NULL)
  3809. {
  3810. if (se->ignore_optional)
  3811. {
  3812. /* Some intrinsics have already been resolved to the correct
  3813. parameters. */
  3814. continue;
  3815. }
  3816. else if (arg->label)
  3817. {
  3818. has_alternate_specifier = 1;
  3819. continue;
  3820. }
  3821. else
  3822. {
  3823. gfc_init_se (&parmse, NULL);
  3824. /* For scalar arguments with VALUE attribute which are passed by
  3825. value, pass "0" and a hidden argument gives the optional
  3826. status. */
  3827. if (fsym && fsym->attr.optional && fsym->attr.value
  3828. && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
  3829. && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
  3830. {
  3831. parmse.expr = fold_convert (gfc_sym_type (fsym),
  3832. integer_zero_node);
  3833. vec_safe_push (optionalargs, boolean_false_node);
  3834. }
  3835. else
  3836. {
  3837. /* Pass a NULL pointer for an absent arg. */
  3838. parmse.expr = null_pointer_node;
  3839. if (arg->missing_arg_type == BT_CHARACTER)
  3840. parmse.string_length = build_int_cst (gfc_charlen_type_node,
  3841. 0);
  3842. }
  3843. }
  3844. }
  3845. else if (arg->expr->expr_type == EXPR_NULL
  3846. && fsym && !fsym->attr.pointer
  3847. && (fsym->ts.type != BT_CLASS
  3848. || !CLASS_DATA (fsym)->attr.class_pointer))
  3849. {
  3850. /* Pass a NULL pointer to denote an absent arg. */
  3851. gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
  3852. && (fsym->ts.type != BT_CLASS
  3853. || !CLASS_DATA (fsym)->attr.allocatable));
  3854. gfc_init_se (&parmse, NULL);
  3855. parmse.expr = null_pointer_node;
  3856. if (arg->missing_arg_type == BT_CHARACTER)
  3857. parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
  3858. }
  3859. else if (fsym && fsym->ts.type == BT_CLASS
  3860. && e->ts.type == BT_DERIVED)
  3861. {
  3862. /* The derived type needs to be converted to a temporary
  3863. CLASS object. */
  3864. gfc_init_se (&parmse, se);
  3865. gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
  3866. fsym->attr.optional
  3867. && e->expr_type == EXPR_VARIABLE
  3868. && e->symtree->n.sym->attr.optional,
  3869. CLASS_DATA (fsym)->attr.class_pointer
  3870. || CLASS_DATA (fsym)->attr.allocatable);
  3871. }
  3872. else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
  3873. {
  3874. /* The intrinsic type needs to be converted to a temporary
  3875. CLASS object for the unlimited polymorphic formal. */
  3876. gfc_init_se (&parmse, se);
  3877. gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
  3878. }
  3879. else if (se->ss && se->ss->info->useflags)
  3880. {
  3881. gfc_ss *ss;
  3882. ss = se->ss;
  3883. /* An elemental function inside a scalarized loop. */
  3884. gfc_init_se (&parmse, se);
  3885. parm_kind = ELEMENTAL;
  3886. if (fsym && fsym->attr.value)
  3887. gfc_conv_expr (&parmse, e);
  3888. else
  3889. gfc_conv_expr_reference (&parmse, e);
  3890. if (e->ts.type == BT_CHARACTER && !e->rank
  3891. && e->expr_type == EXPR_FUNCTION)
  3892. parmse.expr = build_fold_indirect_ref_loc (input_location,
  3893. parmse.expr);
  3894. if (fsym && fsym->ts.type == BT_DERIVED
  3895. && gfc_is_class_container_ref (e))
  3896. {
  3897. parmse.expr = gfc_class_data_get (parmse.expr);
  3898. if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
  3899. && e->symtree->n.sym->attr.optional)
  3900. {
  3901. tree cond = gfc_conv_expr_present (e->symtree->n.sym);
  3902. parmse.expr = build3_loc (input_location, COND_EXPR,
  3903. TREE_TYPE (parmse.expr),
  3904. cond, parmse.expr,
  3905. fold_convert (TREE_TYPE (parmse.expr),
  3906. null_pointer_node));
  3907. }
  3908. }
  3909. /* If we are passing an absent array as optional dummy to an
  3910. elemental procedure, make sure that we pass NULL when the data
  3911. pointer is NULL. We need this extra conditional because of
  3912. scalarization which passes arrays elements to the procedure,
  3913. ignoring the fact that the array can be absent/unallocated/... */
  3914. if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
  3915. {
  3916. tree descriptor_data;
  3917. descriptor_data = ss->info->data.array.data;
  3918. tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  3919. descriptor_data,
  3920. fold_convert (TREE_TYPE (descriptor_data),
  3921. null_pointer_node));
  3922. parmse.expr
  3923. = fold_build3_loc (input_location, COND_EXPR,
  3924. TREE_TYPE (parmse.expr),
  3925. gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
  3926. fold_convert (TREE_TYPE (parmse.expr),
  3927. null_pointer_node),
  3928. parmse.expr);
  3929. }
  3930. /* The scalarizer does not repackage the reference to a class
  3931. array - instead it returns a pointer to the data element. */
  3932. if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
  3933. gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
  3934. fsym->attr.intent != INTENT_IN
  3935. && (CLASS_DATA (fsym)->attr.class_pointer
  3936. || CLASS_DATA (fsym)->attr.allocatable),
  3937. fsym->attr.optional
  3938. && e->expr_type == EXPR_VARIABLE
  3939. && e->symtree->n.sym->attr.optional,
  3940. CLASS_DATA (fsym)->attr.class_pointer
  3941. || CLASS_DATA (fsym)->attr.allocatable);
  3942. }
  3943. else
  3944. {
  3945. bool scalar;
  3946. gfc_ss *argss;
  3947. gfc_init_se (&parmse, NULL);
  3948. /* Check whether the expression is a scalar or not; we cannot use
  3949. e->rank as it can be nonzero for functions arguments. */
  3950. argss = gfc_walk_expr (e);
  3951. scalar = argss == gfc_ss_terminator;
  3952. if (!scalar)
  3953. gfc_free_ss_chain (argss);
  3954. /* Special handling for passing scalar polymorphic coarrays;
  3955. otherwise one passes "class->_data.data" instead of "&class". */
  3956. if (e->rank == 0 && e->ts.type == BT_CLASS
  3957. && fsym && fsym->ts.type == BT_CLASS
  3958. && CLASS_DATA (fsym)->attr.codimension
  3959. && !CLASS_DATA (fsym)->attr.dimension)
  3960. {
  3961. gfc_add_class_array_ref (e);
  3962. parmse.want_coarray = 1;
  3963. scalar = false;
  3964. }
  3965. /* A scalar or transformational function. */
  3966. if (scalar)
  3967. {
  3968. if (e->expr_type == EXPR_VARIABLE
  3969. && e->symtree->n.sym->attr.cray_pointee
  3970. && fsym && fsym->attr.flavor == FL_PROCEDURE)
  3971. {
  3972. /* The Cray pointer needs to be converted to a pointer to
  3973. a type given by the expression. */
  3974. gfc_conv_expr (&parmse, e);
  3975. type = build_pointer_type (TREE_TYPE (parmse.expr));
  3976. tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
  3977. parmse.expr = convert (type, tmp);
  3978. }
  3979. else if (fsym && fsym->attr.value)
  3980. {
  3981. if (fsym->ts.type == BT_CHARACTER
  3982. && fsym->ts.is_c_interop
  3983. && fsym->ns->proc_name != NULL
  3984. && fsym->ns->proc_name->attr.is_bind_c)
  3985. {
  3986. parmse.expr = NULL;
  3987. gfc_conv_scalar_char_value (fsym, &parmse, &e);
  3988. if (parmse.expr == NULL)
  3989. gfc_conv_expr (&parmse, e);
  3990. }
  3991. else
  3992. {
  3993. gfc_conv_expr (&parmse, e);
  3994. if (fsym->attr.optional
  3995. && fsym->ts.type != BT_CLASS
  3996. && fsym->ts.type != BT_DERIVED)
  3997. {
  3998. if (e->expr_type != EXPR_VARIABLE
  3999. || !e->symtree->n.sym->attr.optional
  4000. || e->ref != NULL)
  4001. vec_safe_push (optionalargs, boolean_true_node);
  4002. else
  4003. {
  4004. tmp = gfc_conv_expr_present (e->symtree->n.sym);
  4005. if (!e->symtree->n.sym->attr.value)
  4006. parmse.expr
  4007. = fold_build3_loc (input_location, COND_EXPR,
  4008. TREE_TYPE (parmse.expr),
  4009. tmp, parmse.expr,
  4010. fold_convert (TREE_TYPE (parmse.expr),
  4011. integer_zero_node));
  4012. vec_safe_push (optionalargs, tmp);
  4013. }
  4014. }
  4015. }
  4016. }
  4017. else if (arg->name && arg->name[0] == '%')
  4018. /* Argument list functions %VAL, %LOC and %REF are signalled
  4019. through arg->name. */
  4020. conv_arglist_function (&parmse, arg->expr, arg->name);
  4021. else if ((e->expr_type == EXPR_FUNCTION)
  4022. && ((e->value.function.esym
  4023. && e->value.function.esym->result->attr.pointer)
  4024. || (!e->value.function.esym
  4025. && e->symtree->n.sym->attr.pointer))
  4026. && fsym && fsym->attr.target)
  4027. {
  4028. gfc_conv_expr (&parmse, e);
  4029. parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
  4030. }
  4031. else if (e->expr_type == EXPR_FUNCTION
  4032. && e->symtree->n.sym->result
  4033. && e->symtree->n.sym->result != e->symtree->n.sym
  4034. && e->symtree->n.sym->result->attr.proc_pointer)
  4035. {
  4036. /* Functions returning procedure pointers. */
  4037. gfc_conv_expr (&parmse, e);
  4038. if (fsym && fsym->attr.proc_pointer)
  4039. parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
  4040. }
  4041. else
  4042. {
  4043. if (e->ts.type == BT_CLASS && fsym
  4044. && fsym->ts.type == BT_CLASS
  4045. && (!CLASS_DATA (fsym)->as
  4046. || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
  4047. && CLASS_DATA (e)->attr.codimension)
  4048. {
  4049. gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
  4050. gcc_assert (!CLASS_DATA (fsym)->as);
  4051. gfc_add_class_array_ref (e);
  4052. parmse.want_coarray = 1;
  4053. gfc_conv_expr_reference (&parmse, e);
  4054. class_scalar_coarray_to_class (&parmse, e, fsym->ts,
  4055. fsym->attr.optional
  4056. && e->expr_type == EXPR_VARIABLE);
  4057. }
  4058. else if (e->ts.type == BT_CLASS && fsym
  4059. && fsym->ts.type == BT_CLASS
  4060. && !CLASS_DATA (fsym)->as
  4061. && !CLASS_DATA (e)->as
  4062. && strcmp (fsym->ts.u.derived->name,
  4063. e->ts.u.derived->name))
  4064. {
  4065. type = gfc_typenode_for_spec (&fsym->ts);
  4066. var = gfc_create_var (type, fsym->name);
  4067. gfc_conv_expr (&parmse, e);
  4068. if (fsym->attr.optional
  4069. && e->expr_type == EXPR_VARIABLE
  4070. && e->symtree->n.sym->attr.optional)
  4071. {
  4072. stmtblock_t block;
  4073. tree cond;
  4074. tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
  4075. cond = fold_build2_loc (input_location, NE_EXPR,
  4076. boolean_type_node, tmp,
  4077. fold_convert (TREE_TYPE (tmp),
  4078. null_pointer_node));
  4079. gfc_start_block (&block);
  4080. gfc_add_modify (&block, var,
  4081. fold_build1_loc (input_location,
  4082. VIEW_CONVERT_EXPR,
  4083. type, parmse.expr));
  4084. gfc_add_expr_to_block (&parmse.pre,
  4085. fold_build3_loc (input_location,
  4086. COND_EXPR, void_type_node,
  4087. cond, gfc_finish_block (&block),
  4088. build_empty_stmt (input_location)));
  4089. parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
  4090. parmse.expr = build3_loc (input_location, COND_EXPR,
  4091. TREE_TYPE (parmse.expr),
  4092. cond, parmse.expr,
  4093. fold_convert (TREE_TYPE (parmse.expr),
  4094. null_pointer_node));
  4095. }
  4096. else
  4097. {
  4098. gfc_add_modify (&parmse.pre, var,
  4099. fold_build1_loc (input_location,
  4100. VIEW_CONVERT_EXPR,
  4101. type, parmse.expr));
  4102. parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
  4103. }
  4104. }
  4105. else
  4106. gfc_conv_expr_reference (&parmse, e);
  4107. /* Catch base objects that are not variables. */
  4108. if (e->ts.type == BT_CLASS
  4109. && e->expr_type != EXPR_VARIABLE
  4110. && expr && e == expr->base_expr)
  4111. base_object = build_fold_indirect_ref_loc (input_location,
  4112. parmse.expr);
  4113. /* A class array element needs converting back to be a
  4114. class object, if the formal argument is a class object. */
  4115. if (fsym && fsym->ts.type == BT_CLASS
  4116. && e->ts.type == BT_CLASS
  4117. && ((CLASS_DATA (fsym)->as
  4118. && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
  4119. || CLASS_DATA (e)->attr.dimension))
  4120. gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
  4121. fsym->attr.intent != INTENT_IN
  4122. && (CLASS_DATA (fsym)->attr.class_pointer
  4123. || CLASS_DATA (fsym)->attr.allocatable),
  4124. fsym->attr.optional
  4125. && e->expr_type == EXPR_VARIABLE
  4126. && e->symtree->n.sym->attr.optional,
  4127. CLASS_DATA (fsym)->attr.class_pointer
  4128. || CLASS_DATA (fsym)->attr.allocatable);
  4129. /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
  4130. allocated on entry, it must be deallocated. */
  4131. if (fsym && fsym->attr.intent == INTENT_OUT
  4132. && (fsym->attr.allocatable
  4133. || (fsym->ts.type == BT_CLASS
  4134. && CLASS_DATA (fsym)->attr.allocatable)))
  4135. {
  4136. stmtblock_t block;
  4137. tree ptr;
  4138. gfc_init_block (&block);
  4139. ptr = parmse.expr;
  4140. if (e->ts.type == BT_CLASS)
  4141. ptr = gfc_class_data_get (ptr);
  4142. tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
  4143. true, e, e->ts);
  4144. gfc_add_expr_to_block (&block, tmp);
  4145. tmp = fold_build2_loc (input_location, MODIFY_EXPR,
  4146. void_type_node, ptr,
  4147. null_pointer_node);
  4148. gfc_add_expr_to_block (&block, tmp);
  4149. if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
  4150. {
  4151. gfc_add_modify (&block, ptr,
  4152. fold_convert (TREE_TYPE (ptr),
  4153. null_pointer_node));
  4154. gfc_add_expr_to_block (&block, tmp);
  4155. }
  4156. else if (fsym->ts.type == BT_CLASS)
  4157. {
  4158. gfc_symbol *vtab;
  4159. vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
  4160. tmp = gfc_get_symbol_decl (vtab);
  4161. tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  4162. ptr = gfc_class_vptr_get (parmse.expr);
  4163. gfc_add_modify (&block, ptr,
  4164. fold_convert (TREE_TYPE (ptr), tmp));
  4165. gfc_add_expr_to_block (&block, tmp);
  4166. }
  4167. if (fsym->attr.optional
  4168. && e->expr_type == EXPR_VARIABLE
  4169. && e->symtree->n.sym->attr.optional)
  4170. {
  4171. tmp = fold_build3_loc (input_location, COND_EXPR,
  4172. void_type_node,
  4173. gfc_conv_expr_present (e->symtree->n.sym),
  4174. gfc_finish_block (&block),
  4175. build_empty_stmt (input_location));
  4176. }
  4177. else
  4178. tmp = gfc_finish_block (&block);
  4179. gfc_add_expr_to_block (&se->pre, tmp);
  4180. }
  4181. if (fsym && (fsym->ts.type == BT_DERIVED
  4182. || fsym->ts.type == BT_ASSUMED)
  4183. && e->ts.type == BT_CLASS
  4184. && !CLASS_DATA (e)->attr.dimension
  4185. && !CLASS_DATA (e)->attr.codimension)
  4186. parmse.expr = gfc_class_data_get (parmse.expr);
  4187. /* Wrap scalar variable in a descriptor. We need to convert
  4188. the address of a pointer back to the pointer itself before,
  4189. we can assign it to the data field. */
  4190. if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
  4191. && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
  4192. {
  4193. tmp = parmse.expr;
  4194. if (TREE_CODE (tmp) == ADDR_EXPR
  4195. && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
  4196. tmp = TREE_OPERAND (tmp, 0);
  4197. parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
  4198. fsym->attr);
  4199. parmse.expr = gfc_build_addr_expr (NULL_TREE,
  4200. parmse.expr);
  4201. }
  4202. else if (fsym && e->expr_type != EXPR_NULL
  4203. && ((fsym->attr.pointer
  4204. && fsym->attr.flavor != FL_PROCEDURE)
  4205. || (fsym->attr.proc_pointer
  4206. && !(e->expr_type == EXPR_VARIABLE
  4207. && e->symtree->n.sym->attr.dummy))
  4208. || (fsym->attr.proc_pointer
  4209. && e->expr_type == EXPR_VARIABLE
  4210. && gfc_is_proc_ptr_comp (e))
  4211. || (fsym->attr.allocatable
  4212. && fsym->attr.flavor != FL_PROCEDURE)))
  4213. {
  4214. /* Scalar pointer dummy args require an extra level of
  4215. indirection. The null pointer already contains
  4216. this level of indirection. */
  4217. parm_kind = SCALAR_POINTER;
  4218. parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
  4219. }
  4220. }
  4221. }
  4222. else if (e->ts.type == BT_CLASS
  4223. && fsym && fsym->ts.type == BT_CLASS
  4224. && (CLASS_DATA (fsym)->attr.dimension
  4225. || CLASS_DATA (fsym)->attr.codimension))
  4226. {
  4227. /* Pass a class array. */
  4228. parmse.use_offset = 1;
  4229. gfc_conv_expr_descriptor (&parmse, e);
  4230. /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
  4231. allocated on entry, it must be deallocated. */
  4232. if (fsym->attr.intent == INTENT_OUT
  4233. && CLASS_DATA (fsym)->attr.allocatable)
  4234. {
  4235. stmtblock_t block;
  4236. tree ptr;
  4237. gfc_init_block (&block);
  4238. ptr = parmse.expr;
  4239. ptr = gfc_class_data_get (ptr);
  4240. tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
  4241. NULL_TREE, NULL_TREE,
  4242. NULL_TREE, true, e,
  4243. false);
  4244. gfc_add_expr_to_block (&block, tmp);
  4245. tmp = fold_build2_loc (input_location, MODIFY_EXPR,
  4246. void_type_node, ptr,
  4247. null_pointer_node);
  4248. gfc_add_expr_to_block (&block, tmp);
  4249. gfc_reset_vptr (&block, e);
  4250. if (fsym->attr.optional
  4251. && e->expr_type == EXPR_VARIABLE
  4252. && (!e->ref
  4253. || (e->ref->type == REF_ARRAY
  4254. && e->ref->u.ar.type != AR_FULL))
  4255. && e->symtree->n.sym->attr.optional)
  4256. {
  4257. tmp = fold_build3_loc (input_location, COND_EXPR,
  4258. void_type_node,
  4259. gfc_conv_expr_present (e->symtree->n.sym),
  4260. gfc_finish_block (&block),
  4261. build_empty_stmt (input_location));
  4262. }
  4263. else
  4264. tmp = gfc_finish_block (&block);
  4265. gfc_add_expr_to_block (&se->pre, tmp);
  4266. }
  4267. /* The conversion does not repackage the reference to a class
  4268. array - _data descriptor. */
  4269. gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
  4270. fsym->attr.intent != INTENT_IN
  4271. && (CLASS_DATA (fsym)->attr.class_pointer
  4272. || CLASS_DATA (fsym)->attr.allocatable),
  4273. fsym->attr.optional
  4274. && e->expr_type == EXPR_VARIABLE
  4275. && e->symtree->n.sym->attr.optional,
  4276. CLASS_DATA (fsym)->attr.class_pointer
  4277. || CLASS_DATA (fsym)->attr.allocatable);
  4278. }
  4279. else
  4280. {
  4281. /* If the procedure requires an explicit interface, the actual
  4282. argument is passed according to the corresponding formal
  4283. argument. If the corresponding formal argument is a POINTER,
  4284. ALLOCATABLE or assumed shape, we do not use g77's calling
  4285. convention, and pass the address of the array descriptor
  4286. instead. Otherwise we use g77's calling convention. */
  4287. bool f;
  4288. f = (fsym != NULL)
  4289. && !(fsym->attr.pointer || fsym->attr.allocatable)
  4290. && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
  4291. && fsym->as->type != AS_ASSUMED_RANK;
  4292. if (comp)
  4293. f = f || !comp->attr.always_explicit;
  4294. else
  4295. f = f || !sym->attr.always_explicit;
  4296. /* If the argument is a function call that may not create
  4297. a temporary for the result, we have to check that we
  4298. can do it, i.e. that there is no alias between this
  4299. argument and another one. */
  4300. if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
  4301. {
  4302. gfc_expr *iarg;
  4303. sym_intent intent;
  4304. if (fsym != NULL)
  4305. intent = fsym->attr.intent;
  4306. else
  4307. intent = INTENT_UNKNOWN;
  4308. if (gfc_check_fncall_dependency (e, intent, sym, args,
  4309. NOT_ELEMENTAL))
  4310. parmse.force_tmp = 1;
  4311. iarg = e->value.function.actual->expr;
  4312. /* Temporary needed if aliasing due to host association. */
  4313. if (sym->attr.contained
  4314. && !sym->attr.pure
  4315. && !sym->attr.implicit_pure
  4316. && !sym->attr.use_assoc
  4317. && iarg->expr_type == EXPR_VARIABLE
  4318. && sym->ns == iarg->symtree->n.sym->ns)
  4319. parmse.force_tmp = 1;
  4320. /* Ditto within module. */
  4321. if (sym->attr.use_assoc
  4322. && !sym->attr.pure
  4323. && !sym->attr.implicit_pure
  4324. && iarg->expr_type == EXPR_VARIABLE
  4325. && sym->module == iarg->symtree->n.sym->module)
  4326. parmse.force_tmp = 1;
  4327. }
  4328. if (e->expr_type == EXPR_VARIABLE
  4329. && is_subref_array (e))
  4330. /* The actual argument is a component reference to an
  4331. array of derived types. In this case, the argument
  4332. is converted to a temporary, which is passed and then
  4333. written back after the procedure call. */
  4334. gfc_conv_subref_array_arg (&parmse, e, f,
  4335. fsym ? fsym->attr.intent : INTENT_INOUT,
  4336. fsym && fsym->attr.pointer);
  4337. else if (gfc_is_class_array_ref (e, NULL)
  4338. && fsym && fsym->ts.type == BT_DERIVED)
  4339. /* The actual argument is a component reference to an
  4340. array of derived types. In this case, the argument
  4341. is converted to a temporary, which is passed and then
  4342. written back after the procedure call.
  4343. OOP-TODO: Insert code so that if the dynamic type is
  4344. the same as the declared type, copy-in/copy-out does
  4345. not occur. */
  4346. gfc_conv_subref_array_arg (&parmse, e, f,
  4347. fsym ? fsym->attr.intent : INTENT_INOUT,
  4348. fsym && fsym->attr.pointer);
  4349. else if (gfc_is_alloc_class_array_function (e)
  4350. && fsym && fsym->ts.type == BT_DERIVED)
  4351. /* See previous comment. For function actual argument,
  4352. the write out is not needed so the intent is set as
  4353. intent in. */
  4354. {
  4355. e->must_finalize = 1;
  4356. gfc_conv_subref_array_arg (&parmse, e, f,
  4357. INTENT_IN,
  4358. fsym && fsym->attr.pointer);
  4359. }
  4360. else
  4361. gfc_conv_array_parameter (&parmse, e, f, fsym, sym->name, NULL);
  4362. /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
  4363. allocated on entry, it must be deallocated. */
  4364. if (fsym && fsym->attr.allocatable
  4365. && fsym->attr.intent == INTENT_OUT)
  4366. {
  4367. tmp = build_fold_indirect_ref_loc (input_location,
  4368. parmse.expr);
  4369. tmp = gfc_trans_dealloc_allocated (tmp, false, e);
  4370. if (fsym->attr.optional
  4371. && e->expr_type == EXPR_VARIABLE
  4372. && e->symtree->n.sym->attr.optional)
  4373. tmp = fold_build3_loc (input_location, COND_EXPR,
  4374. void_type_node,
  4375. gfc_conv_expr_present (e->symtree->n.sym),
  4376. tmp, build_empty_stmt (input_location));
  4377. gfc_add_expr_to_block (&se->pre, tmp);
  4378. }
  4379. }
  4380. }
  4381. /* The case with fsym->attr.optional is that of a user subroutine
  4382. with an interface indicating an optional argument. When we call
  4383. an intrinsic subroutine, however, fsym is NULL, but we might still
  4384. have an optional argument, so we proceed to the substitution
  4385. just in case. */
  4386. if (e && (fsym == NULL || fsym->attr.optional))
  4387. {
  4388. /* If an optional argument is itself an optional dummy argument,
  4389. check its presence and substitute a null if absent. This is
  4390. only needed when passing an array to an elemental procedure
  4391. as then array elements are accessed - or no NULL pointer is
  4392. allowed and a "1" or "0" should be passed if not present.
  4393. When passing a non-array-descriptor full array to a
  4394. non-array-descriptor dummy, no check is needed. For
  4395. array-descriptor actual to array-descriptor dummy, see
  4396. PR 41911 for why a check has to be inserted.
  4397. fsym == NULL is checked as intrinsics required the descriptor
  4398. but do not always set fsym. */
  4399. if (e->expr_type == EXPR_VARIABLE
  4400. && e->symtree->n.sym->attr.optional
  4401. && ((e->rank != 0 && sym->attr.elemental)
  4402. || e->representation.length || e->ts.type == BT_CHARACTER
  4403. || (e->rank != 0
  4404. && (fsym == NULL
  4405. || (fsym-> as
  4406. && (fsym->as->type == AS_ASSUMED_SHAPE
  4407. || fsym->as->type == AS_ASSUMED_RANK
  4408. || fsym->as->type == AS_DEFERRED))))))
  4409. gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
  4410. e->representation.length);
  4411. }
  4412. if (fsym && e)
  4413. {
  4414. /* Obtain the character length of an assumed character length
  4415. length procedure from the typespec. */
  4416. if (fsym->ts.type == BT_CHARACTER
  4417. && parmse.string_length == NULL_TREE
  4418. && e->ts.type == BT_PROCEDURE
  4419. && e->symtree->n.sym->ts.type == BT_CHARACTER
  4420. && e->symtree->n.sym->ts.u.cl->length != NULL
  4421. && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
  4422. {
  4423. gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
  4424. parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
  4425. }
  4426. }
  4427. if (fsym && need_interface_mapping && e)
  4428. gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
  4429. gfc_add_block_to_block (&se->pre, &parmse.pre);
  4430. gfc_add_block_to_block (&post, &parmse.post);
  4431. /* Allocated allocatable components of derived types must be
  4432. deallocated for non-variable scalars. Non-variable arrays are
  4433. dealt with in trans-array.c(gfc_conv_array_parameter). */
  4434. if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
  4435. && e->ts.u.derived->attr.alloc_comp
  4436. && !(e->symtree && e->symtree->n.sym->attr.pointer)
  4437. && (e->expr_type != EXPR_VARIABLE && !e->rank))
  4438. {
  4439. int parm_rank;
  4440. tmp = build_fold_indirect_ref_loc (input_location,
  4441. parmse.expr);
  4442. parm_rank = e->rank;
  4443. switch (parm_kind)
  4444. {
  4445. case (ELEMENTAL):
  4446. case (SCALAR):
  4447. parm_rank = 0;
  4448. break;
  4449. case (SCALAR_POINTER):
  4450. tmp = build_fold_indirect_ref_loc (input_location,
  4451. tmp);
  4452. break;
  4453. }
  4454. if (e->expr_type == EXPR_OP
  4455. && e->value.op.op == INTRINSIC_PARENTHESES
  4456. && e->value.op.op1->expr_type == EXPR_VARIABLE)
  4457. {
  4458. tree local_tmp;
  4459. local_tmp = gfc_evaluate_now (tmp, &se->pre);
  4460. local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
  4461. gfc_add_expr_to_block (&se->post, local_tmp);
  4462. }
  4463. if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
  4464. {
  4465. /* The derived type is passed to gfc_deallocate_alloc_comp.
  4466. Therefore, class actuals can handled correctly but derived
  4467. types passed to class formals need the _data component. */
  4468. tmp = gfc_class_data_get (tmp);
  4469. if (!CLASS_DATA (fsym)->attr.dimension)
  4470. tmp = build_fold_indirect_ref_loc (input_location, tmp);
  4471. }
  4472. tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
  4473. gfc_add_expr_to_block (&se->post, tmp);
  4474. }
  4475. /* Add argument checking of passing an unallocated/NULL actual to
  4476. a nonallocatable/nonpointer dummy. */
  4477. if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
  4478. {
  4479. symbol_attribute attr;
  4480. char *msg;
  4481. tree cond;
  4482. if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
  4483. attr = gfc_expr_attr (e);
  4484. else
  4485. goto end_pointer_check;
  4486. /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
  4487. allocatable to an optional dummy, cf. 12.5.2.12. */
  4488. if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
  4489. && (gfc_option.allow_std & GFC_STD_F2008) != 0)
  4490. goto end_pointer_check;
  4491. if (attr.optional)
  4492. {
  4493. /* If the actual argument is an optional pointer/allocatable and
  4494. the formal argument takes an nonpointer optional value,
  4495. it is invalid to pass a non-present argument on, even
  4496. though there is no technical reason for this in gfortran.
  4497. See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
  4498. tree present, null_ptr, type;
  4499. if (attr.allocatable
  4500. && (fsym == NULL || !fsym->attr.allocatable))
  4501. msg = xasprintf ("Allocatable actual argument '%s' is not "
  4502. "allocated or not present",
  4503. e->symtree->n.sym->name);
  4504. else if (attr.pointer
  4505. && (fsym == NULL || !fsym->attr.pointer))
  4506. msg = xasprintf ("Pointer actual argument '%s' is not "
  4507. "associated or not present",
  4508. e->symtree->n.sym->name);
  4509. else if (attr.proc_pointer
  4510. && (fsym == NULL || !fsym->attr.proc_pointer))
  4511. msg = xasprintf ("Proc-pointer actual argument '%s' is not "
  4512. "associated or not present",
  4513. e->symtree->n.sym->name);
  4514. else
  4515. goto end_pointer_check;
  4516. present = gfc_conv_expr_present (e->symtree->n.sym);
  4517. type = TREE_TYPE (present);
  4518. present = fold_build2_loc (input_location, EQ_EXPR,
  4519. boolean_type_node, present,
  4520. fold_convert (type,
  4521. null_pointer_node));
  4522. type = TREE_TYPE (parmse.expr);
  4523. null_ptr = fold_build2_loc (input_location, EQ_EXPR,
  4524. boolean_type_node, parmse.expr,
  4525. fold_convert (type,
  4526. null_pointer_node));
  4527. cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
  4528. boolean_type_node, present, null_ptr);
  4529. }
  4530. else
  4531. {
  4532. if (attr.allocatable
  4533. && (fsym == NULL || !fsym->attr.allocatable))
  4534. msg = xasprintf ("Allocatable actual argument '%s' is not "
  4535. "allocated", e->symtree->n.sym->name);
  4536. else if (attr.pointer
  4537. && (fsym == NULL || !fsym->attr.pointer))
  4538. msg = xasprintf ("Pointer actual argument '%s' is not "
  4539. "associated", e->symtree->n.sym->name);
  4540. else if (attr.proc_pointer
  4541. && (fsym == NULL || !fsym->attr.proc_pointer))
  4542. msg = xasprintf ("Proc-pointer actual argument '%s' is not "
  4543. "associated", e->symtree->n.sym->name);
  4544. else
  4545. goto end_pointer_check;
  4546. tmp = parmse.expr;
  4547. /* If the argument is passed by value, we need to strip the
  4548. INDIRECT_REF. */
  4549. if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
  4550. tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  4551. cond = fold_build2_loc (input_location, EQ_EXPR,
  4552. boolean_type_node, tmp,
  4553. fold_convert (TREE_TYPE (tmp),
  4554. null_pointer_node));
  4555. }
  4556. gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
  4557. msg);
  4558. free (msg);
  4559. }
  4560. end_pointer_check:
  4561. /* Deferred length dummies pass the character length by reference
  4562. so that the value can be returned. */
  4563. if (parmse.string_length && fsym && fsym->ts.deferred)
  4564. {
  4565. if (INDIRECT_REF_P (parmse.string_length))
  4566. /* In chains of functions/procedure calls the string_length already
  4567. is a pointer to the variable holding the length. Therefore
  4568. remove the deref on call. */
  4569. parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
  4570. else
  4571. {
  4572. tmp = parmse.string_length;
  4573. if (TREE_CODE (tmp) != VAR_DECL)
  4574. tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
  4575. parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
  4576. }
  4577. }
  4578. /* Character strings are passed as two parameters, a length and a
  4579. pointer - except for Bind(c) which only passes the pointer.
  4580. An unlimited polymorphic formal argument likewise does not
  4581. need the length. */
  4582. if (parmse.string_length != NULL_TREE
  4583. && !sym->attr.is_bind_c
  4584. && !(fsym && UNLIMITED_POLY (fsym)))
  4585. vec_safe_push (stringargs, parmse.string_length);
  4586. /* When calling __copy for character expressions to unlimited
  4587. polymorphic entities, the dst argument needs a string length. */
  4588. if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
  4589. && strncmp (sym->name, "__vtab_CHARACTER", 16) == 0
  4590. && arg->next && arg->next->expr
  4591. && arg->next->expr->ts.type == BT_DERIVED
  4592. && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
  4593. vec_safe_push (stringargs, parmse.string_length);
  4594. /* For descriptorless coarrays and assumed-shape coarray dummies, we
  4595. pass the token and the offset as additional arguments. */
  4596. if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
  4597. && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
  4598. && !fsym->attr.allocatable)
  4599. || (fsym->ts.type == BT_CLASS
  4600. && CLASS_DATA (fsym)->attr.codimension
  4601. && !CLASS_DATA (fsym)->attr.allocatable)))
  4602. {
  4603. /* Token and offset. */
  4604. vec_safe_push (stringargs, null_pointer_node);
  4605. vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
  4606. gcc_assert (fsym->attr.optional);
  4607. }
  4608. else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
  4609. && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
  4610. && !fsym->attr.allocatable)
  4611. || (fsym->ts.type == BT_CLASS
  4612. && CLASS_DATA (fsym)->attr.codimension
  4613. && !CLASS_DATA (fsym)->attr.allocatable)))
  4614. {
  4615. tree caf_decl, caf_type;
  4616. tree offset, tmp2;
  4617. caf_decl = gfc_get_tree_for_caf_expr (e);
  4618. caf_type = TREE_TYPE (caf_decl);
  4619. if (GFC_DESCRIPTOR_TYPE_P (caf_type)
  4620. && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
  4621. || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
  4622. tmp = gfc_conv_descriptor_token (caf_decl);
  4623. else if (DECL_LANG_SPECIFIC (caf_decl)
  4624. && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
  4625. tmp = GFC_DECL_TOKEN (caf_decl);
  4626. else
  4627. {
  4628. gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
  4629. && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
  4630. tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
  4631. }
  4632. vec_safe_push (stringargs, tmp);
  4633. if (GFC_DESCRIPTOR_TYPE_P (caf_type)
  4634. && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
  4635. offset = build_int_cst (gfc_array_index_type, 0);
  4636. else if (DECL_LANG_SPECIFIC (caf_decl)
  4637. && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
  4638. offset = GFC_DECL_CAF_OFFSET (caf_decl);
  4639. else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
  4640. offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
  4641. else
  4642. offset = build_int_cst (gfc_array_index_type, 0);
  4643. if (GFC_DESCRIPTOR_TYPE_P (caf_type))
  4644. tmp = gfc_conv_descriptor_data_get (caf_decl);
  4645. else
  4646. {
  4647. gcc_assert (POINTER_TYPE_P (caf_type));
  4648. tmp = caf_decl;
  4649. }
  4650. tmp2 = fsym->ts.type == BT_CLASS
  4651. ? gfc_class_data_get (parmse.expr) : parmse.expr;
  4652. if ((fsym->ts.type != BT_CLASS
  4653. && (fsym->as->type == AS_ASSUMED_SHAPE
  4654. || fsym->as->type == AS_ASSUMED_RANK))
  4655. || (fsym->ts.type == BT_CLASS
  4656. && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
  4657. || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
  4658. {
  4659. if (fsym->ts.type == BT_CLASS)
  4660. gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
  4661. else
  4662. {
  4663. gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
  4664. tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
  4665. }
  4666. gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
  4667. tmp2 = gfc_conv_descriptor_data_get (tmp2);
  4668. }
  4669. else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
  4670. tmp2 = gfc_conv_descriptor_data_get (tmp2);
  4671. else
  4672. {
  4673. gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
  4674. }
  4675. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  4676. gfc_array_index_type,
  4677. fold_convert (gfc_array_index_type, tmp2),
  4678. fold_convert (gfc_array_index_type, tmp));
  4679. offset = fold_build2_loc (input_location, PLUS_EXPR,
  4680. gfc_array_index_type, offset, tmp);
  4681. vec_safe_push (stringargs, offset);
  4682. }
  4683. vec_safe_push (arglist, parmse.expr);
  4684. }
  4685. gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
  4686. if (comp)
  4687. ts = comp->ts;
  4688. else
  4689. ts = sym->ts;
  4690. if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
  4691. se->string_length = build_int_cst (gfc_charlen_type_node, 1);
  4692. else if (ts.type == BT_CHARACTER)
  4693. {
  4694. if (ts.u.cl->length == NULL)
  4695. {
  4696. /* Assumed character length results are not allowed by 5.1.1.5 of the
  4697. standard and are trapped in resolve.c; except in the case of SPREAD
  4698. (and other intrinsics?) and dummy functions. In the case of SPREAD,
  4699. we take the character length of the first argument for the result.
  4700. For dummies, we have to look through the formal argument list for
  4701. this function and use the character length found there.*/
  4702. if (ts.deferred)
  4703. cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
  4704. else if (!sym->attr.dummy)
  4705. cl.backend_decl = (*stringargs)[0];
  4706. else
  4707. {
  4708. formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
  4709. for (; formal; formal = formal->next)
  4710. if (strcmp (formal->sym->name, sym->name) == 0)
  4711. cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
  4712. }
  4713. len = cl.backend_decl;
  4714. }
  4715. else
  4716. {
  4717. tree tmp;
  4718. /* Calculate the length of the returned string. */
  4719. gfc_init_se (&parmse, NULL);
  4720. if (need_interface_mapping)
  4721. gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
  4722. else
  4723. gfc_conv_expr (&parmse, ts.u.cl->length);
  4724. gfc_add_block_to_block (&se->pre, &parmse.pre);
  4725. gfc_add_block_to_block (&se->post, &parmse.post);
  4726. tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
  4727. tmp = fold_build2_loc (input_location, MAX_EXPR,
  4728. gfc_charlen_type_node, tmp,
  4729. build_int_cst (gfc_charlen_type_node, 0));
  4730. cl.backend_decl = tmp;
  4731. }
  4732. /* Set up a charlen structure for it. */
  4733. cl.next = NULL;
  4734. cl.length = NULL;
  4735. ts.u.cl = &cl;
  4736. len = cl.backend_decl;
  4737. }
  4738. byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
  4739. || (!comp && gfc_return_by_reference (sym));
  4740. if (byref)
  4741. {
  4742. if (se->direct_byref)
  4743. {
  4744. /* Sometimes, too much indirection can be applied; e.g. for
  4745. function_result = array_valued_recursive_function. */
  4746. if (TREE_TYPE (TREE_TYPE (se->expr))
  4747. && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
  4748. && GFC_DESCRIPTOR_TYPE_P
  4749. (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
  4750. se->expr = build_fold_indirect_ref_loc (input_location,
  4751. se->expr);
  4752. /* If the lhs of an assignment x = f(..) is allocatable and
  4753. f2003 is allowed, we must do the automatic reallocation.
  4754. TODO - deal with intrinsics, without using a temporary. */
  4755. if (flag_realloc_lhs
  4756. && se->ss && se->ss->loop_chain
  4757. && se->ss->loop_chain->is_alloc_lhs
  4758. && !expr->value.function.isym
  4759. && sym->result->as != NULL)
  4760. {
  4761. /* Evaluate the bounds of the result, if known. */
  4762. gfc_set_loop_bounds_from_array_spec (&mapping, se,
  4763. sym->result->as);
  4764. /* Perform the automatic reallocation. */
  4765. tmp = gfc_alloc_allocatable_for_assignment (se->loop,
  4766. expr, NULL);
  4767. gfc_add_expr_to_block (&se->pre, tmp);
  4768. /* Pass the temporary as the first argument. */
  4769. result = info->descriptor;
  4770. }
  4771. else
  4772. result = build_fold_indirect_ref_loc (input_location,
  4773. se->expr);
  4774. vec_safe_push (retargs, se->expr);
  4775. }
  4776. else if (comp && comp->attr.dimension)
  4777. {
  4778. gcc_assert (se->loop && info);
  4779. /* Set the type of the array. */
  4780. tmp = gfc_typenode_for_spec (&comp->ts);
  4781. gcc_assert (se->ss->dimen == se->loop->dimen);
  4782. /* Evaluate the bounds of the result, if known. */
  4783. gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
  4784. /* If the lhs of an assignment x = f(..) is allocatable and
  4785. f2003 is allowed, we must not generate the function call
  4786. here but should just send back the results of the mapping.
  4787. This is signalled by the function ss being flagged. */
  4788. if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
  4789. {
  4790. gfc_free_interface_mapping (&mapping);
  4791. return has_alternate_specifier;
  4792. }
  4793. /* Create a temporary to store the result. In case the function
  4794. returns a pointer, the temporary will be a shallow copy and
  4795. mustn't be deallocated. */
  4796. callee_alloc = comp->attr.allocatable || comp->attr.pointer;
  4797. gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
  4798. tmp, NULL_TREE, false,
  4799. !comp->attr.pointer, callee_alloc,
  4800. &se->ss->info->expr->where);
  4801. /* Pass the temporary as the first argument. */
  4802. result = info->descriptor;
  4803. tmp = gfc_build_addr_expr (NULL_TREE, result);
  4804. vec_safe_push (retargs, tmp);
  4805. }
  4806. else if (!comp && sym->result->attr.dimension)
  4807. {
  4808. gcc_assert (se->loop && info);
  4809. /* Set the type of the array. */
  4810. tmp = gfc_typenode_for_spec (&ts);
  4811. gcc_assert (se->ss->dimen == se->loop->dimen);
  4812. /* Evaluate the bounds of the result, if known. */
  4813. gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
  4814. /* If the lhs of an assignment x = f(..) is allocatable and
  4815. f2003 is allowed, we must not generate the function call
  4816. here but should just send back the results of the mapping.
  4817. This is signalled by the function ss being flagged. */
  4818. if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
  4819. {
  4820. gfc_free_interface_mapping (&mapping);
  4821. return has_alternate_specifier;
  4822. }
  4823. /* Create a temporary to store the result. In case the function
  4824. returns a pointer, the temporary will be a shallow copy and
  4825. mustn't be deallocated. */
  4826. callee_alloc = sym->attr.allocatable || sym->attr.pointer;
  4827. gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
  4828. tmp, NULL_TREE, false,
  4829. !sym->attr.pointer, callee_alloc,
  4830. &se->ss->info->expr->where);
  4831. /* Pass the temporary as the first argument. */
  4832. result = info->descriptor;
  4833. tmp = gfc_build_addr_expr (NULL_TREE, result);
  4834. vec_safe_push (retargs, tmp);
  4835. }
  4836. else if (ts.type == BT_CHARACTER)
  4837. {
  4838. /* Pass the string length. */
  4839. type = gfc_get_character_type (ts.kind, ts.u.cl);
  4840. type = build_pointer_type (type);
  4841. /* Return an address to a char[0:len-1]* temporary for
  4842. character pointers. */
  4843. if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
  4844. || (comp && (comp->attr.pointer || comp->attr.allocatable)))
  4845. {
  4846. var = gfc_create_var (type, "pstr");
  4847. if ((!comp && sym->attr.allocatable)
  4848. || (comp && comp->attr.allocatable))
  4849. {
  4850. gfc_add_modify (&se->pre, var,
  4851. fold_convert (TREE_TYPE (var),
  4852. null_pointer_node));
  4853. tmp = gfc_call_free (convert (pvoid_type_node, var));
  4854. gfc_add_expr_to_block (&se->post, tmp);
  4855. }
  4856. /* Provide an address expression for the function arguments. */
  4857. var = gfc_build_addr_expr (NULL_TREE, var);
  4858. }
  4859. else
  4860. var = gfc_conv_string_tmp (se, type, len);
  4861. vec_safe_push (retargs, var);
  4862. }
  4863. else
  4864. {
  4865. gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
  4866. type = gfc_get_complex_type (ts.kind);
  4867. var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
  4868. vec_safe_push (retargs, var);
  4869. }
  4870. /* Add the string length to the argument list. */
  4871. if (ts.type == BT_CHARACTER && ts.deferred)
  4872. {
  4873. tmp = len;
  4874. if (TREE_CODE (tmp) != VAR_DECL)
  4875. tmp = gfc_evaluate_now (len, &se->pre);
  4876. tmp = gfc_build_addr_expr (NULL_TREE, tmp);
  4877. vec_safe_push (retargs, tmp);
  4878. }
  4879. else if (ts.type == BT_CHARACTER)
  4880. vec_safe_push (retargs, len);
  4881. }
  4882. gfc_free_interface_mapping (&mapping);
  4883. /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
  4884. arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
  4885. + vec_safe_length (stringargs) + vec_safe_length (append_args));
  4886. vec_safe_reserve (retargs, arglen);
  4887. /* Add the return arguments. */
  4888. retargs->splice (arglist);
  4889. /* Add the hidden present status for optional+value to the arguments. */
  4890. retargs->splice (optionalargs);
  4891. /* Add the hidden string length parameters to the arguments. */
  4892. retargs->splice (stringargs);
  4893. /* We may want to append extra arguments here. This is used e.g. for
  4894. calls to libgfortran_matmul_??, which need extra information. */
  4895. if (!vec_safe_is_empty (append_args))
  4896. retargs->splice (append_args);
  4897. arglist = retargs;
  4898. /* Generate the actual call. */
  4899. if (base_object == NULL_TREE)
  4900. conv_function_val (se, sym, expr);
  4901. else
  4902. conv_base_obj_fcn_val (se, base_object, expr);
  4903. /* If there are alternate return labels, function type should be
  4904. integer. Can't modify the type in place though, since it can be shared
  4905. with other functions. For dummy arguments, the typing is done to
  4906. this result, even if it has to be repeated for each call. */
  4907. if (has_alternate_specifier
  4908. && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
  4909. {
  4910. if (!sym->attr.dummy)
  4911. {
  4912. TREE_TYPE (sym->backend_decl)
  4913. = build_function_type (integer_type_node,
  4914. TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
  4915. se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
  4916. }
  4917. else
  4918. TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
  4919. }
  4920. fntype = TREE_TYPE (TREE_TYPE (se->expr));
  4921. se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
  4922. /* If we have a pointer function, but we don't want a pointer, e.g.
  4923. something like
  4924. x = f()
  4925. where f is pointer valued, we have to dereference the result. */
  4926. if (!se->want_pointer && !byref
  4927. && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
  4928. || (comp && (comp->attr.pointer || comp->attr.allocatable))))
  4929. se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
  4930. /* f2c calling conventions require a scalar default real function to
  4931. return a double precision result. Convert this back to default
  4932. real. We only care about the cases that can happen in Fortran 77.
  4933. */
  4934. if (flag_f2c && sym->ts.type == BT_REAL
  4935. && sym->ts.kind == gfc_default_real_kind
  4936. && !sym->attr.always_explicit)
  4937. se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
  4938. /* A pure function may still have side-effects - it may modify its
  4939. parameters. */
  4940. TREE_SIDE_EFFECTS (se->expr) = 1;
  4941. #if 0
  4942. if (!sym->attr.pure)
  4943. TREE_SIDE_EFFECTS (se->expr) = 1;
  4944. #endif
  4945. if (byref)
  4946. {
  4947. /* Add the function call to the pre chain. There is no expression. */
  4948. gfc_add_expr_to_block (&se->pre, se->expr);
  4949. se->expr = NULL_TREE;
  4950. if (!se->direct_byref)
  4951. {
  4952. if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
  4953. {
  4954. if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
  4955. {
  4956. /* Check the data pointer hasn't been modified. This would
  4957. happen in a function returning a pointer. */
  4958. tmp = gfc_conv_descriptor_data_get (info->descriptor);
  4959. tmp = fold_build2_loc (input_location, NE_EXPR,
  4960. boolean_type_node,
  4961. tmp, info->data);
  4962. gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
  4963. gfc_msg_fault);
  4964. }
  4965. se->expr = info->descriptor;
  4966. /* Bundle in the string length. */
  4967. se->string_length = len;
  4968. }
  4969. else if (ts.type == BT_CHARACTER)
  4970. {
  4971. /* Dereference for character pointer results. */
  4972. if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
  4973. || (comp && (comp->attr.pointer || comp->attr.allocatable)))
  4974. se->expr = build_fold_indirect_ref_loc (input_location, var);
  4975. else
  4976. se->expr = var;
  4977. se->string_length = len;
  4978. }
  4979. else
  4980. {
  4981. gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
  4982. se->expr = build_fold_indirect_ref_loc (input_location, var);
  4983. }
  4984. }
  4985. }
  4986. /* Follow the function call with the argument post block. */
  4987. if (byref)
  4988. {
  4989. gfc_add_block_to_block (&se->pre, &post);
  4990. /* Transformational functions of derived types with allocatable
  4991. components must have the result allocatable components copied. */
  4992. arg = expr->value.function.actual;
  4993. if (result && arg && expr->rank
  4994. && expr->value.function.isym
  4995. && expr->value.function.isym->transformational
  4996. && arg->expr->ts.type == BT_DERIVED
  4997. && arg->expr->ts.u.derived->attr.alloc_comp)
  4998. {
  4999. tree tmp2;
  5000. /* Copy the allocatable components. We have to use a
  5001. temporary here to prevent source allocatable components
  5002. from being corrupted. */
  5003. tmp2 = gfc_evaluate_now (result, &se->pre);
  5004. tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
  5005. result, tmp2, expr->rank);
  5006. gfc_add_expr_to_block (&se->pre, tmp);
  5007. tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
  5008. expr->rank);
  5009. gfc_add_expr_to_block (&se->pre, tmp);
  5010. /* Finally free the temporary's data field. */
  5011. tmp = gfc_conv_descriptor_data_get (tmp2);
  5012. tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
  5013. NULL_TREE, NULL_TREE, true,
  5014. NULL, false);
  5015. gfc_add_expr_to_block (&se->pre, tmp);
  5016. }
  5017. }
  5018. else
  5019. {
  5020. /* For a function with a class array result, save the result as
  5021. a temporary, set the info fields needed by the scalarizer and
  5022. call the finalization function of the temporary. Note that the
  5023. nullification of allocatable components needed by the result
  5024. is done in gfc_trans_assignment_1. */
  5025. if (expr && ((gfc_is_alloc_class_array_function (expr)
  5026. && se->ss && se->ss->loop)
  5027. || gfc_is_alloc_class_scalar_function (expr))
  5028. && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
  5029. && expr->must_finalize)
  5030. {
  5031. tree final_fndecl;
  5032. tree is_final;
  5033. int n;
  5034. if (se->ss && se->ss->loop)
  5035. {
  5036. se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
  5037. tmp = gfc_class_data_get (se->expr);
  5038. info->descriptor = tmp;
  5039. info->data = gfc_conv_descriptor_data_get (tmp);
  5040. info->offset = gfc_conv_descriptor_offset_get (tmp);
  5041. for (n = 0; n < se->ss->loop->dimen; n++)
  5042. {
  5043. tree dim = gfc_rank_cst[n];
  5044. se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
  5045. se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
  5046. }
  5047. }
  5048. else
  5049. {
  5050. /* TODO Eliminate the doubling of temporaries. This
  5051. one is necessary to ensure no memory leakage. */
  5052. se->expr = gfc_evaluate_now (se->expr, &se->pre);
  5053. tmp = gfc_class_data_get (se->expr);
  5054. tmp = gfc_conv_scalar_to_descriptor (se, tmp,
  5055. CLASS_DATA (expr->value.function.esym->result)->attr);
  5056. }
  5057. final_fndecl = gfc_class_vtab_final_get (se->expr);
  5058. is_final = fold_build2_loc (input_location, NE_EXPR,
  5059. boolean_type_node,
  5060. final_fndecl,
  5061. fold_convert (TREE_TYPE (final_fndecl),
  5062. null_pointer_node));
  5063. final_fndecl = build_fold_indirect_ref_loc (input_location,
  5064. final_fndecl);
  5065. tmp = build_call_expr_loc (input_location,
  5066. final_fndecl, 3,
  5067. gfc_build_addr_expr (NULL, tmp),
  5068. gfc_class_vtab_size_get (se->expr),
  5069. boolean_false_node);
  5070. tmp = fold_build3_loc (input_location, COND_EXPR,
  5071. void_type_node, is_final, tmp,
  5072. build_empty_stmt (input_location));
  5073. if (se->ss && se->ss->loop)
  5074. {
  5075. gfc_add_expr_to_block (&se->ss->loop->post, tmp);
  5076. tmp = gfc_call_free (convert (pvoid_type_node, info->data));
  5077. gfc_add_expr_to_block (&se->ss->loop->post, tmp);
  5078. }
  5079. else
  5080. {
  5081. gfc_add_expr_to_block (&se->post, tmp);
  5082. tmp = gfc_class_data_get (se->expr);
  5083. tmp = gfc_call_free (convert (pvoid_type_node, tmp));
  5084. gfc_add_expr_to_block (&se->post, tmp);
  5085. }
  5086. expr->must_finalize = 0;
  5087. }
  5088. gfc_add_block_to_block (&se->post, &post);
  5089. }
  5090. return has_alternate_specifier;
  5091. }
  5092. /* Fill a character string with spaces. */
  5093. static tree
  5094. fill_with_spaces (tree start, tree type, tree size)
  5095. {
  5096. stmtblock_t block, loop;
  5097. tree i, el, exit_label, cond, tmp;
  5098. /* For a simple char type, we can call memset(). */
  5099. if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
  5100. return build_call_expr_loc (input_location,
  5101. builtin_decl_explicit (BUILT_IN_MEMSET),
  5102. 3, start,
  5103. build_int_cst (gfc_get_int_type (gfc_c_int_kind),
  5104. lang_hooks.to_target_charset (' ')),
  5105. size);
  5106. /* Otherwise, we use a loop:
  5107. for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
  5108. *el = (type) ' ';
  5109. */
  5110. /* Initialize variables. */
  5111. gfc_init_block (&block);
  5112. i = gfc_create_var (sizetype, "i");
  5113. gfc_add_modify (&block, i, fold_convert (sizetype, size));
  5114. el = gfc_create_var (build_pointer_type (type), "el");
  5115. gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
  5116. exit_label = gfc_build_label_decl (NULL_TREE);
  5117. TREE_USED (exit_label) = 1;
  5118. /* Loop body. */
  5119. gfc_init_block (&loop);
  5120. /* Exit condition. */
  5121. cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
  5122. build_zero_cst (sizetype));
  5123. tmp = build1_v (GOTO_EXPR, exit_label);
  5124. tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
  5125. build_empty_stmt (input_location));
  5126. gfc_add_expr_to_block (&loop, tmp);
  5127. /* Assignment. */
  5128. gfc_add_modify (&loop,
  5129. fold_build1_loc (input_location, INDIRECT_REF, type, el),
  5130. build_int_cst (type, lang_hooks.to_target_charset (' ')));
  5131. /* Increment loop variables. */
  5132. gfc_add_modify (&loop, i,
  5133. fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
  5134. TYPE_SIZE_UNIT (type)));
  5135. gfc_add_modify (&loop, el,
  5136. fold_build_pointer_plus_loc (input_location,
  5137. el, TYPE_SIZE_UNIT (type)));
  5138. /* Making the loop... actually loop! */
  5139. tmp = gfc_finish_block (&loop);
  5140. tmp = build1_v (LOOP_EXPR, tmp);
  5141. gfc_add_expr_to_block (&block, tmp);
  5142. /* The exit label. */
  5143. tmp = build1_v (LABEL_EXPR, exit_label);
  5144. gfc_add_expr_to_block (&block, tmp);
  5145. return gfc_finish_block (&block);
  5146. }
  5147. /* Generate code to copy a string. */
  5148. void
  5149. gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
  5150. int dkind, tree slength, tree src, int skind)
  5151. {
  5152. tree tmp, dlen, slen;
  5153. tree dsc;
  5154. tree ssc;
  5155. tree cond;
  5156. tree cond2;
  5157. tree tmp2;
  5158. tree tmp3;
  5159. tree tmp4;
  5160. tree chartype;
  5161. stmtblock_t tempblock;
  5162. gcc_assert (dkind == skind);
  5163. if (slength != NULL_TREE)
  5164. {
  5165. slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
  5166. ssc = gfc_string_to_single_character (slen, src, skind);
  5167. }
  5168. else
  5169. {
  5170. slen = build_int_cst (size_type_node, 1);
  5171. ssc = src;
  5172. }
  5173. if (dlength != NULL_TREE)
  5174. {
  5175. dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
  5176. dsc = gfc_string_to_single_character (dlen, dest, dkind);
  5177. }
  5178. else
  5179. {
  5180. dlen = build_int_cst (size_type_node, 1);
  5181. dsc = dest;
  5182. }
  5183. /* Assign directly if the types are compatible. */
  5184. if (dsc != NULL_TREE && ssc != NULL_TREE
  5185. && TREE_TYPE (dsc) == TREE_TYPE (ssc))
  5186. {
  5187. gfc_add_modify (block, dsc, ssc);
  5188. return;
  5189. }
  5190. /* Do nothing if the destination length is zero. */
  5191. cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
  5192. build_int_cst (size_type_node, 0));
  5193. /* The following code was previously in _gfortran_copy_string:
  5194. // The two strings may overlap so we use memmove.
  5195. void
  5196. copy_string (GFC_INTEGER_4 destlen, char * dest,
  5197. GFC_INTEGER_4 srclen, const char * src)
  5198. {
  5199. if (srclen >= destlen)
  5200. {
  5201. // This will truncate if too long.
  5202. memmove (dest, src, destlen);
  5203. }
  5204. else
  5205. {
  5206. memmove (dest, src, srclen);
  5207. // Pad with spaces.
  5208. memset (&dest[srclen], ' ', destlen - srclen);
  5209. }
  5210. }
  5211. We're now doing it here for better optimization, but the logic
  5212. is the same. */
  5213. /* For non-default character kinds, we have to multiply the string
  5214. length by the base type size. */
  5215. chartype = gfc_get_char_type (dkind);
  5216. slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
  5217. fold_convert (size_type_node, slen),
  5218. fold_convert (size_type_node,
  5219. TYPE_SIZE_UNIT (chartype)));
  5220. dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
  5221. fold_convert (size_type_node, dlen),
  5222. fold_convert (size_type_node,
  5223. TYPE_SIZE_UNIT (chartype)));
  5224. if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
  5225. dest = fold_convert (pvoid_type_node, dest);
  5226. else
  5227. dest = gfc_build_addr_expr (pvoid_type_node, dest);
  5228. if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
  5229. src = fold_convert (pvoid_type_node, src);
  5230. else
  5231. src = gfc_build_addr_expr (pvoid_type_node, src);
  5232. /* Truncate string if source is too long. */
  5233. cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
  5234. dlen);
  5235. tmp2 = build_call_expr_loc (input_location,
  5236. builtin_decl_explicit (BUILT_IN_MEMMOVE),
  5237. 3, dest, src, dlen);
  5238. /* Else copy and pad with spaces. */
  5239. tmp3 = build_call_expr_loc (input_location,
  5240. builtin_decl_explicit (BUILT_IN_MEMMOVE),
  5241. 3, dest, src, slen);
  5242. tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
  5243. tmp4 = fill_with_spaces (tmp4, chartype,
  5244. fold_build2_loc (input_location, MINUS_EXPR,
  5245. TREE_TYPE(dlen), dlen, slen));
  5246. gfc_init_block (&tempblock);
  5247. gfc_add_expr_to_block (&tempblock, tmp3);
  5248. gfc_add_expr_to_block (&tempblock, tmp4);
  5249. tmp3 = gfc_finish_block (&tempblock);
  5250. /* The whole copy_string function is there. */
  5251. tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
  5252. tmp2, tmp3);
  5253. tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
  5254. build_empty_stmt (input_location));
  5255. gfc_add_expr_to_block (block, tmp);
  5256. }
  5257. /* Translate a statement function.
  5258. The value of a statement function reference is obtained by evaluating the
  5259. expression using the values of the actual arguments for the values of the
  5260. corresponding dummy arguments. */
  5261. static void
  5262. gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
  5263. {
  5264. gfc_symbol *sym;
  5265. gfc_symbol *fsym;
  5266. gfc_formal_arglist *fargs;
  5267. gfc_actual_arglist *args;
  5268. gfc_se lse;
  5269. gfc_se rse;
  5270. gfc_saved_var *saved_vars;
  5271. tree *temp_vars;
  5272. tree type;
  5273. tree tmp;
  5274. int n;
  5275. sym = expr->symtree->n.sym;
  5276. args = expr->value.function.actual;
  5277. gfc_init_se (&lse, NULL);
  5278. gfc_init_se (&rse, NULL);
  5279. n = 0;
  5280. for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
  5281. n++;
  5282. saved_vars = XCNEWVEC (gfc_saved_var, n);
  5283. temp_vars = XCNEWVEC (tree, n);
  5284. for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
  5285. fargs = fargs->next, n++)
  5286. {
  5287. /* Each dummy shall be specified, explicitly or implicitly, to be
  5288. scalar. */
  5289. gcc_assert (fargs->sym->attr.dimension == 0);
  5290. fsym = fargs->sym;
  5291. if (fsym->ts.type == BT_CHARACTER)
  5292. {
  5293. /* Copy string arguments. */
  5294. tree arglen;
  5295. gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
  5296. && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
  5297. /* Create a temporary to hold the value. */
  5298. if (fsym->ts.u.cl->backend_decl == NULL_TREE)
  5299. fsym->ts.u.cl->backend_decl
  5300. = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
  5301. type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
  5302. temp_vars[n] = gfc_create_var (type, fsym->name);
  5303. arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
  5304. gfc_conv_expr (&rse, args->expr);
  5305. gfc_conv_string_parameter (&rse);
  5306. gfc_add_block_to_block (&se->pre, &lse.pre);
  5307. gfc_add_block_to_block (&se->pre, &rse.pre);
  5308. gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
  5309. rse.string_length, rse.expr, fsym->ts.kind);
  5310. gfc_add_block_to_block (&se->pre, &lse.post);
  5311. gfc_add_block_to_block (&se->pre, &rse.post);
  5312. }
  5313. else
  5314. {
  5315. /* For everything else, just evaluate the expression. */
  5316. /* Create a temporary to hold the value. */
  5317. type = gfc_typenode_for_spec (&fsym->ts);
  5318. temp_vars[n] = gfc_create_var (type, fsym->name);
  5319. gfc_conv_expr (&lse, args->expr);
  5320. gfc_add_block_to_block (&se->pre, &lse.pre);
  5321. gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
  5322. gfc_add_block_to_block (&se->pre, &lse.post);
  5323. }
  5324. args = args->next;
  5325. }
  5326. /* Use the temporary variables in place of the real ones. */
  5327. for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
  5328. fargs = fargs->next, n++)
  5329. gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
  5330. gfc_conv_expr (se, sym->value);
  5331. if (sym->ts.type == BT_CHARACTER)
  5332. {
  5333. gfc_conv_const_charlen (sym->ts.u.cl);
  5334. /* Force the expression to the correct length. */
  5335. if (!INTEGER_CST_P (se->string_length)
  5336. || tree_int_cst_lt (se->string_length,
  5337. sym->ts.u.cl->backend_decl))
  5338. {
  5339. type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
  5340. tmp = gfc_create_var (type, sym->name);
  5341. tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
  5342. gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
  5343. sym->ts.kind, se->string_length, se->expr,
  5344. sym->ts.kind);
  5345. se->expr = tmp;
  5346. }
  5347. se->string_length = sym->ts.u.cl->backend_decl;
  5348. }
  5349. /* Restore the original variables. */
  5350. for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
  5351. fargs = fargs->next, n++)
  5352. gfc_restore_sym (fargs->sym, &saved_vars[n]);
  5353. free (temp_vars);
  5354. free (saved_vars);
  5355. }
  5356. /* Translate a function expression. */
  5357. static void
  5358. gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
  5359. {
  5360. gfc_symbol *sym;
  5361. if (expr->value.function.isym)
  5362. {
  5363. gfc_conv_intrinsic_function (se, expr);
  5364. return;
  5365. }
  5366. /* expr.value.function.esym is the resolved (specific) function symbol for
  5367. most functions. However this isn't set for dummy procedures. */
  5368. sym = expr->value.function.esym;
  5369. if (!sym)
  5370. sym = expr->symtree->n.sym;
  5371. /* The IEEE_ARITHMETIC functions are caught here. */
  5372. if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
  5373. if (gfc_conv_ieee_arithmetic_function (se, expr))
  5374. return;
  5375. /* We distinguish statement functions from general functions to improve
  5376. runtime performance. */
  5377. if (sym->attr.proc == PROC_ST_FUNCTION)
  5378. {
  5379. gfc_conv_statement_function (se, expr);
  5380. return;
  5381. }
  5382. gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
  5383. NULL);
  5384. }
  5385. /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
  5386. static bool
  5387. is_zero_initializer_p (gfc_expr * expr)
  5388. {
  5389. if (expr->expr_type != EXPR_CONSTANT)
  5390. return false;
  5391. /* We ignore constants with prescribed memory representations for now. */
  5392. if (expr->representation.string)
  5393. return false;
  5394. switch (expr->ts.type)
  5395. {
  5396. case BT_INTEGER:
  5397. return mpz_cmp_si (expr->value.integer, 0) == 0;
  5398. case BT_REAL:
  5399. return mpfr_zero_p (expr->value.real)
  5400. && MPFR_SIGN (expr->value.real) >= 0;
  5401. case BT_LOGICAL:
  5402. return expr->value.logical == 0;
  5403. case BT_COMPLEX:
  5404. return mpfr_zero_p (mpc_realref (expr->value.complex))
  5405. && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
  5406. && mpfr_zero_p (mpc_imagref (expr->value.complex))
  5407. && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
  5408. default:
  5409. break;
  5410. }
  5411. return false;
  5412. }
  5413. static void
  5414. gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
  5415. {
  5416. gfc_ss *ss;
  5417. ss = se->ss;
  5418. gcc_assert (ss != NULL && ss != gfc_ss_terminator);
  5419. gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
  5420. gfc_conv_tmp_array_ref (se);
  5421. }
  5422. /* Build a static initializer. EXPR is the expression for the initial value.
  5423. The other parameters describe the variable of the component being
  5424. initialized. EXPR may be null. */
  5425. tree
  5426. gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
  5427. bool array, bool pointer, bool procptr)
  5428. {
  5429. gfc_se se;
  5430. if (!(expr || pointer || procptr))
  5431. return NULL_TREE;
  5432. /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
  5433. (these are the only two iso_c_binding derived types that can be
  5434. used as initialization expressions). If so, we need to modify
  5435. the 'expr' to be that for a (void *). */
  5436. if (expr != NULL && expr->ts.type == BT_DERIVED
  5437. && expr->ts.is_iso_c && expr->ts.u.derived)
  5438. {
  5439. gfc_symbol *derived = expr->ts.u.derived;
  5440. /* The derived symbol has already been converted to a (void *). Use
  5441. its kind. */
  5442. expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
  5443. expr->ts.f90_type = derived->ts.f90_type;
  5444. gfc_init_se (&se, NULL);
  5445. gfc_conv_constant (&se, expr);
  5446. gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
  5447. return se.expr;
  5448. }
  5449. if (array && !procptr)
  5450. {
  5451. tree ctor;
  5452. /* Arrays need special handling. */
  5453. if (pointer)
  5454. ctor = gfc_build_null_descriptor (type);
  5455. /* Special case assigning an array to zero. */
  5456. else if (is_zero_initializer_p (expr))
  5457. ctor = build_constructor (type, NULL);
  5458. else
  5459. ctor = gfc_conv_array_initializer (type, expr);
  5460. TREE_STATIC (ctor) = 1;
  5461. return ctor;
  5462. }
  5463. else if (pointer || procptr)
  5464. {
  5465. if (ts->type == BT_CLASS && !procptr)
  5466. {
  5467. gfc_init_se (&se, NULL);
  5468. gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
  5469. gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
  5470. TREE_STATIC (se.expr) = 1;
  5471. return se.expr;
  5472. }
  5473. else if (!expr || expr->expr_type == EXPR_NULL)
  5474. return fold_convert (type, null_pointer_node);
  5475. else
  5476. {
  5477. gfc_init_se (&se, NULL);
  5478. se.want_pointer = 1;
  5479. gfc_conv_expr (&se, expr);
  5480. gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
  5481. return se.expr;
  5482. }
  5483. }
  5484. else
  5485. {
  5486. switch (ts->type)
  5487. {
  5488. case BT_DERIVED:
  5489. case BT_CLASS:
  5490. gfc_init_se (&se, NULL);
  5491. if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
  5492. gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
  5493. else
  5494. gfc_conv_structure (&se, expr, 1);
  5495. gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
  5496. TREE_STATIC (se.expr) = 1;
  5497. return se.expr;
  5498. case BT_CHARACTER:
  5499. {
  5500. tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
  5501. TREE_STATIC (ctor) = 1;
  5502. return ctor;
  5503. }
  5504. default:
  5505. gfc_init_se (&se, NULL);
  5506. gfc_conv_constant (&se, expr);
  5507. gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
  5508. return se.expr;
  5509. }
  5510. }
  5511. }
  5512. static tree
  5513. gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
  5514. {
  5515. gfc_se rse;
  5516. gfc_se lse;
  5517. gfc_ss *rss;
  5518. gfc_ss *lss;
  5519. gfc_array_info *lss_array;
  5520. stmtblock_t body;
  5521. stmtblock_t block;
  5522. gfc_loopinfo loop;
  5523. int n;
  5524. tree tmp;
  5525. gfc_start_block (&block);
  5526. /* Initialize the scalarizer. */
  5527. gfc_init_loopinfo (&loop);
  5528. gfc_init_se (&lse, NULL);
  5529. gfc_init_se (&rse, NULL);
  5530. /* Walk the rhs. */
  5531. rss = gfc_walk_expr (expr);
  5532. if (rss == gfc_ss_terminator)
  5533. /* The rhs is scalar. Add a ss for the expression. */
  5534. rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
  5535. /* Create a SS for the destination. */
  5536. lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
  5537. GFC_SS_COMPONENT);
  5538. lss_array = &lss->info->data.array;
  5539. lss_array->shape = gfc_get_shape (cm->as->rank);
  5540. lss_array->descriptor = dest;
  5541. lss_array->data = gfc_conv_array_data (dest);
  5542. lss_array->offset = gfc_conv_array_offset (dest);
  5543. for (n = 0; n < cm->as->rank; n++)
  5544. {
  5545. lss_array->start[n] = gfc_conv_array_lbound (dest, n);
  5546. lss_array->stride[n] = gfc_index_one_node;
  5547. mpz_init (lss_array->shape[n]);
  5548. mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
  5549. cm->as->lower[n]->value.integer);
  5550. mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
  5551. }
  5552. /* Associate the SS with the loop. */
  5553. gfc_add_ss_to_loop (&loop, lss);
  5554. gfc_add_ss_to_loop (&loop, rss);
  5555. /* Calculate the bounds of the scalarization. */
  5556. gfc_conv_ss_startstride (&loop);
  5557. /* Setup the scalarizing loops. */
  5558. gfc_conv_loop_setup (&loop, &expr->where);
  5559. /* Setup the gfc_se structures. */
  5560. gfc_copy_loopinfo_to_se (&lse, &loop);
  5561. gfc_copy_loopinfo_to_se (&rse, &loop);
  5562. rse.ss = rss;
  5563. gfc_mark_ss_chain_used (rss, 1);
  5564. lse.ss = lss;
  5565. gfc_mark_ss_chain_used (lss, 1);
  5566. /* Start the scalarized loop body. */
  5567. gfc_start_scalarized_body (&loop, &body);
  5568. gfc_conv_tmp_array_ref (&lse);
  5569. if (cm->ts.type == BT_CHARACTER)
  5570. lse.string_length = cm->ts.u.cl->backend_decl;
  5571. gfc_conv_expr (&rse, expr);
  5572. tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
  5573. gfc_add_expr_to_block (&body, tmp);
  5574. gcc_assert (rse.ss == gfc_ss_terminator);
  5575. /* Generate the copying loops. */
  5576. gfc_trans_scalarizing_loops (&loop, &body);
  5577. /* Wrap the whole thing up. */
  5578. gfc_add_block_to_block (&block, &loop.pre);
  5579. gfc_add_block_to_block (&block, &loop.post);
  5580. gcc_assert (lss_array->shape != NULL);
  5581. gfc_free_shape (&lss_array->shape, cm->as->rank);
  5582. gfc_cleanup_loop (&loop);
  5583. return gfc_finish_block (&block);
  5584. }
  5585. static tree
  5586. gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
  5587. gfc_expr * expr)
  5588. {
  5589. gfc_se se;
  5590. stmtblock_t block;
  5591. tree offset;
  5592. int n;
  5593. tree tmp;
  5594. tree tmp2;
  5595. gfc_array_spec *as;
  5596. gfc_expr *arg = NULL;
  5597. gfc_start_block (&block);
  5598. gfc_init_se (&se, NULL);
  5599. /* Get the descriptor for the expressions. */
  5600. se.want_pointer = 0;
  5601. gfc_conv_expr_descriptor (&se, expr);
  5602. gfc_add_block_to_block (&block, &se.pre);
  5603. gfc_add_modify (&block, dest, se.expr);
  5604. /* Deal with arrays of derived types with allocatable components. */
  5605. if (cm->ts.type == BT_DERIVED
  5606. && cm->ts.u.derived->attr.alloc_comp)
  5607. tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
  5608. se.expr, dest,
  5609. cm->as->rank);
  5610. else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
  5611. && CLASS_DATA(cm)->attr.allocatable)
  5612. {
  5613. if (cm->ts.u.derived->attr.alloc_comp)
  5614. tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
  5615. se.expr, dest,
  5616. expr->rank);
  5617. else
  5618. {
  5619. tmp = TREE_TYPE (dest);
  5620. tmp = gfc_duplicate_allocatable (dest, se.expr,
  5621. tmp, expr->rank);
  5622. }
  5623. }
  5624. else
  5625. tmp = gfc_duplicate_allocatable (dest, se.expr,
  5626. TREE_TYPE(cm->backend_decl),
  5627. cm->as->rank);
  5628. gfc_add_expr_to_block (&block, tmp);
  5629. gfc_add_block_to_block (&block, &se.post);
  5630. if (expr->expr_type != EXPR_VARIABLE)
  5631. gfc_conv_descriptor_data_set (&block, se.expr,
  5632. null_pointer_node);
  5633. /* We need to know if the argument of a conversion function is a
  5634. variable, so that the correct lower bound can be used. */
  5635. if (expr->expr_type == EXPR_FUNCTION
  5636. && expr->value.function.isym
  5637. && expr->value.function.isym->conversion
  5638. && expr->value.function.actual->expr
  5639. && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
  5640. arg = expr->value.function.actual->expr;
  5641. /* Obtain the array spec of full array references. */
  5642. if (arg)
  5643. as = gfc_get_full_arrayspec_from_expr (arg);
  5644. else
  5645. as = gfc_get_full_arrayspec_from_expr (expr);
  5646. /* Shift the lbound and ubound of temporaries to being unity,
  5647. rather than zero, based. Always calculate the offset. */
  5648. offset = gfc_conv_descriptor_offset_get (dest);
  5649. gfc_add_modify (&block, offset, gfc_index_zero_node);
  5650. tmp2 =gfc_create_var (gfc_array_index_type, NULL);
  5651. for (n = 0; n < expr->rank; n++)
  5652. {
  5653. tree span;
  5654. tree lbound;
  5655. /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
  5656. TODO It looks as if gfc_conv_expr_descriptor should return
  5657. the correct bounds and that the following should not be
  5658. necessary. This would simplify gfc_conv_intrinsic_bound
  5659. as well. */
  5660. if (as && as->lower[n])
  5661. {
  5662. gfc_se lbse;
  5663. gfc_init_se (&lbse, NULL);
  5664. gfc_conv_expr (&lbse, as->lower[n]);
  5665. gfc_add_block_to_block (&block, &lbse.pre);
  5666. lbound = gfc_evaluate_now (lbse.expr, &block);
  5667. }
  5668. else if (as && arg)
  5669. {
  5670. tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
  5671. lbound = gfc_conv_descriptor_lbound_get (tmp,
  5672. gfc_rank_cst[n]);
  5673. }
  5674. else if (as)
  5675. lbound = gfc_conv_descriptor_lbound_get (dest,
  5676. gfc_rank_cst[n]);
  5677. else
  5678. lbound = gfc_index_one_node;
  5679. lbound = fold_convert (gfc_array_index_type, lbound);
  5680. /* Shift the bounds and set the offset accordingly. */
  5681. tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
  5682. span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  5683. tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
  5684. tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  5685. span, lbound);
  5686. gfc_conv_descriptor_ubound_set (&block, dest,
  5687. gfc_rank_cst[n], tmp);
  5688. gfc_conv_descriptor_lbound_set (&block, dest,
  5689. gfc_rank_cst[n], lbound);
  5690. tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  5691. gfc_conv_descriptor_lbound_get (dest,
  5692. gfc_rank_cst[n]),
  5693. gfc_conv_descriptor_stride_get (dest,
  5694. gfc_rank_cst[n]));
  5695. gfc_add_modify (&block, tmp2, tmp);
  5696. tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  5697. offset, tmp2);
  5698. gfc_conv_descriptor_offset_set (&block, dest, tmp);
  5699. }
  5700. if (arg)
  5701. {
  5702. /* If a conversion expression has a null data pointer
  5703. argument, nullify the allocatable component. */
  5704. tree non_null_expr;
  5705. tree null_expr;
  5706. if (arg->symtree->n.sym->attr.allocatable
  5707. || arg->symtree->n.sym->attr.pointer)
  5708. {
  5709. non_null_expr = gfc_finish_block (&block);
  5710. gfc_start_block (&block);
  5711. gfc_conv_descriptor_data_set (&block, dest,
  5712. null_pointer_node);
  5713. null_expr = gfc_finish_block (&block);
  5714. tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
  5715. tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
  5716. fold_convert (TREE_TYPE (tmp), null_pointer_node));
  5717. return build3_v (COND_EXPR, tmp,
  5718. null_expr, non_null_expr);
  5719. }
  5720. }
  5721. return gfc_finish_block (&block);
  5722. }
  5723. /* Allocate or reallocate scalar component, as necessary. */
  5724. static void
  5725. alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
  5726. tree comp,
  5727. gfc_component *cm,
  5728. gfc_expr *expr2,
  5729. gfc_symbol *sym)
  5730. {
  5731. tree tmp;
  5732. tree ptr;
  5733. tree size;
  5734. tree size_in_bytes;
  5735. tree lhs_cl_size = NULL_TREE;
  5736. if (!comp)
  5737. return;
  5738. if (!expr2 || expr2->rank)
  5739. return;
  5740. realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
  5741. if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
  5742. {
  5743. char name[GFC_MAX_SYMBOL_LEN+9];
  5744. gfc_component *strlen;
  5745. /* Use the rhs string length and the lhs element size. */
  5746. gcc_assert (expr2->ts.type == BT_CHARACTER);
  5747. if (!expr2->ts.u.cl->backend_decl)
  5748. {
  5749. gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
  5750. gcc_assert (expr2->ts.u.cl->backend_decl);
  5751. }
  5752. size = expr2->ts.u.cl->backend_decl;
  5753. /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
  5754. component. */
  5755. sprintf (name, "_%s_length", cm->name);
  5756. strlen = gfc_find_component (sym, name, true, true);
  5757. lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
  5758. gfc_charlen_type_node,
  5759. TREE_OPERAND (comp, 0),
  5760. strlen->backend_decl, NULL_TREE);
  5761. tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
  5762. tmp = TYPE_SIZE_UNIT (tmp);
  5763. size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
  5764. TREE_TYPE (tmp), tmp,
  5765. fold_convert (TREE_TYPE (tmp), size));
  5766. }
  5767. else
  5768. {
  5769. /* Otherwise use the length in bytes of the rhs. */
  5770. size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
  5771. size_in_bytes = size;
  5772. }
  5773. size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
  5774. size_in_bytes, size_one_node);
  5775. if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
  5776. {
  5777. tmp = build_call_expr_loc (input_location,
  5778. builtin_decl_explicit (BUILT_IN_CALLOC),
  5779. 2, build_one_cst (size_type_node),
  5780. size_in_bytes);
  5781. tmp = fold_convert (TREE_TYPE (comp), tmp);
  5782. gfc_add_modify (block, comp, tmp);
  5783. }
  5784. else
  5785. {
  5786. tmp = build_call_expr_loc (input_location,
  5787. builtin_decl_explicit (BUILT_IN_MALLOC),
  5788. 1, size_in_bytes);
  5789. if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
  5790. ptr = gfc_class_data_get (comp);
  5791. else
  5792. ptr = comp;
  5793. tmp = fold_convert (TREE_TYPE (ptr), tmp);
  5794. gfc_add_modify (block, ptr, tmp);
  5795. }
  5796. if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
  5797. /* Update the lhs character length. */
  5798. gfc_add_modify (block, lhs_cl_size, size);
  5799. }
  5800. /* Assign a single component of a derived type constructor. */
  5801. static tree
  5802. gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
  5803. gfc_symbol *sym, bool init)
  5804. {
  5805. gfc_se se;
  5806. gfc_se lse;
  5807. stmtblock_t block;
  5808. tree tmp;
  5809. tree vtab;
  5810. gfc_start_block (&block);
  5811. if (cm->attr.pointer || cm->attr.proc_pointer)
  5812. {
  5813. /* Only care about pointers here, not about allocatables. */
  5814. gfc_init_se (&se, NULL);
  5815. /* Pointer component. */
  5816. if ((cm->attr.dimension || cm->attr.codimension)
  5817. && !cm->attr.proc_pointer)
  5818. {
  5819. /* Array pointer. */
  5820. if (expr->expr_type == EXPR_NULL)
  5821. gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
  5822. else
  5823. {
  5824. se.direct_byref = 1;
  5825. se.expr = dest;
  5826. gfc_conv_expr_descriptor (&se, expr);
  5827. gfc_add_block_to_block (&block, &se.pre);
  5828. gfc_add_block_to_block (&block, &se.post);
  5829. }
  5830. }
  5831. else
  5832. {
  5833. /* Scalar pointers. */
  5834. se.want_pointer = 1;
  5835. gfc_conv_expr (&se, expr);
  5836. gfc_add_block_to_block (&block, &se.pre);
  5837. if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
  5838. && expr->symtree->n.sym->attr.dummy)
  5839. se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
  5840. gfc_add_modify (&block, dest,
  5841. fold_convert (TREE_TYPE (dest), se.expr));
  5842. gfc_add_block_to_block (&block, &se.post);
  5843. }
  5844. }
  5845. else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
  5846. {
  5847. /* NULL initialization for CLASS components. */
  5848. tmp = gfc_trans_structure_assign (dest,
  5849. gfc_class_initializer (&cm->ts, expr),
  5850. false);
  5851. gfc_add_expr_to_block (&block, tmp);
  5852. }
  5853. else if ((cm->attr.dimension || cm->attr.codimension)
  5854. && !cm->attr.proc_pointer)
  5855. {
  5856. if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
  5857. gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
  5858. else if (cm->attr.allocatable)
  5859. {
  5860. tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
  5861. gfc_add_expr_to_block (&block, tmp);
  5862. }
  5863. else
  5864. {
  5865. tmp = gfc_trans_subarray_assign (dest, cm, expr);
  5866. gfc_add_expr_to_block (&block, tmp);
  5867. }
  5868. }
  5869. else if (cm->ts.type == BT_CLASS
  5870. && CLASS_DATA (cm)->attr.dimension
  5871. && CLASS_DATA (cm)->attr.allocatable
  5872. && expr->ts.type == BT_DERIVED)
  5873. {
  5874. vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
  5875. vtab = gfc_build_addr_expr (NULL_TREE, vtab);
  5876. tmp = gfc_class_vptr_get (dest);
  5877. gfc_add_modify (&block, tmp,
  5878. fold_convert (TREE_TYPE (tmp), vtab));
  5879. tmp = gfc_class_data_get (dest);
  5880. tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
  5881. gfc_add_expr_to_block (&block, tmp);
  5882. }
  5883. else if (init && (cm->attr.allocatable
  5884. || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable)))
  5885. {
  5886. /* Take care about non-array allocatable components here. The alloc_*
  5887. routine below is motivated by the alloc_scalar_allocatable_for_
  5888. assignment() routine, but with the realloc portions removed and
  5889. different input. */
  5890. alloc_scalar_allocatable_for_subcomponent_assignment (&block,
  5891. dest,
  5892. cm,
  5893. expr,
  5894. sym);
  5895. /* The remainder of these instructions follow the if (cm->attr.pointer)
  5896. if (!cm->attr.dimension) part above. */
  5897. gfc_init_se (&se, NULL);
  5898. gfc_conv_expr (&se, expr);
  5899. gfc_add_block_to_block (&block, &se.pre);
  5900. if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
  5901. && expr->symtree->n.sym->attr.dummy)
  5902. se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
  5903. if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
  5904. {
  5905. tmp = gfc_class_data_get (dest);
  5906. tmp = build_fold_indirect_ref_loc (input_location, tmp);
  5907. vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
  5908. vtab = gfc_build_addr_expr (NULL_TREE, vtab);
  5909. gfc_add_modify (&block, gfc_class_vptr_get (dest),
  5910. fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
  5911. }
  5912. else
  5913. tmp = build_fold_indirect_ref_loc (input_location, dest);
  5914. /* For deferred strings insert a memcpy. */
  5915. if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
  5916. {
  5917. tree size;
  5918. gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
  5919. size = size_of_string_in_bytes (cm->ts.kind, se.string_length
  5920. ? se.string_length
  5921. : expr->ts.u.cl->backend_decl);
  5922. tmp = gfc_build_memcpy_call (tmp, se.expr, size);
  5923. gfc_add_expr_to_block (&block, tmp);
  5924. }
  5925. else
  5926. gfc_add_modify (&block, tmp,
  5927. fold_convert (TREE_TYPE (tmp), se.expr));
  5928. gfc_add_block_to_block (&block, &se.post);
  5929. }
  5930. else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
  5931. {
  5932. if (expr->expr_type != EXPR_STRUCTURE)
  5933. {
  5934. gfc_init_se (&se, NULL);
  5935. gfc_conv_expr (&se, expr);
  5936. gfc_add_block_to_block (&block, &se.pre);
  5937. if (cm->ts.u.derived->attr.alloc_comp
  5938. && expr->expr_type == EXPR_VARIABLE)
  5939. {
  5940. tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
  5941. dest, expr->rank);
  5942. gfc_add_expr_to_block (&block, tmp);
  5943. }
  5944. else
  5945. gfc_add_modify (&block, dest,
  5946. fold_convert (TREE_TYPE (dest), se.expr));
  5947. gfc_add_block_to_block (&block, &se.post);
  5948. }
  5949. else
  5950. {
  5951. /* Nested constructors. */
  5952. tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
  5953. gfc_add_expr_to_block (&block, tmp);
  5954. }
  5955. }
  5956. else if (gfc_deferred_strlen (cm, &tmp))
  5957. {
  5958. tree strlen;
  5959. strlen = tmp;
  5960. gcc_assert (strlen);
  5961. strlen = fold_build3_loc (input_location, COMPONENT_REF,
  5962. TREE_TYPE (strlen),
  5963. TREE_OPERAND (dest, 0),
  5964. strlen, NULL_TREE);
  5965. if (expr->expr_type == EXPR_NULL)
  5966. {
  5967. tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
  5968. gfc_add_modify (&block, dest, tmp);
  5969. tmp = build_int_cst (TREE_TYPE (strlen), 0);
  5970. gfc_add_modify (&block, strlen, tmp);
  5971. }
  5972. else
  5973. {
  5974. tree size;
  5975. gfc_init_se (&se, NULL);
  5976. gfc_conv_expr (&se, expr);
  5977. size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
  5978. tmp = build_call_expr_loc (input_location,
  5979. builtin_decl_explicit (BUILT_IN_MALLOC),
  5980. 1, size);
  5981. gfc_add_modify (&block, dest,
  5982. fold_convert (TREE_TYPE (dest), tmp));
  5983. gfc_add_modify (&block, strlen, se.string_length);
  5984. tmp = gfc_build_memcpy_call (dest, se.expr, size);
  5985. gfc_add_expr_to_block (&block, tmp);
  5986. }
  5987. }
  5988. else if (!cm->attr.artificial)
  5989. {
  5990. /* Scalar component (excluding deferred parameters). */
  5991. gfc_init_se (&se, NULL);
  5992. gfc_init_se (&lse, NULL);
  5993. gfc_conv_expr (&se, expr);
  5994. if (cm->ts.type == BT_CHARACTER)
  5995. lse.string_length = cm->ts.u.cl->backend_decl;
  5996. lse.expr = dest;
  5997. tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
  5998. gfc_add_expr_to_block (&block, tmp);
  5999. }
  6000. return gfc_finish_block (&block);
  6001. }
  6002. /* Assign a derived type constructor to a variable. */
  6003. static tree
  6004. gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init)
  6005. {
  6006. gfc_constructor *c;
  6007. gfc_component *cm;
  6008. stmtblock_t block;
  6009. tree field;
  6010. tree tmp;
  6011. gfc_start_block (&block);
  6012. cm = expr->ts.u.derived->components;
  6013. if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
  6014. && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
  6015. || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
  6016. {
  6017. gfc_se se, lse;
  6018. gcc_assert (cm->backend_decl == NULL);
  6019. gfc_init_se (&se, NULL);
  6020. gfc_init_se (&lse, NULL);
  6021. gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
  6022. lse.expr = dest;
  6023. gfc_add_modify (&block, lse.expr,
  6024. fold_convert (TREE_TYPE (lse.expr), se.expr));
  6025. return gfc_finish_block (&block);
  6026. }
  6027. for (c = gfc_constructor_first (expr->value.constructor);
  6028. c; c = gfc_constructor_next (c), cm = cm->next)
  6029. {
  6030. /* Skip absent members in default initializers. */
  6031. if (!c->expr && !cm->attr.allocatable)
  6032. continue;
  6033. field = cm->backend_decl;
  6034. tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
  6035. dest, field, NULL_TREE);
  6036. if (!c->expr)
  6037. {
  6038. gfc_expr *e = gfc_get_null_expr (NULL);
  6039. tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
  6040. init);
  6041. gfc_free_expr (e);
  6042. }
  6043. else
  6044. tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
  6045. expr->ts.u.derived, init);
  6046. gfc_add_expr_to_block (&block, tmp);
  6047. }
  6048. return gfc_finish_block (&block);
  6049. }
  6050. /* Build an expression for a constructor. If init is nonzero then
  6051. this is part of a static variable initializer. */
  6052. void
  6053. gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
  6054. {
  6055. gfc_constructor *c;
  6056. gfc_component *cm;
  6057. tree val;
  6058. tree type;
  6059. tree tmp;
  6060. vec<constructor_elt, va_gc> *v = NULL;
  6061. gcc_assert (se->ss == NULL);
  6062. gcc_assert (expr->expr_type == EXPR_STRUCTURE);
  6063. type = gfc_typenode_for_spec (&expr->ts);
  6064. if (!init)
  6065. {
  6066. /* Create a temporary variable and fill it in. */
  6067. se->expr = gfc_create_var (type, expr->ts.u.derived->name);
  6068. /* The symtree in expr is NULL, if the code to generate is for
  6069. initializing the static members only. */
  6070. tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL);
  6071. gfc_add_expr_to_block (&se->pre, tmp);
  6072. return;
  6073. }
  6074. cm = expr->ts.u.derived->components;
  6075. for (c = gfc_constructor_first (expr->value.constructor);
  6076. c; c = gfc_constructor_next (c), cm = cm->next)
  6077. {
  6078. /* Skip absent members in default initializers and allocatable
  6079. components. Although the latter have a default initializer
  6080. of EXPR_NULL,... by default, the static nullify is not needed
  6081. since this is done every time we come into scope. */
  6082. if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
  6083. continue;
  6084. if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
  6085. && strcmp (cm->name, "_extends") == 0
  6086. && cm->initializer->symtree)
  6087. {
  6088. tree vtab;
  6089. gfc_symbol *vtabs;
  6090. vtabs = cm->initializer->symtree->n.sym;
  6091. vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
  6092. vtab = unshare_expr_without_location (vtab);
  6093. CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
  6094. }
  6095. else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
  6096. {
  6097. val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
  6098. CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
  6099. fold_convert (TREE_TYPE (cm->backend_decl),
  6100. val));
  6101. }
  6102. else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
  6103. CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
  6104. fold_convert (TREE_TYPE (cm->backend_decl),
  6105. integer_zero_node));
  6106. else
  6107. {
  6108. val = gfc_conv_initializer (c->expr, &cm->ts,
  6109. TREE_TYPE (cm->backend_decl),
  6110. cm->attr.dimension, cm->attr.pointer,
  6111. cm->attr.proc_pointer);
  6112. val = unshare_expr_without_location (val);
  6113. /* Append it to the constructor list. */
  6114. CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
  6115. }
  6116. }
  6117. se->expr = build_constructor (type, v);
  6118. if (init)
  6119. TREE_CONSTANT (se->expr) = 1;
  6120. }
  6121. /* Translate a substring expression. */
  6122. static void
  6123. gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
  6124. {
  6125. gfc_ref *ref;
  6126. ref = expr->ref;
  6127. gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
  6128. se->expr = gfc_build_wide_string_const (expr->ts.kind,
  6129. expr->value.character.length,
  6130. expr->value.character.string);
  6131. se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
  6132. TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
  6133. if (ref)
  6134. gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
  6135. }
  6136. /* Entry point for expression translation. Evaluates a scalar quantity.
  6137. EXPR is the expression to be translated, and SE is the state structure if
  6138. called from within the scalarized. */
  6139. void
  6140. gfc_conv_expr (gfc_se * se, gfc_expr * expr)
  6141. {
  6142. gfc_ss *ss;
  6143. ss = se->ss;
  6144. if (ss && ss->info->expr == expr
  6145. && (ss->info->type == GFC_SS_SCALAR
  6146. || ss->info->type == GFC_SS_REFERENCE))
  6147. {
  6148. gfc_ss_info *ss_info;
  6149. ss_info = ss->info;
  6150. /* Substitute a scalar expression evaluated outside the scalarization
  6151. loop. */
  6152. se->expr = ss_info->data.scalar.value;
  6153. /* If the reference can be NULL, the value field contains the reference,
  6154. not the value the reference points to (see gfc_add_loop_ss_code). */
  6155. if (ss_info->can_be_null_ref)
  6156. se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
  6157. se->string_length = ss_info->string_length;
  6158. gfc_advance_se_ss_chain (se);
  6159. return;
  6160. }
  6161. /* We need to convert the expressions for the iso_c_binding derived types.
  6162. C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
  6163. null_pointer_node. C_PTR and C_FUNPTR are converted to match the
  6164. typespec for the C_PTR and C_FUNPTR symbols, which has already been
  6165. updated to be an integer with a kind equal to the size of a (void *). */
  6166. if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
  6167. && expr->ts.u.derived->attr.is_bind_c)
  6168. {
  6169. if (expr->expr_type == EXPR_VARIABLE
  6170. && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
  6171. || expr->symtree->n.sym->intmod_sym_id
  6172. == ISOCBINDING_NULL_FUNPTR))
  6173. {
  6174. /* Set expr_type to EXPR_NULL, which will result in
  6175. null_pointer_node being used below. */
  6176. expr->expr_type = EXPR_NULL;
  6177. }
  6178. else
  6179. {
  6180. /* Update the type/kind of the expression to be what the new
  6181. type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
  6182. expr->ts.type = BT_INTEGER;
  6183. expr->ts.f90_type = BT_VOID;
  6184. expr->ts.kind = gfc_index_integer_kind;
  6185. }
  6186. }
  6187. gfc_fix_class_refs (expr);
  6188. switch (expr->expr_type)
  6189. {
  6190. case EXPR_OP:
  6191. gfc_conv_expr_op (se, expr);
  6192. break;
  6193. case EXPR_FUNCTION:
  6194. gfc_conv_function_expr (se, expr);
  6195. break;
  6196. case EXPR_CONSTANT:
  6197. gfc_conv_constant (se, expr);
  6198. break;
  6199. case EXPR_VARIABLE:
  6200. gfc_conv_variable (se, expr);
  6201. break;
  6202. case EXPR_NULL:
  6203. se->expr = null_pointer_node;
  6204. break;
  6205. case EXPR_SUBSTRING:
  6206. gfc_conv_substring_expr (se, expr);
  6207. break;
  6208. case EXPR_STRUCTURE:
  6209. gfc_conv_structure (se, expr, 0);
  6210. break;
  6211. case EXPR_ARRAY:
  6212. gfc_conv_array_constructor_expr (se, expr);
  6213. break;
  6214. default:
  6215. gcc_unreachable ();
  6216. break;
  6217. }
  6218. }
  6219. /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
  6220. of an assignment. */
  6221. void
  6222. gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
  6223. {
  6224. gfc_conv_expr (se, expr);
  6225. /* All numeric lvalues should have empty post chains. If not we need to
  6226. figure out a way of rewriting an lvalue so that it has no post chain. */
  6227. gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
  6228. }
  6229. /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
  6230. numeric expressions. Used for scalar values where inserting cleanup code
  6231. is inconvenient. */
  6232. void
  6233. gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
  6234. {
  6235. tree val;
  6236. gcc_assert (expr->ts.type != BT_CHARACTER);
  6237. gfc_conv_expr (se, expr);
  6238. if (se->post.head)
  6239. {
  6240. val = gfc_create_var (TREE_TYPE (se->expr), NULL);
  6241. gfc_add_modify (&se->pre, val, se->expr);
  6242. se->expr = val;
  6243. gfc_add_block_to_block (&se->pre, &se->post);
  6244. }
  6245. }
  6246. /* Helper to translate an expression and convert it to a particular type. */
  6247. void
  6248. gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
  6249. {
  6250. gfc_conv_expr_val (se, expr);
  6251. se->expr = convert (type, se->expr);
  6252. }
  6253. /* Converts an expression so that it can be passed by reference. Scalar
  6254. values only. */
  6255. void
  6256. gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
  6257. {
  6258. gfc_ss *ss;
  6259. tree var;
  6260. ss = se->ss;
  6261. if (ss && ss->info->expr == expr
  6262. && ss->info->type == GFC_SS_REFERENCE)
  6263. {
  6264. /* Returns a reference to the scalar evaluated outside the loop
  6265. for this case. */
  6266. gfc_conv_expr (se, expr);
  6267. if (expr->ts.type == BT_CHARACTER
  6268. && expr->expr_type != EXPR_FUNCTION)
  6269. gfc_conv_string_parameter (se);
  6270. else
  6271. se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
  6272. return;
  6273. }
  6274. if (expr->ts.type == BT_CHARACTER)
  6275. {
  6276. gfc_conv_expr (se, expr);
  6277. gfc_conv_string_parameter (se);
  6278. return;
  6279. }
  6280. if (expr->expr_type == EXPR_VARIABLE)
  6281. {
  6282. se->want_pointer = 1;
  6283. gfc_conv_expr (se, expr);
  6284. if (se->post.head)
  6285. {
  6286. var = gfc_create_var (TREE_TYPE (se->expr), NULL);
  6287. gfc_add_modify (&se->pre, var, se->expr);
  6288. gfc_add_block_to_block (&se->pre, &se->post);
  6289. se->expr = var;
  6290. }
  6291. return;
  6292. }
  6293. if (expr->expr_type == EXPR_FUNCTION
  6294. && ((expr->value.function.esym
  6295. && expr->value.function.esym->result->attr.pointer
  6296. && !expr->value.function.esym->result->attr.dimension)
  6297. || (!expr->value.function.esym && !expr->ref
  6298. && expr->symtree->n.sym->attr.pointer
  6299. && !expr->symtree->n.sym->attr.dimension)))
  6300. {
  6301. se->want_pointer = 1;
  6302. gfc_conv_expr (se, expr);
  6303. var = gfc_create_var (TREE_TYPE (se->expr), NULL);
  6304. gfc_add_modify (&se->pre, var, se->expr);
  6305. se->expr = var;
  6306. return;
  6307. }
  6308. gfc_conv_expr (se, expr);
  6309. /* Create a temporary var to hold the value. */
  6310. if (TREE_CONSTANT (se->expr))
  6311. {
  6312. tree tmp = se->expr;
  6313. STRIP_TYPE_NOPS (tmp);
  6314. var = build_decl (input_location,
  6315. CONST_DECL, NULL, TREE_TYPE (tmp));
  6316. DECL_INITIAL (var) = tmp;
  6317. TREE_STATIC (var) = 1;
  6318. pushdecl (var);
  6319. }
  6320. else
  6321. {
  6322. var = gfc_create_var (TREE_TYPE (se->expr), NULL);
  6323. gfc_add_modify (&se->pre, var, se->expr);
  6324. }
  6325. gfc_add_block_to_block (&se->pre, &se->post);
  6326. /* Take the address of that value. */
  6327. se->expr = gfc_build_addr_expr (NULL_TREE, var);
  6328. if (expr->ts.type == BT_DERIVED && expr->rank
  6329. && !gfc_is_finalizable (expr->ts.u.derived, NULL)
  6330. && expr->ts.u.derived->attr.alloc_comp
  6331. && expr->expr_type != EXPR_VARIABLE)
  6332. {
  6333. tree tmp;
  6334. tmp = build_fold_indirect_ref_loc (input_location, se->expr);
  6335. tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
  6336. /* The components shall be deallocated before
  6337. their containing entity. */
  6338. gfc_prepend_expr_to_block (&se->post, tmp);
  6339. }
  6340. }
  6341. tree
  6342. gfc_trans_pointer_assign (gfc_code * code)
  6343. {
  6344. return gfc_trans_pointer_assignment (code->expr1, code->expr2);
  6345. }
  6346. /* Generate code for a pointer assignment. */
  6347. tree
  6348. gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
  6349. {
  6350. gfc_expr *expr1_vptr = NULL;
  6351. gfc_se lse;
  6352. gfc_se rse;
  6353. stmtblock_t block;
  6354. tree desc;
  6355. tree tmp;
  6356. tree decl;
  6357. bool scalar;
  6358. gfc_ss *ss;
  6359. gfc_start_block (&block);
  6360. gfc_init_se (&lse, NULL);
  6361. /* Check whether the expression is a scalar or not; we cannot use
  6362. expr1->rank as it can be nonzero for proc pointers. */
  6363. ss = gfc_walk_expr (expr1);
  6364. scalar = ss == gfc_ss_terminator;
  6365. if (!scalar)
  6366. gfc_free_ss_chain (ss);
  6367. if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
  6368. && expr2->expr_type != EXPR_FUNCTION)
  6369. {
  6370. gfc_add_data_component (expr2);
  6371. /* The following is required as gfc_add_data_component doesn't
  6372. update ts.type if there is a tailing REF_ARRAY. */
  6373. expr2->ts.type = BT_DERIVED;
  6374. }
  6375. if (scalar)
  6376. {
  6377. /* Scalar pointers. */
  6378. lse.want_pointer = 1;
  6379. gfc_conv_expr (&lse, expr1);
  6380. gfc_init_se (&rse, NULL);
  6381. rse.want_pointer = 1;
  6382. gfc_conv_expr (&rse, expr2);
  6383. if (expr1->symtree->n.sym->attr.proc_pointer
  6384. && expr1->symtree->n.sym->attr.dummy)
  6385. lse.expr = build_fold_indirect_ref_loc (input_location,
  6386. lse.expr);
  6387. if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
  6388. && expr2->symtree->n.sym->attr.dummy)
  6389. rse.expr = build_fold_indirect_ref_loc (input_location,
  6390. rse.expr);
  6391. gfc_add_block_to_block (&block, &lse.pre);
  6392. gfc_add_block_to_block (&block, &rse.pre);
  6393. /* For string assignments to unlimited polymorphic pointers add an
  6394. assignment of the string_length to the _len component of the
  6395. pointer. */
  6396. if ((expr1->ts.type == BT_CLASS || expr1->ts.type == BT_DERIVED)
  6397. && expr1->ts.u.derived->attr.unlimited_polymorphic
  6398. && (expr2->ts.type == BT_CHARACTER ||
  6399. ((expr2->ts.type == BT_DERIVED || expr2->ts.type == BT_CLASS)
  6400. && expr2->ts.u.derived->attr.unlimited_polymorphic)))
  6401. {
  6402. gfc_expr *len_comp;
  6403. gfc_se se;
  6404. len_comp = gfc_get_len_component (expr1);
  6405. gfc_init_se (&se, NULL);
  6406. gfc_conv_expr (&se, len_comp);
  6407. /* ptr % _len = len (str) */
  6408. gfc_add_modify (&block, se.expr, rse.string_length);
  6409. lse.string_length = se.expr;
  6410. gfc_free_expr (len_comp);
  6411. }
  6412. /* Check character lengths if character expression. The test is only
  6413. really added if -fbounds-check is enabled. Exclude deferred
  6414. character length lefthand sides. */
  6415. if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
  6416. && !expr1->ts.deferred
  6417. && !expr1->symtree->n.sym->attr.proc_pointer
  6418. && !gfc_is_proc_ptr_comp (expr1))
  6419. {
  6420. gcc_assert (expr2->ts.type == BT_CHARACTER);
  6421. gcc_assert (lse.string_length && rse.string_length);
  6422. gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
  6423. lse.string_length, rse.string_length,
  6424. &block);
  6425. }
  6426. /* The assignment to an deferred character length sets the string
  6427. length to that of the rhs. */
  6428. if (expr1->ts.deferred)
  6429. {
  6430. if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
  6431. gfc_add_modify (&block, lse.string_length, rse.string_length);
  6432. else if (lse.string_length != NULL)
  6433. gfc_add_modify (&block, lse.string_length,
  6434. build_int_cst (gfc_charlen_type_node, 0));
  6435. }
  6436. if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS)
  6437. rse.expr = gfc_class_data_get (rse.expr);
  6438. gfc_add_modify (&block, lse.expr,
  6439. fold_convert (TREE_TYPE (lse.expr), rse.expr));
  6440. gfc_add_block_to_block (&block, &rse.post);
  6441. gfc_add_block_to_block (&block, &lse.post);
  6442. }
  6443. else
  6444. {
  6445. gfc_ref* remap;
  6446. bool rank_remap;
  6447. tree strlen_lhs;
  6448. tree strlen_rhs = NULL_TREE;
  6449. /* Array pointer. Find the last reference on the LHS and if it is an
  6450. array section ref, we're dealing with bounds remapping. In this case,
  6451. set it to AR_FULL so that gfc_conv_expr_descriptor does
  6452. not see it and process the bounds remapping afterwards explicitly. */
  6453. for (remap = expr1->ref; remap; remap = remap->next)
  6454. if (!remap->next && remap->type == REF_ARRAY
  6455. && remap->u.ar.type == AR_SECTION)
  6456. break;
  6457. rank_remap = (remap && remap->u.ar.end[0]);
  6458. gfc_init_se (&lse, NULL);
  6459. if (remap)
  6460. lse.descriptor_only = 1;
  6461. if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS
  6462. && expr1->ts.type == BT_CLASS)
  6463. expr1_vptr = gfc_copy_expr (expr1);
  6464. gfc_conv_expr_descriptor (&lse, expr1);
  6465. strlen_lhs = lse.string_length;
  6466. desc = lse.expr;
  6467. if (expr2->expr_type == EXPR_NULL)
  6468. {
  6469. /* Just set the data pointer to null. */
  6470. gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
  6471. }
  6472. else if (rank_remap)
  6473. {
  6474. /* If we are rank-remapping, just get the RHS's descriptor and
  6475. process this later on. */
  6476. gfc_init_se (&rse, NULL);
  6477. rse.direct_byref = 1;
  6478. rse.byref_noassign = 1;
  6479. if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
  6480. {
  6481. gfc_conv_function_expr (&rse, expr2);
  6482. if (expr1->ts.type != BT_CLASS)
  6483. rse.expr = gfc_class_data_get (rse.expr);
  6484. else
  6485. {
  6486. gfc_add_block_to_block (&block, &rse.pre);
  6487. tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
  6488. gfc_add_modify (&lse.pre, tmp, rse.expr);
  6489. gfc_add_vptr_component (expr1_vptr);
  6490. gfc_init_se (&rse, NULL);
  6491. rse.want_pointer = 1;
  6492. gfc_conv_expr (&rse, expr1_vptr);
  6493. gfc_add_modify (&lse.pre, rse.expr,
  6494. fold_convert (TREE_TYPE (rse.expr),
  6495. gfc_class_vptr_get (tmp)));
  6496. rse.expr = gfc_class_data_get (tmp);
  6497. }
  6498. }
  6499. else if (expr2->expr_type == EXPR_FUNCTION)
  6500. {
  6501. tree bound[GFC_MAX_DIMENSIONS];
  6502. int i;
  6503. for (i = 0; i < expr2->rank; i++)
  6504. bound[i] = NULL_TREE;
  6505. tmp = gfc_typenode_for_spec (&expr2->ts);
  6506. tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
  6507. bound, bound, 0,
  6508. GFC_ARRAY_POINTER_CONT, false);
  6509. tmp = gfc_create_var (tmp, "ptrtemp");
  6510. lse.descriptor_only = 0;
  6511. lse.expr = tmp;
  6512. lse.direct_byref = 1;
  6513. gfc_conv_expr_descriptor (&lse, expr2);
  6514. strlen_rhs = lse.string_length;
  6515. rse.expr = tmp;
  6516. }
  6517. else
  6518. {
  6519. gfc_conv_expr_descriptor (&rse, expr2);
  6520. strlen_rhs = rse.string_length;
  6521. }
  6522. }
  6523. else if (expr2->expr_type == EXPR_VARIABLE)
  6524. {
  6525. /* Assign directly to the LHS's descriptor. */
  6526. lse.descriptor_only = 0;
  6527. lse.direct_byref = 1;
  6528. gfc_conv_expr_descriptor (&lse, expr2);
  6529. strlen_rhs = lse.string_length;
  6530. /* If this is a subreference array pointer assignment, use the rhs
  6531. descriptor element size for the lhs span. */
  6532. if (expr1->symtree->n.sym->attr.subref_array_pointer)
  6533. {
  6534. decl = expr1->symtree->n.sym->backend_decl;
  6535. gfc_init_se (&rse, NULL);
  6536. rse.descriptor_only = 1;
  6537. gfc_conv_expr (&rse, expr2);
  6538. tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
  6539. tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
  6540. if (!INTEGER_CST_P (tmp))
  6541. gfc_add_block_to_block (&lse.post, &rse.pre);
  6542. gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
  6543. }
  6544. }
  6545. else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
  6546. {
  6547. gfc_init_se (&rse, NULL);
  6548. rse.want_pointer = 1;
  6549. gfc_conv_function_expr (&rse, expr2);
  6550. if (expr1->ts.type != BT_CLASS)
  6551. {
  6552. rse.expr = gfc_class_data_get (rse.expr);
  6553. gfc_add_modify (&lse.pre, desc, rse.expr);
  6554. }
  6555. else
  6556. {
  6557. gfc_add_block_to_block (&block, &rse.pre);
  6558. tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
  6559. gfc_add_modify (&lse.pre, tmp, rse.expr);
  6560. gfc_add_vptr_component (expr1_vptr);
  6561. gfc_init_se (&rse, NULL);
  6562. rse.want_pointer = 1;
  6563. gfc_conv_expr (&rse, expr1_vptr);
  6564. gfc_add_modify (&lse.pre, rse.expr,
  6565. fold_convert (TREE_TYPE (rse.expr),
  6566. gfc_class_vptr_get (tmp)));
  6567. rse.expr = gfc_class_data_get (tmp);
  6568. gfc_add_modify (&lse.pre, desc, rse.expr);
  6569. }
  6570. }
  6571. else
  6572. {
  6573. /* Assign to a temporary descriptor and then copy that
  6574. temporary to the pointer. */
  6575. tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
  6576. lse.descriptor_only = 0;
  6577. lse.expr = tmp;
  6578. lse.direct_byref = 1;
  6579. gfc_conv_expr_descriptor (&lse, expr2);
  6580. strlen_rhs = lse.string_length;
  6581. gfc_add_modify (&lse.pre, desc, tmp);
  6582. }
  6583. if (expr1_vptr)
  6584. gfc_free_expr (expr1_vptr);
  6585. gfc_add_block_to_block (&block, &lse.pre);
  6586. if (rank_remap)
  6587. gfc_add_block_to_block (&block, &rse.pre);
  6588. /* If we do bounds remapping, update LHS descriptor accordingly. */
  6589. if (remap)
  6590. {
  6591. int dim;
  6592. gcc_assert (remap->u.ar.dimen == expr1->rank);
  6593. if (rank_remap)
  6594. {
  6595. /* Do rank remapping. We already have the RHS's descriptor
  6596. converted in rse and now have to build the correct LHS
  6597. descriptor for it. */
  6598. tree dtype, data;
  6599. tree offs, stride;
  6600. tree lbound, ubound;
  6601. /* Set dtype. */
  6602. dtype = gfc_conv_descriptor_dtype (desc);
  6603. tmp = gfc_get_dtype (TREE_TYPE (desc));
  6604. gfc_add_modify (&block, dtype, tmp);
  6605. /* Copy data pointer. */
  6606. data = gfc_conv_descriptor_data_get (rse.expr);
  6607. gfc_conv_descriptor_data_set (&block, desc, data);
  6608. /* Copy offset but adjust it such that it would correspond
  6609. to a lbound of zero. */
  6610. offs = gfc_conv_descriptor_offset_get (rse.expr);
  6611. for (dim = 0; dim < expr2->rank; ++dim)
  6612. {
  6613. stride = gfc_conv_descriptor_stride_get (rse.expr,
  6614. gfc_rank_cst[dim]);
  6615. lbound = gfc_conv_descriptor_lbound_get (rse.expr,
  6616. gfc_rank_cst[dim]);
  6617. tmp = fold_build2_loc (input_location, MULT_EXPR,
  6618. gfc_array_index_type, stride, lbound);
  6619. offs = fold_build2_loc (input_location, PLUS_EXPR,
  6620. gfc_array_index_type, offs, tmp);
  6621. }
  6622. gfc_conv_descriptor_offset_set (&block, desc, offs);
  6623. /* Set the bounds as declared for the LHS and calculate strides as
  6624. well as another offset update accordingly. */
  6625. stride = gfc_conv_descriptor_stride_get (rse.expr,
  6626. gfc_rank_cst[0]);
  6627. for (dim = 0; dim < expr1->rank; ++dim)
  6628. {
  6629. gfc_se lower_se;
  6630. gfc_se upper_se;
  6631. gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
  6632. /* Convert declared bounds. */
  6633. gfc_init_se (&lower_se, NULL);
  6634. gfc_init_se (&upper_se, NULL);
  6635. gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
  6636. gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
  6637. gfc_add_block_to_block (&block, &lower_se.pre);
  6638. gfc_add_block_to_block (&block, &upper_se.pre);
  6639. lbound = fold_convert (gfc_array_index_type, lower_se.expr);
  6640. ubound = fold_convert (gfc_array_index_type, upper_se.expr);
  6641. lbound = gfc_evaluate_now (lbound, &block);
  6642. ubound = gfc_evaluate_now (ubound, &block);
  6643. gfc_add_block_to_block (&block, &lower_se.post);
  6644. gfc_add_block_to_block (&block, &upper_se.post);
  6645. /* Set bounds in descriptor. */
  6646. gfc_conv_descriptor_lbound_set (&block, desc,
  6647. gfc_rank_cst[dim], lbound);
  6648. gfc_conv_descriptor_ubound_set (&block, desc,
  6649. gfc_rank_cst[dim], ubound);
  6650. /* Set stride. */
  6651. stride = gfc_evaluate_now (stride, &block);
  6652. gfc_conv_descriptor_stride_set (&block, desc,
  6653. gfc_rank_cst[dim], stride);
  6654. /* Update offset. */
  6655. offs = gfc_conv_descriptor_offset_get (desc);
  6656. tmp = fold_build2_loc (input_location, MULT_EXPR,
  6657. gfc_array_index_type, lbound, stride);
  6658. offs = fold_build2_loc (input_location, MINUS_EXPR,
  6659. gfc_array_index_type, offs, tmp);
  6660. offs = gfc_evaluate_now (offs, &block);
  6661. gfc_conv_descriptor_offset_set (&block, desc, offs);
  6662. /* Update stride. */
  6663. tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
  6664. stride = fold_build2_loc (input_location, MULT_EXPR,
  6665. gfc_array_index_type, stride, tmp);
  6666. }
  6667. }
  6668. else
  6669. {
  6670. /* Bounds remapping. Just shift the lower bounds. */
  6671. gcc_assert (expr1->rank == expr2->rank);
  6672. for (dim = 0; dim < remap->u.ar.dimen; ++dim)
  6673. {
  6674. gfc_se lbound_se;
  6675. gcc_assert (remap->u.ar.start[dim]);
  6676. gcc_assert (!remap->u.ar.end[dim]);
  6677. gfc_init_se (&lbound_se, NULL);
  6678. gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
  6679. gfc_add_block_to_block (&block, &lbound_se.pre);
  6680. gfc_conv_shift_descriptor_lbound (&block, desc,
  6681. dim, lbound_se.expr);
  6682. gfc_add_block_to_block (&block, &lbound_se.post);
  6683. }
  6684. }
  6685. }
  6686. /* Check string lengths if applicable. The check is only really added
  6687. to the output code if -fbounds-check is enabled. */
  6688. if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
  6689. {
  6690. gcc_assert (expr2->ts.type == BT_CHARACTER);
  6691. gcc_assert (strlen_lhs && strlen_rhs);
  6692. gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
  6693. strlen_lhs, strlen_rhs, &block);
  6694. }
  6695. /* If rank remapping was done, check with -fcheck=bounds that
  6696. the target is at least as large as the pointer. */
  6697. if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
  6698. {
  6699. tree lsize, rsize;
  6700. tree fault;
  6701. const char* msg;
  6702. lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
  6703. rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
  6704. lsize = gfc_evaluate_now (lsize, &block);
  6705. rsize = gfc_evaluate_now (rsize, &block);
  6706. fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
  6707. rsize, lsize);
  6708. msg = _("Target of rank remapping is too small (%ld < %ld)");
  6709. gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
  6710. msg, rsize, lsize);
  6711. }
  6712. gfc_add_block_to_block (&block, &lse.post);
  6713. if (rank_remap)
  6714. gfc_add_block_to_block (&block, &rse.post);
  6715. }
  6716. return gfc_finish_block (&block);
  6717. }
  6718. /* Makes sure se is suitable for passing as a function string parameter. */
  6719. /* TODO: Need to check all callers of this function. It may be abused. */
  6720. void
  6721. gfc_conv_string_parameter (gfc_se * se)
  6722. {
  6723. tree type;
  6724. if (TREE_CODE (se->expr) == STRING_CST)
  6725. {
  6726. type = TREE_TYPE (TREE_TYPE (se->expr));
  6727. se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
  6728. return;
  6729. }
  6730. if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
  6731. {
  6732. if (TREE_CODE (se->expr) != INDIRECT_REF)
  6733. {
  6734. type = TREE_TYPE (se->expr);
  6735. se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
  6736. }
  6737. else
  6738. {
  6739. type = gfc_get_character_type_len (gfc_default_character_kind,
  6740. se->string_length);
  6741. type = build_pointer_type (type);
  6742. se->expr = gfc_build_addr_expr (type, se->expr);
  6743. }
  6744. }
  6745. gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
  6746. }
  6747. /* Generate code for assignment of scalar variables. Includes character
  6748. strings and derived types with allocatable components.
  6749. If you know that the LHS has no allocations, set dealloc to false.
  6750. DEEP_COPY has no effect if the typespec TS is not a derived type with
  6751. allocatable components. Otherwise, if it is set, an explicit copy of each
  6752. allocatable component is made. This is necessary as a simple copy of the
  6753. whole object would copy array descriptors as is, so that the lhs's
  6754. allocatable components would point to the rhs's after the assignment.
  6755. Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
  6756. necessary if the rhs is a non-pointer function, as the allocatable components
  6757. are not accessible by other means than the function's result after the
  6758. function has returned. It is even more subtle when temporaries are involved,
  6759. as the two following examples show:
  6760. 1. When we evaluate an array constructor, a temporary is created. Thus
  6761. there is theoretically no alias possible. However, no deep copy is
  6762. made for this temporary, so that if the constructor is made of one or
  6763. more variable with allocatable components, those components still point
  6764. to the variable's: DEEP_COPY should be set for the assignment from the
  6765. temporary to the lhs in that case.
  6766. 2. When assigning a scalar to an array, we evaluate the scalar value out
  6767. of the loop, store it into a temporary variable, and assign from that.
  6768. In that case, deep copying when assigning to the temporary would be a
  6769. waste of resources; however deep copies should happen when assigning from
  6770. the temporary to each array element: again DEEP_COPY should be set for
  6771. the assignment from the temporary to the lhs. */
  6772. tree
  6773. gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
  6774. bool l_is_temp, bool deep_copy, bool dealloc)
  6775. {
  6776. stmtblock_t block;
  6777. tree tmp;
  6778. tree cond;
  6779. gfc_init_block (&block);
  6780. if (ts.type == BT_CHARACTER)
  6781. {
  6782. tree rlen = NULL;
  6783. tree llen = NULL;
  6784. if (lse->string_length != NULL_TREE)
  6785. {
  6786. gfc_conv_string_parameter (lse);
  6787. gfc_add_block_to_block (&block, &lse->pre);
  6788. llen = lse->string_length;
  6789. }
  6790. if (rse->string_length != NULL_TREE)
  6791. {
  6792. gcc_assert (rse->string_length != NULL_TREE);
  6793. gfc_conv_string_parameter (rse);
  6794. gfc_add_block_to_block (&block, &rse->pre);
  6795. rlen = rse->string_length;
  6796. }
  6797. gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
  6798. rse->expr, ts.kind);
  6799. }
  6800. else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
  6801. {
  6802. tree tmp_var = NULL_TREE;
  6803. cond = NULL_TREE;
  6804. /* Are the rhs and the lhs the same? */
  6805. if (deep_copy)
  6806. {
  6807. cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  6808. gfc_build_addr_expr (NULL_TREE, lse->expr),
  6809. gfc_build_addr_expr (NULL_TREE, rse->expr));
  6810. cond = gfc_evaluate_now (cond, &lse->pre);
  6811. }
  6812. /* Deallocate the lhs allocated components as long as it is not
  6813. the same as the rhs. This must be done following the assignment
  6814. to prevent deallocating data that could be used in the rhs
  6815. expression. */
  6816. if (!l_is_temp && dealloc)
  6817. {
  6818. tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
  6819. tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
  6820. if (deep_copy)
  6821. tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
  6822. tmp);
  6823. gfc_add_expr_to_block (&lse->post, tmp);
  6824. }
  6825. gfc_add_block_to_block (&block, &rse->pre);
  6826. gfc_add_block_to_block (&block, &lse->pre);
  6827. gfc_add_modify (&block, lse->expr,
  6828. fold_convert (TREE_TYPE (lse->expr), rse->expr));
  6829. /* Restore pointer address of coarray components. */
  6830. if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
  6831. {
  6832. tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
  6833. tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
  6834. tmp);
  6835. gfc_add_expr_to_block (&block, tmp);
  6836. }
  6837. /* Do a deep copy if the rhs is a variable, if it is not the
  6838. same as the lhs. */
  6839. if (deep_copy)
  6840. {
  6841. tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
  6842. tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
  6843. tmp);
  6844. gfc_add_expr_to_block (&block, tmp);
  6845. }
  6846. }
  6847. else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
  6848. {
  6849. gfc_add_block_to_block (&block, &lse->pre);
  6850. gfc_add_block_to_block (&block, &rse->pre);
  6851. tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
  6852. TREE_TYPE (lse->expr), rse->expr);
  6853. gfc_add_modify (&block, lse->expr, tmp);
  6854. }
  6855. else
  6856. {
  6857. gfc_add_block_to_block (&block, &lse->pre);
  6858. gfc_add_block_to_block (&block, &rse->pre);
  6859. gfc_add_modify (&block, lse->expr,
  6860. fold_convert (TREE_TYPE (lse->expr), rse->expr));
  6861. }
  6862. gfc_add_block_to_block (&block, &lse->post);
  6863. gfc_add_block_to_block (&block, &rse->post);
  6864. return gfc_finish_block (&block);
  6865. }
  6866. /* There are quite a lot of restrictions on the optimisation in using an
  6867. array function assign without a temporary. */
  6868. static bool
  6869. arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
  6870. {
  6871. gfc_ref * ref;
  6872. bool seen_array_ref;
  6873. bool c = false;
  6874. gfc_symbol *sym = expr1->symtree->n.sym;
  6875. /* Play it safe with class functions assigned to a derived type. */
  6876. if (gfc_is_alloc_class_array_function (expr2)
  6877. && expr1->ts.type == BT_DERIVED)
  6878. return true;
  6879. /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
  6880. if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
  6881. return true;
  6882. /* Elemental functions are scalarized so that they don't need a
  6883. temporary in gfc_trans_assignment_1, so return a true. Otherwise,
  6884. they would need special treatment in gfc_trans_arrayfunc_assign. */
  6885. if (expr2->value.function.esym != NULL
  6886. && expr2->value.function.esym->attr.elemental)
  6887. return true;
  6888. /* Need a temporary if rhs is not FULL or a contiguous section. */
  6889. if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
  6890. return true;
  6891. /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
  6892. if (gfc_ref_needs_temporary_p (expr1->ref))
  6893. return true;
  6894. /* Functions returning pointers or allocatables need temporaries. */
  6895. c = expr2->value.function.esym
  6896. ? (expr2->value.function.esym->attr.pointer
  6897. || expr2->value.function.esym->attr.allocatable)
  6898. : (expr2->symtree->n.sym->attr.pointer
  6899. || expr2->symtree->n.sym->attr.allocatable);
  6900. if (c)
  6901. return true;
  6902. /* Character array functions need temporaries unless the
  6903. character lengths are the same. */
  6904. if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
  6905. {
  6906. if (expr1->ts.u.cl->length == NULL
  6907. || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
  6908. return true;
  6909. if (expr2->ts.u.cl->length == NULL
  6910. || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
  6911. return true;
  6912. if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
  6913. expr2->ts.u.cl->length->value.integer) != 0)
  6914. return true;
  6915. }
  6916. /* Check that no LHS component references appear during an array
  6917. reference. This is needed because we do not have the means to
  6918. span any arbitrary stride with an array descriptor. This check
  6919. is not needed for the rhs because the function result has to be
  6920. a complete type. */
  6921. seen_array_ref = false;
  6922. for (ref = expr1->ref; ref; ref = ref->next)
  6923. {
  6924. if (ref->type == REF_ARRAY)
  6925. seen_array_ref= true;
  6926. else if (ref->type == REF_COMPONENT && seen_array_ref)
  6927. return true;
  6928. }
  6929. /* Check for a dependency. */
  6930. if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
  6931. expr2->value.function.esym,
  6932. expr2->value.function.actual,
  6933. NOT_ELEMENTAL))
  6934. return true;
  6935. /* If we have reached here with an intrinsic function, we do not
  6936. need a temporary except in the particular case that reallocation
  6937. on assignment is active and the lhs is allocatable and a target. */
  6938. if (expr2->value.function.isym)
  6939. return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target);
  6940. /* If the LHS is a dummy, we need a temporary if it is not
  6941. INTENT(OUT). */
  6942. if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
  6943. return true;
  6944. /* If the lhs has been host_associated, is in common, a pointer or is
  6945. a target and the function is not using a RESULT variable, aliasing
  6946. can occur and a temporary is needed. */
  6947. if ((sym->attr.host_assoc
  6948. || sym->attr.in_common
  6949. || sym->attr.pointer
  6950. || sym->attr.cray_pointee
  6951. || sym->attr.target)
  6952. && expr2->symtree != NULL
  6953. && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
  6954. return true;
  6955. /* A PURE function can unconditionally be called without a temporary. */
  6956. if (expr2->value.function.esym != NULL
  6957. && expr2->value.function.esym->attr.pure)
  6958. return false;
  6959. /* Implicit_pure functions are those which could legally be declared
  6960. to be PURE. */
  6961. if (expr2->value.function.esym != NULL
  6962. && expr2->value.function.esym->attr.implicit_pure)
  6963. return false;
  6964. if (!sym->attr.use_assoc
  6965. && !sym->attr.in_common
  6966. && !sym->attr.pointer
  6967. && !sym->attr.target
  6968. && !sym->attr.cray_pointee
  6969. && expr2->value.function.esym)
  6970. {
  6971. /* A temporary is not needed if the function is not contained and
  6972. the variable is local or host associated and not a pointer or
  6973. a target. */
  6974. if (!expr2->value.function.esym->attr.contained)
  6975. return false;
  6976. /* A temporary is not needed if the lhs has never been host
  6977. associated and the procedure is contained. */
  6978. else if (!sym->attr.host_assoc)
  6979. return false;
  6980. /* A temporary is not needed if the variable is local and not
  6981. a pointer, a target or a result. */
  6982. if (sym->ns->parent
  6983. && expr2->value.function.esym->ns == sym->ns->parent)
  6984. return false;
  6985. }
  6986. /* Default to temporary use. */
  6987. return true;
  6988. }
  6989. /* Provide the loop info so that the lhs descriptor can be built for
  6990. reallocatable assignments from extrinsic function calls. */
  6991. static void
  6992. realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
  6993. gfc_loopinfo *loop)
  6994. {
  6995. /* Signal that the function call should not be made by
  6996. gfc_conv_loop_setup. */
  6997. se->ss->is_alloc_lhs = 1;
  6998. gfc_init_loopinfo (loop);
  6999. gfc_add_ss_to_loop (loop, *ss);
  7000. gfc_add_ss_to_loop (loop, se->ss);
  7001. gfc_conv_ss_startstride (loop);
  7002. gfc_conv_loop_setup (loop, where);
  7003. gfc_copy_loopinfo_to_se (se, loop);
  7004. gfc_add_block_to_block (&se->pre, &loop->pre);
  7005. gfc_add_block_to_block (&se->pre, &loop->post);
  7006. se->ss->is_alloc_lhs = 0;
  7007. }
  7008. /* For assignment to a reallocatable lhs from intrinsic functions,
  7009. replace the se.expr (ie. the result) with a temporary descriptor.
  7010. Null the data field so that the library allocates space for the
  7011. result. Free the data of the original descriptor after the function,
  7012. in case it appears in an argument expression and transfer the
  7013. result to the original descriptor. */
  7014. static void
  7015. fcncall_realloc_result (gfc_se *se, int rank)
  7016. {
  7017. tree desc;
  7018. tree res_desc;
  7019. tree tmp;
  7020. tree offset;
  7021. tree zero_cond;
  7022. int n;
  7023. /* Use the allocation done by the library. Substitute the lhs
  7024. descriptor with a copy, whose data field is nulled.*/
  7025. desc = build_fold_indirect_ref_loc (input_location, se->expr);
  7026. if (POINTER_TYPE_P (TREE_TYPE (desc)))
  7027. desc = build_fold_indirect_ref_loc (input_location, desc);
  7028. /* Unallocated, the descriptor does not have a dtype. */
  7029. tmp = gfc_conv_descriptor_dtype (desc);
  7030. gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
  7031. res_desc = gfc_evaluate_now (desc, &se->pre);
  7032. gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
  7033. se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
  7034. /* Free the lhs after the function call and copy the result data to
  7035. the lhs descriptor. */
  7036. tmp = gfc_conv_descriptor_data_get (desc);
  7037. zero_cond = fold_build2_loc (input_location, EQ_EXPR,
  7038. boolean_type_node, tmp,
  7039. build_int_cst (TREE_TYPE (tmp), 0));
  7040. zero_cond = gfc_evaluate_now (zero_cond, &se->post);
  7041. tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
  7042. gfc_add_expr_to_block (&se->post, tmp);
  7043. tmp = gfc_conv_descriptor_data_get (res_desc);
  7044. gfc_conv_descriptor_data_set (&se->post, desc, tmp);
  7045. /* Check that the shapes are the same between lhs and expression. */
  7046. for (n = 0 ; n < rank; n++)
  7047. {
  7048. tree tmp1;
  7049. tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
  7050. tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
  7051. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  7052. gfc_array_index_type, tmp, tmp1);
  7053. tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
  7054. tmp = fold_build2_loc (input_location, MINUS_EXPR,
  7055. gfc_array_index_type, tmp, tmp1);
  7056. tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
  7057. tmp = fold_build2_loc (input_location, PLUS_EXPR,
  7058. gfc_array_index_type, tmp, tmp1);
  7059. tmp = fold_build2_loc (input_location, NE_EXPR,
  7060. boolean_type_node, tmp,
  7061. gfc_index_zero_node);
  7062. tmp = gfc_evaluate_now (tmp, &se->post);
  7063. zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
  7064. boolean_type_node, tmp,
  7065. zero_cond);
  7066. }
  7067. /* 'zero_cond' being true is equal to lhs not being allocated or the
  7068. shapes being different. */
  7069. zero_cond = gfc_evaluate_now (zero_cond, &se->post);
  7070. /* Now reset the bounds returned from the function call to bounds based
  7071. on the lhs lbounds, except where the lhs is not allocated or the shapes
  7072. of 'variable and 'expr' are different. Set the offset accordingly. */
  7073. offset = gfc_index_zero_node;
  7074. for (n = 0 ; n < rank; n++)
  7075. {
  7076. tree lbound;
  7077. lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
  7078. lbound = fold_build3_loc (input_location, COND_EXPR,
  7079. gfc_array_index_type, zero_cond,
  7080. gfc_index_one_node, lbound);
  7081. lbound = gfc_evaluate_now (lbound, &se->post);
  7082. tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
  7083. tmp = fold_build2_loc (input_location, PLUS_EXPR,
  7084. gfc_array_index_type, tmp, lbound);
  7085. gfc_conv_descriptor_lbound_set (&se->post, desc,
  7086. gfc_rank_cst[n], lbound);
  7087. gfc_conv_descriptor_ubound_set (&se->post, desc,
  7088. gfc_rank_cst[n], tmp);
  7089. /* Set stride and accumulate the offset. */
  7090. tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
  7091. gfc_conv_descriptor_stride_set (&se->post, desc,
  7092. gfc_rank_cst[n], tmp);
  7093. tmp = fold_build2_loc (input_location, MULT_EXPR,
  7094. gfc_array_index_type, lbound, tmp);
  7095. offset = fold_build2_loc (input_location, MINUS_EXPR,
  7096. gfc_array_index_type, offset, tmp);
  7097. offset = gfc_evaluate_now (offset, &se->post);
  7098. }
  7099. gfc_conv_descriptor_offset_set (&se->post, desc, offset);
  7100. }
  7101. /* Try to translate array(:) = func (...), where func is a transformational
  7102. array function, without using a temporary. Returns NULL if this isn't the
  7103. case. */
  7104. static tree
  7105. gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
  7106. {
  7107. gfc_se se;
  7108. gfc_ss *ss = NULL;
  7109. gfc_component *comp = NULL;
  7110. gfc_loopinfo loop;
  7111. if (arrayfunc_assign_needs_temporary (expr1, expr2))
  7112. return NULL;
  7113. /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
  7114. functions. */
  7115. comp = gfc_get_proc_ptr_comp (expr2);
  7116. gcc_assert (expr2->value.function.isym
  7117. || (comp && comp->attr.dimension)
  7118. || (!comp && gfc_return_by_reference (expr2->value.function.esym)
  7119. && expr2->value.function.esym->result->attr.dimension));
  7120. gfc_init_se (&se, NULL);
  7121. gfc_start_block (&se.pre);
  7122. se.want_pointer = 1;
  7123. gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
  7124. if (expr1->ts.type == BT_DERIVED
  7125. && expr1->ts.u.derived->attr.alloc_comp)
  7126. {
  7127. tree tmp;
  7128. tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
  7129. expr1->rank);
  7130. gfc_add_expr_to_block (&se.pre, tmp);
  7131. }
  7132. se.direct_byref = 1;
  7133. se.ss = gfc_walk_expr (expr2);
  7134. gcc_assert (se.ss != gfc_ss_terminator);
  7135. /* Reallocate on assignment needs the loopinfo for extrinsic functions.
  7136. This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
  7137. Clearly, this cannot be done for an allocatable function result, since
  7138. the shape of the result is unknown and, in any case, the function must
  7139. correctly take care of the reallocation internally. For intrinsic
  7140. calls, the array data is freed and the library takes care of allocation.
  7141. TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
  7142. to the library. */
  7143. if (flag_realloc_lhs
  7144. && gfc_is_reallocatable_lhs (expr1)
  7145. && !gfc_expr_attr (expr1).codimension
  7146. && !gfc_is_coindexed (expr1)
  7147. && !(expr2->value.function.esym
  7148. && expr2->value.function.esym->result->attr.allocatable))
  7149. {
  7150. realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
  7151. if (!expr2->value.function.isym)
  7152. {
  7153. ss = gfc_walk_expr (expr1);
  7154. gcc_assert (ss != gfc_ss_terminator);
  7155. realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
  7156. ss->is_alloc_lhs = 1;
  7157. }
  7158. else
  7159. fcncall_realloc_result (&se, expr1->rank);
  7160. }
  7161. gfc_conv_function_expr (&se, expr2);
  7162. gfc_add_block_to_block (&se.pre, &se.post);
  7163. if (ss)
  7164. gfc_cleanup_loop (&loop);
  7165. else
  7166. gfc_free_ss_chain (se.ss);
  7167. return gfc_finish_block (&se.pre);
  7168. }
  7169. /* Try to efficiently translate array(:) = 0. Return NULL if this
  7170. can't be done. */
  7171. static tree
  7172. gfc_trans_zero_assign (gfc_expr * expr)
  7173. {
  7174. tree dest, len, type;
  7175. tree tmp;
  7176. gfc_symbol *sym;
  7177. sym = expr->symtree->n.sym;
  7178. dest = gfc_get_symbol_decl (sym);
  7179. type = TREE_TYPE (dest);
  7180. if (POINTER_TYPE_P (type))
  7181. type = TREE_TYPE (type);
  7182. if (!GFC_ARRAY_TYPE_P (type))
  7183. return NULL_TREE;
  7184. /* Determine the length of the array. */
  7185. len = GFC_TYPE_ARRAY_SIZE (type);
  7186. if (!len || TREE_CODE (len) != INTEGER_CST)
  7187. return NULL_TREE;
  7188. tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  7189. len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
  7190. fold_convert (gfc_array_index_type, tmp));
  7191. /* If we are zeroing a local array avoid taking its address by emitting
  7192. a = {} instead. */
  7193. if (!POINTER_TYPE_P (TREE_TYPE (dest)))
  7194. return build2_loc (input_location, MODIFY_EXPR, void_type_node,
  7195. dest, build_constructor (TREE_TYPE (dest),
  7196. NULL));
  7197. /* Convert arguments to the correct types. */
  7198. dest = fold_convert (pvoid_type_node, dest);
  7199. len = fold_convert (size_type_node, len);
  7200. /* Construct call to __builtin_memset. */
  7201. tmp = build_call_expr_loc (input_location,
  7202. builtin_decl_explicit (BUILT_IN_MEMSET),
  7203. 3, dest, integer_zero_node, len);
  7204. return fold_convert (void_type_node, tmp);
  7205. }
  7206. /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
  7207. that constructs the call to __builtin_memcpy. */
  7208. tree
  7209. gfc_build_memcpy_call (tree dst, tree src, tree len)
  7210. {
  7211. tree tmp;
  7212. /* Convert arguments to the correct types. */
  7213. if (!POINTER_TYPE_P (TREE_TYPE (dst)))
  7214. dst = gfc_build_addr_expr (pvoid_type_node, dst);
  7215. else
  7216. dst = fold_convert (pvoid_type_node, dst);
  7217. if (!POINTER_TYPE_P (TREE_TYPE (src)))
  7218. src = gfc_build_addr_expr (pvoid_type_node, src);
  7219. else
  7220. src = fold_convert (pvoid_type_node, src);
  7221. len = fold_convert (size_type_node, len);
  7222. /* Construct call to __builtin_memcpy. */
  7223. tmp = build_call_expr_loc (input_location,
  7224. builtin_decl_explicit (BUILT_IN_MEMCPY),
  7225. 3, dst, src, len);
  7226. return fold_convert (void_type_node, tmp);
  7227. }
  7228. /* Try to efficiently translate dst(:) = src(:). Return NULL if this
  7229. can't be done. EXPR1 is the destination/lhs and EXPR2 is the
  7230. source/rhs, both are gfc_full_array_ref_p which have been checked for
  7231. dependencies. */
  7232. static tree
  7233. gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
  7234. {
  7235. tree dst, dlen, dtype;
  7236. tree src, slen, stype;
  7237. tree tmp;
  7238. dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
  7239. src = gfc_get_symbol_decl (expr2->symtree->n.sym);
  7240. dtype = TREE_TYPE (dst);
  7241. if (POINTER_TYPE_P (dtype))
  7242. dtype = TREE_TYPE (dtype);
  7243. stype = TREE_TYPE (src);
  7244. if (POINTER_TYPE_P (stype))
  7245. stype = TREE_TYPE (stype);
  7246. if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
  7247. return NULL_TREE;
  7248. /* Determine the lengths of the arrays. */
  7249. dlen = GFC_TYPE_ARRAY_SIZE (dtype);
  7250. if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
  7251. return NULL_TREE;
  7252. tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
  7253. dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  7254. dlen, fold_convert (gfc_array_index_type, tmp));
  7255. slen = GFC_TYPE_ARRAY_SIZE (stype);
  7256. if (!slen || TREE_CODE (slen) != INTEGER_CST)
  7257. return NULL_TREE;
  7258. tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
  7259. slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  7260. slen, fold_convert (gfc_array_index_type, tmp));
  7261. /* Sanity check that they are the same. This should always be
  7262. the case, as we should already have checked for conformance. */
  7263. if (!tree_int_cst_equal (slen, dlen))
  7264. return NULL_TREE;
  7265. return gfc_build_memcpy_call (dst, src, dlen);
  7266. }
  7267. /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
  7268. this can't be done. EXPR1 is the destination/lhs for which
  7269. gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
  7270. static tree
  7271. gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
  7272. {
  7273. unsigned HOST_WIDE_INT nelem;
  7274. tree dst, dtype;
  7275. tree src, stype;
  7276. tree len;
  7277. tree tmp;
  7278. nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
  7279. if (nelem == 0)
  7280. return NULL_TREE;
  7281. dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
  7282. dtype = TREE_TYPE (dst);
  7283. if (POINTER_TYPE_P (dtype))
  7284. dtype = TREE_TYPE (dtype);
  7285. if (!GFC_ARRAY_TYPE_P (dtype))
  7286. return NULL_TREE;
  7287. /* Determine the lengths of the array. */
  7288. len = GFC_TYPE_ARRAY_SIZE (dtype);
  7289. if (!len || TREE_CODE (len) != INTEGER_CST)
  7290. return NULL_TREE;
  7291. /* Confirm that the constructor is the same size. */
  7292. if (compare_tree_int (len, nelem) != 0)
  7293. return NULL_TREE;
  7294. tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
  7295. len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
  7296. fold_convert (gfc_array_index_type, tmp));
  7297. stype = gfc_typenode_for_spec (&expr2->ts);
  7298. src = gfc_build_constant_array_constructor (expr2, stype);
  7299. stype = TREE_TYPE (src);
  7300. if (POINTER_TYPE_P (stype))
  7301. stype = TREE_TYPE (stype);
  7302. return gfc_build_memcpy_call (dst, src, len);
  7303. }
  7304. /* Tells whether the expression is to be treated as a variable reference. */
  7305. static bool
  7306. expr_is_variable (gfc_expr *expr)
  7307. {
  7308. gfc_expr *arg;
  7309. gfc_component *comp;
  7310. gfc_symbol *func_ifc;
  7311. if (expr->expr_type == EXPR_VARIABLE)
  7312. return true;
  7313. arg = gfc_get_noncopying_intrinsic_argument (expr);
  7314. if (arg)
  7315. {
  7316. gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
  7317. return expr_is_variable (arg);
  7318. }
  7319. /* A data-pointer-returning function should be considered as a variable
  7320. too. */
  7321. if (expr->expr_type == EXPR_FUNCTION
  7322. && expr->ref == NULL)
  7323. {
  7324. if (expr->value.function.isym != NULL)
  7325. return false;
  7326. if (expr->value.function.esym != NULL)
  7327. {
  7328. func_ifc = expr->value.function.esym;
  7329. goto found_ifc;
  7330. }
  7331. else
  7332. {
  7333. gcc_assert (expr->symtree);
  7334. func_ifc = expr->symtree->n.sym;
  7335. goto found_ifc;
  7336. }
  7337. gcc_unreachable ();
  7338. }
  7339. comp = gfc_get_proc_ptr_comp (expr);
  7340. if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
  7341. && comp)
  7342. {
  7343. func_ifc = comp->ts.interface;
  7344. goto found_ifc;
  7345. }
  7346. if (expr->expr_type == EXPR_COMPCALL)
  7347. {
  7348. gcc_assert (!expr->value.compcall.tbp->is_generic);
  7349. func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
  7350. goto found_ifc;
  7351. }
  7352. return false;
  7353. found_ifc:
  7354. gcc_assert (func_ifc->attr.function
  7355. && func_ifc->result != NULL);
  7356. return func_ifc->result->attr.pointer;
  7357. }
  7358. /* Is the lhs OK for automatic reallocation? */
  7359. static bool
  7360. is_scalar_reallocatable_lhs (gfc_expr *expr)
  7361. {
  7362. gfc_ref * ref;
  7363. /* An allocatable variable with no reference. */
  7364. if (expr->symtree->n.sym->attr.allocatable
  7365. && !expr->ref)
  7366. return true;
  7367. /* All that can be left are allocatable components. */
  7368. if ((expr->symtree->n.sym->ts.type != BT_DERIVED
  7369. && expr->symtree->n.sym->ts.type != BT_CLASS)
  7370. || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
  7371. return false;
  7372. /* Find an allocatable component ref last. */
  7373. for (ref = expr->ref; ref; ref = ref->next)
  7374. if (ref->type == REF_COMPONENT
  7375. && !ref->next
  7376. && ref->u.c.component->attr.allocatable)
  7377. return true;
  7378. return false;
  7379. }
  7380. /* Allocate or reallocate scalar lhs, as necessary. */
  7381. static void
  7382. alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
  7383. tree string_length,
  7384. gfc_expr *expr1,
  7385. gfc_expr *expr2)
  7386. {
  7387. tree cond;
  7388. tree tmp;
  7389. tree size;
  7390. tree size_in_bytes;
  7391. tree jump_label1;
  7392. tree jump_label2;
  7393. gfc_se lse;
  7394. if (!expr1 || expr1->rank)
  7395. return;
  7396. if (!expr2 || expr2->rank)
  7397. return;
  7398. realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
  7399. /* Since this is a scalar lhs, we can afford to do this. That is,
  7400. there is no risk of side effects being repeated. */
  7401. gfc_init_se (&lse, NULL);
  7402. lse.want_pointer = 1;
  7403. gfc_conv_expr (&lse, expr1);
  7404. jump_label1 = gfc_build_label_decl (NULL_TREE);
  7405. jump_label2 = gfc_build_label_decl (NULL_TREE);
  7406. /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
  7407. tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
  7408. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  7409. lse.expr, tmp);
  7410. tmp = build3_v (COND_EXPR, cond,
  7411. build1_v (GOTO_EXPR, jump_label1),
  7412. build_empty_stmt (input_location));
  7413. gfc_add_expr_to_block (block, tmp);
  7414. if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
  7415. {
  7416. /* Use the rhs string length and the lhs element size. */
  7417. size = string_length;
  7418. tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
  7419. tmp = TYPE_SIZE_UNIT (tmp);
  7420. size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
  7421. TREE_TYPE (tmp), tmp,
  7422. fold_convert (TREE_TYPE (tmp), size));
  7423. }
  7424. else
  7425. {
  7426. /* Otherwise use the length in bytes of the rhs. */
  7427. size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
  7428. size_in_bytes = size;
  7429. }
  7430. size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
  7431. size_in_bytes, size_one_node);
  7432. if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
  7433. {
  7434. tmp = build_call_expr_loc (input_location,
  7435. builtin_decl_explicit (BUILT_IN_CALLOC),
  7436. 2, build_one_cst (size_type_node),
  7437. size_in_bytes);
  7438. tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
  7439. gfc_add_modify (block, lse.expr, tmp);
  7440. }
  7441. else
  7442. {
  7443. tmp = build_call_expr_loc (input_location,
  7444. builtin_decl_explicit (BUILT_IN_MALLOC),
  7445. 1, size_in_bytes);
  7446. tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
  7447. gfc_add_modify (block, lse.expr, tmp);
  7448. }
  7449. if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
  7450. {
  7451. /* Deferred characters need checking for lhs and rhs string
  7452. length. Other deferred parameter variables will have to
  7453. come here too. */
  7454. tmp = build1_v (GOTO_EXPR, jump_label2);
  7455. gfc_add_expr_to_block (block, tmp);
  7456. }
  7457. tmp = build1_v (LABEL_EXPR, jump_label1);
  7458. gfc_add_expr_to_block (block, tmp);
  7459. /* For a deferred length character, reallocate if lengths of lhs and
  7460. rhs are different. */
  7461. if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
  7462. {
  7463. cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  7464. lse.string_length, size);
  7465. /* Jump past the realloc if the lengths are the same. */
  7466. tmp = build3_v (COND_EXPR, cond,
  7467. build1_v (GOTO_EXPR, jump_label2),
  7468. build_empty_stmt (input_location));
  7469. gfc_add_expr_to_block (block, tmp);
  7470. tmp = build_call_expr_loc (input_location,
  7471. builtin_decl_explicit (BUILT_IN_REALLOC),
  7472. 2, fold_convert (pvoid_type_node, lse.expr),
  7473. size_in_bytes);
  7474. tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
  7475. gfc_add_modify (block, lse.expr, tmp);
  7476. tmp = build1_v (LABEL_EXPR, jump_label2);
  7477. gfc_add_expr_to_block (block, tmp);
  7478. /* Update the lhs character length. */
  7479. size = string_length;
  7480. gfc_add_modify (block, lse.string_length, size);
  7481. }
  7482. }
  7483. /* Check for assignments of the type
  7484. a = a + 4
  7485. to make sure we do not check for reallocation unneccessarily. */
  7486. static bool
  7487. is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
  7488. {
  7489. gfc_actual_arglist *a;
  7490. gfc_expr *e1, *e2;
  7491. switch (expr2->expr_type)
  7492. {
  7493. case EXPR_VARIABLE:
  7494. return gfc_dep_compare_expr (expr1, expr2) == 0;
  7495. case EXPR_FUNCTION:
  7496. if (expr2->value.function.esym
  7497. && expr2->value.function.esym->attr.elemental)
  7498. {
  7499. for (a = expr2->value.function.actual; a != NULL; a = a->next)
  7500. {
  7501. e1 = a->expr;
  7502. if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
  7503. return false;
  7504. }
  7505. return true;
  7506. }
  7507. else if (expr2->value.function.isym
  7508. && expr2->value.function.isym->elemental)
  7509. {
  7510. for (a = expr2->value.function.actual; a != NULL; a = a->next)
  7511. {
  7512. e1 = a->expr;
  7513. if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
  7514. return false;
  7515. }
  7516. return true;
  7517. }
  7518. break;
  7519. case EXPR_OP:
  7520. switch (expr2->value.op.op)
  7521. {
  7522. case INTRINSIC_NOT:
  7523. case INTRINSIC_UPLUS:
  7524. case INTRINSIC_UMINUS:
  7525. case INTRINSIC_PARENTHESES:
  7526. return is_runtime_conformable (expr1, expr2->value.op.op1);
  7527. case INTRINSIC_PLUS:
  7528. case INTRINSIC_MINUS:
  7529. case INTRINSIC_TIMES:
  7530. case INTRINSIC_DIVIDE:
  7531. case INTRINSIC_POWER:
  7532. case INTRINSIC_AND:
  7533. case INTRINSIC_OR:
  7534. case INTRINSIC_EQV:
  7535. case INTRINSIC_NEQV:
  7536. case INTRINSIC_EQ:
  7537. case INTRINSIC_NE:
  7538. case INTRINSIC_GT:
  7539. case INTRINSIC_GE:
  7540. case INTRINSIC_LT:
  7541. case INTRINSIC_LE:
  7542. case INTRINSIC_EQ_OS:
  7543. case INTRINSIC_NE_OS:
  7544. case INTRINSIC_GT_OS:
  7545. case INTRINSIC_GE_OS:
  7546. case INTRINSIC_LT_OS:
  7547. case INTRINSIC_LE_OS:
  7548. e1 = expr2->value.op.op1;
  7549. e2 = expr2->value.op.op2;
  7550. if (e1->rank == 0 && e2->rank > 0)
  7551. return is_runtime_conformable (expr1, e2);
  7552. else if (e1->rank > 0 && e2->rank == 0)
  7553. return is_runtime_conformable (expr1, e1);
  7554. else if (e1->rank > 0 && e2->rank > 0)
  7555. return is_runtime_conformable (expr1, e1)
  7556. && is_runtime_conformable (expr1, e2);
  7557. break;
  7558. default:
  7559. break;
  7560. }
  7561. break;
  7562. default:
  7563. break;
  7564. }
  7565. return false;
  7566. }
  7567. /* Subroutine of gfc_trans_assignment that actually scalarizes the
  7568. assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
  7569. init_flag indicates initialization expressions and dealloc that no
  7570. deallocate prior assignment is needed (if in doubt, set true). */
  7571. static tree
  7572. gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
  7573. bool dealloc)
  7574. {
  7575. gfc_se lse;
  7576. gfc_se rse;
  7577. gfc_ss *lss;
  7578. gfc_ss *lss_section;
  7579. gfc_ss *rss;
  7580. gfc_loopinfo loop;
  7581. tree tmp;
  7582. stmtblock_t block;
  7583. stmtblock_t body;
  7584. bool l_is_temp;
  7585. bool scalar_to_array;
  7586. tree string_length;
  7587. int n;
  7588. /* Assignment of the form lhs = rhs. */
  7589. gfc_start_block (&block);
  7590. gfc_init_se (&lse, NULL);
  7591. gfc_init_se (&rse, NULL);
  7592. /* Walk the lhs. */
  7593. lss = gfc_walk_expr (expr1);
  7594. if (gfc_is_reallocatable_lhs (expr1)
  7595. && !(expr2->expr_type == EXPR_FUNCTION
  7596. && expr2->value.function.isym != NULL))
  7597. lss->is_alloc_lhs = 1;
  7598. rss = NULL;
  7599. if ((expr1->ts.type == BT_DERIVED)
  7600. && (gfc_is_alloc_class_array_function (expr2)
  7601. || gfc_is_alloc_class_scalar_function (expr2)))
  7602. expr2->must_finalize = 1;
  7603. if (lss != gfc_ss_terminator)
  7604. {
  7605. /* The assignment needs scalarization. */
  7606. lss_section = lss;
  7607. /* Find a non-scalar SS from the lhs. */
  7608. while (lss_section != gfc_ss_terminator
  7609. && lss_section->info->type != GFC_SS_SECTION)
  7610. lss_section = lss_section->next;
  7611. gcc_assert (lss_section != gfc_ss_terminator);
  7612. /* Initialize the scalarizer. */
  7613. gfc_init_loopinfo (&loop);
  7614. /* Walk the rhs. */
  7615. rss = gfc_walk_expr (expr2);
  7616. if (rss == gfc_ss_terminator)
  7617. /* The rhs is scalar. Add a ss for the expression. */
  7618. rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
  7619. /* Associate the SS with the loop. */
  7620. gfc_add_ss_to_loop (&loop, lss);
  7621. gfc_add_ss_to_loop (&loop, rss);
  7622. /* Calculate the bounds of the scalarization. */
  7623. gfc_conv_ss_startstride (&loop);
  7624. /* Enable loop reversal. */
  7625. for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
  7626. loop.reverse[n] = GFC_ENABLE_REVERSE;
  7627. /* Resolve any data dependencies in the statement. */
  7628. gfc_conv_resolve_dependencies (&loop, lss, rss);
  7629. /* Setup the scalarizing loops. */
  7630. gfc_conv_loop_setup (&loop, &expr2->where);
  7631. /* Setup the gfc_se structures. */
  7632. gfc_copy_loopinfo_to_se (&lse, &loop);
  7633. gfc_copy_loopinfo_to_se (&rse, &loop);
  7634. rse.ss = rss;
  7635. gfc_mark_ss_chain_used (rss, 1);
  7636. if (loop.temp_ss == NULL)
  7637. {
  7638. lse.ss = lss;
  7639. gfc_mark_ss_chain_used (lss, 1);
  7640. }
  7641. else
  7642. {
  7643. lse.ss = loop.temp_ss;
  7644. gfc_mark_ss_chain_used (lss, 3);
  7645. gfc_mark_ss_chain_used (loop.temp_ss, 3);
  7646. }
  7647. /* Allow the scalarizer to workshare array assignments. */
  7648. if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
  7649. ompws_flags |= OMPWS_SCALARIZER_WS;
  7650. /* Start the scalarized loop body. */
  7651. gfc_start_scalarized_body (&loop, &body);
  7652. }
  7653. else
  7654. gfc_init_block (&body);
  7655. l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
  7656. /* Translate the expression. */
  7657. gfc_conv_expr (&rse, expr2);
  7658. /* Deal with the case of a scalar class function assigned to a derived type. */
  7659. if (gfc_is_alloc_class_scalar_function (expr2)
  7660. && expr1->ts.type == BT_DERIVED)
  7661. {
  7662. rse.expr = gfc_class_data_get (rse.expr);
  7663. rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
  7664. }
  7665. /* Stabilize a string length for temporaries. */
  7666. if (expr2->ts.type == BT_CHARACTER)
  7667. string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
  7668. else
  7669. string_length = NULL_TREE;
  7670. if (l_is_temp)
  7671. {
  7672. gfc_conv_tmp_array_ref (&lse);
  7673. if (expr2->ts.type == BT_CHARACTER)
  7674. lse.string_length = string_length;
  7675. }
  7676. else
  7677. gfc_conv_expr (&lse, expr1);
  7678. /* Assignments of scalar derived types with allocatable components
  7679. to arrays must be done with a deep copy and the rhs temporary
  7680. must have its components deallocated afterwards. */
  7681. scalar_to_array = (expr2->ts.type == BT_DERIVED
  7682. && expr2->ts.u.derived->attr.alloc_comp
  7683. && !expr_is_variable (expr2)
  7684. && !gfc_is_constant_expr (expr2)
  7685. && expr1->rank && !expr2->rank);
  7686. scalar_to_array |= (expr1->ts.type == BT_DERIVED
  7687. && expr1->rank
  7688. && expr1->ts.u.derived->attr.alloc_comp
  7689. && gfc_is_alloc_class_scalar_function (expr2));
  7690. if (scalar_to_array && dealloc)
  7691. {
  7692. tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
  7693. gfc_add_expr_to_block (&loop.post, tmp);
  7694. }
  7695. /* When assigning a character function result to a deferred-length variable,
  7696. the function call must happen before the (re)allocation of the lhs -
  7697. otherwise the character length of the result is not known.
  7698. NOTE: This relies on having the exact dependence of the length type
  7699. parameter available to the caller; gfortran saves it in the .mod files. */
  7700. if (flag_realloc_lhs && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred)
  7701. gfc_add_block_to_block (&block, &rse.pre);
  7702. /* Nullify the allocatable components corresponding to those of the lhs
  7703. derived type, so that the finalization of the function result does not
  7704. affect the lhs of the assignment. Prepend is used to ensure that the
  7705. nullification occurs before the call to the finalizer. In the case of
  7706. a scalar to array assignment, this is done in gfc_trans_scalar_assign
  7707. as part of the deep copy. */
  7708. if (!scalar_to_array && (expr1->ts.type == BT_DERIVED)
  7709. && (gfc_is_alloc_class_array_function (expr2)
  7710. || gfc_is_alloc_class_scalar_function (expr2)))
  7711. {
  7712. tmp = rse.expr;
  7713. tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
  7714. gfc_prepend_expr_to_block (&rse.post, tmp);
  7715. if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
  7716. gfc_add_block_to_block (&loop.post, &rse.post);
  7717. }
  7718. tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
  7719. l_is_temp || init_flag,
  7720. expr_is_variable (expr2) || scalar_to_array
  7721. || expr2->expr_type == EXPR_ARRAY, dealloc);
  7722. gfc_add_expr_to_block (&body, tmp);
  7723. if (lss == gfc_ss_terminator)
  7724. {
  7725. /* F2003: Add the code for reallocation on assignment. */
  7726. if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1))
  7727. alloc_scalar_allocatable_for_assignment (&block, string_length,
  7728. expr1, expr2);
  7729. /* Use the scalar assignment as is. */
  7730. gfc_add_block_to_block (&block, &body);
  7731. }
  7732. else
  7733. {
  7734. gcc_assert (lse.ss == gfc_ss_terminator
  7735. && rse.ss == gfc_ss_terminator);
  7736. if (l_is_temp)
  7737. {
  7738. gfc_trans_scalarized_loop_boundary (&loop, &body);
  7739. /* We need to copy the temporary to the actual lhs. */
  7740. gfc_init_se (&lse, NULL);
  7741. gfc_init_se (&rse, NULL);
  7742. gfc_copy_loopinfo_to_se (&lse, &loop);
  7743. gfc_copy_loopinfo_to_se (&rse, &loop);
  7744. rse.ss = loop.temp_ss;
  7745. lse.ss = lss;
  7746. gfc_conv_tmp_array_ref (&rse);
  7747. gfc_conv_expr (&lse, expr1);
  7748. gcc_assert (lse.ss == gfc_ss_terminator
  7749. && rse.ss == gfc_ss_terminator);
  7750. if (expr2->ts.type == BT_CHARACTER)
  7751. rse.string_length = string_length;
  7752. tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
  7753. false, false, dealloc);
  7754. gfc_add_expr_to_block (&body, tmp);
  7755. }
  7756. /* F2003: Allocate or reallocate lhs of allocatable array. */
  7757. if (flag_realloc_lhs
  7758. && gfc_is_reallocatable_lhs (expr1)
  7759. && !gfc_expr_attr (expr1).codimension
  7760. && !gfc_is_coindexed (expr1)
  7761. && expr2->rank
  7762. && !is_runtime_conformable (expr1, expr2))
  7763. {
  7764. realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
  7765. ompws_flags &= ~OMPWS_SCALARIZER_WS;
  7766. tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
  7767. if (tmp != NULL_TREE)
  7768. gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
  7769. }
  7770. /* Generate the copying loops. */
  7771. gfc_trans_scalarizing_loops (&loop, &body);
  7772. /* Wrap the whole thing up. */
  7773. gfc_add_block_to_block (&block, &loop.pre);
  7774. gfc_add_block_to_block (&block, &loop.post);
  7775. gfc_cleanup_loop (&loop);
  7776. }
  7777. return gfc_finish_block (&block);
  7778. }
  7779. /* Check whether EXPR is a copyable array. */
  7780. static bool
  7781. copyable_array_p (gfc_expr * expr)
  7782. {
  7783. if (expr->expr_type != EXPR_VARIABLE)
  7784. return false;
  7785. /* First check it's an array. */
  7786. if (expr->rank < 1 || !expr->ref || expr->ref->next)
  7787. return false;
  7788. if (!gfc_full_array_ref_p (expr->ref, NULL))
  7789. return false;
  7790. /* Next check that it's of a simple enough type. */
  7791. switch (expr->ts.type)
  7792. {
  7793. case BT_INTEGER:
  7794. case BT_REAL:
  7795. case BT_COMPLEX:
  7796. case BT_LOGICAL:
  7797. return true;
  7798. case BT_CHARACTER:
  7799. return false;
  7800. case BT_DERIVED:
  7801. return !expr->ts.u.derived->attr.alloc_comp;
  7802. default:
  7803. break;
  7804. }
  7805. return false;
  7806. }
  7807. /* Translate an assignment. */
  7808. tree
  7809. gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
  7810. bool dealloc)
  7811. {
  7812. tree tmp;
  7813. /* Special case a single function returning an array. */
  7814. if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
  7815. {
  7816. tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
  7817. if (tmp)
  7818. return tmp;
  7819. }
  7820. /* Special case assigning an array to zero. */
  7821. if (copyable_array_p (expr1)
  7822. && is_zero_initializer_p (expr2))
  7823. {
  7824. tmp = gfc_trans_zero_assign (expr1);
  7825. if (tmp)
  7826. return tmp;
  7827. }
  7828. /* Special case copying one array to another. */
  7829. if (copyable_array_p (expr1)
  7830. && copyable_array_p (expr2)
  7831. && gfc_compare_types (&expr1->ts, &expr2->ts)
  7832. && !gfc_check_dependency (expr1, expr2, 0))
  7833. {
  7834. tmp = gfc_trans_array_copy (expr1, expr2);
  7835. if (tmp)
  7836. return tmp;
  7837. }
  7838. /* Special case initializing an array from a constant array constructor. */
  7839. if (copyable_array_p (expr1)
  7840. && expr2->expr_type == EXPR_ARRAY
  7841. && gfc_compare_types (&expr1->ts, &expr2->ts))
  7842. {
  7843. tmp = gfc_trans_array_constructor_copy (expr1, expr2);
  7844. if (tmp)
  7845. return tmp;
  7846. }
  7847. /* Fallback to the scalarizer to generate explicit loops. */
  7848. return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
  7849. }
  7850. tree
  7851. gfc_trans_init_assign (gfc_code * code)
  7852. {
  7853. return gfc_trans_assignment (code->expr1, code->expr2, true, false);
  7854. }
  7855. tree
  7856. gfc_trans_assign (gfc_code * code)
  7857. {
  7858. return gfc_trans_assignment (code->expr1, code->expr2, false, true);
  7859. }