12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594 |
- //===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements semantic analysis for initializers.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/DeclObjC.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/ExprObjC.h"
- #include "clang/AST/ExprOpenMP.h"
- #include "clang/AST/TypeLoc.h"
- #include "clang/Basic/CharInfo.h"
- #include "clang/Basic/SourceManager.h"
- #include "clang/Basic/TargetInfo.h"
- #include "clang/Sema/Designator.h"
- #include "clang/Sema/Initialization.h"
- #include "clang/Sema/Lookup.h"
- #include "clang/Sema/SemaInternal.h"
- #include "llvm/ADT/APInt.h"
- #include "llvm/ADT/PointerIntPair.h"
- #include "llvm/ADT/SmallString.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace clang;
- //===----------------------------------------------------------------------===//
- // Sema Initialization Checking
- //===----------------------------------------------------------------------===//
- /// Check whether T is compatible with a wide character type (wchar_t,
- /// char16_t or char32_t).
- static bool IsWideCharCompatible(QualType T, ASTContext &Context) {
- if (Context.typesAreCompatible(Context.getWideCharType(), T))
- return true;
- if (Context.getLangOpts().CPlusPlus || Context.getLangOpts().C11) {
- return Context.typesAreCompatible(Context.Char16Ty, T) ||
- Context.typesAreCompatible(Context.Char32Ty, T);
- }
- return false;
- }
- enum StringInitFailureKind {
- SIF_None,
- SIF_NarrowStringIntoWideChar,
- SIF_WideStringIntoChar,
- SIF_IncompatWideStringIntoWideChar,
- SIF_UTF8StringIntoPlainChar,
- SIF_PlainStringIntoUTF8Char,
- SIF_Other
- };
- /// Check whether the array of type AT can be initialized by the Init
- /// expression by means of string initialization. Returns SIF_None if so,
- /// otherwise returns a StringInitFailureKind that describes why the
- /// initialization would not work.
- static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
- ASTContext &Context) {
- if (!isa<ConstantArrayType>(AT) && !isa<IncompleteArrayType>(AT))
- return SIF_Other;
- // See if this is a string literal or @encode.
- Init = Init->IgnoreParens();
- // Handle @encode, which is a narrow string.
- if (isa<ObjCEncodeExpr>(Init) && AT->getElementType()->isCharType())
- return SIF_None;
- // Otherwise we can only handle string literals.
- StringLiteral *SL = dyn_cast<StringLiteral>(Init);
- if (!SL)
- return SIF_Other;
- const QualType ElemTy =
- Context.getCanonicalType(AT->getElementType()).getUnqualifiedType();
- auto IsCharOrUnsignedChar = [](const QualType &T) {
- const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr());
- return BT && BT->isCharType() && BT->getKind() != BuiltinType::SChar;
- };
- switch (SL->getKind()) {
- case StringLiteral::UTF8:
- // char8_t array can be initialized with a UTF-8 string.
- // - C++20 [dcl.init.string] (DR)
- // Additionally, an array of char or unsigned char may be initialized
- // by a UTF-8 string literal.
- if (ElemTy->isChar8Type() ||
- (Context.getLangOpts().Char8 &&
- IsCharOrUnsignedChar(ElemTy.getCanonicalType())))
- return SIF_None;
- [[fallthrough]];
- case StringLiteral::Ordinary:
- // char array can be initialized with a narrow string.
- // Only allow char x[] = "foo"; not char x[] = L"foo";
- if (ElemTy->isCharType())
- return (SL->getKind() == StringLiteral::UTF8 &&
- Context.getLangOpts().Char8)
- ? SIF_UTF8StringIntoPlainChar
- : SIF_None;
- if (ElemTy->isChar8Type())
- return SIF_PlainStringIntoUTF8Char;
- if (IsWideCharCompatible(ElemTy, Context))
- return SIF_NarrowStringIntoWideChar;
- return SIF_Other;
- // C99 6.7.8p15 (with correction from DR343), or C11 6.7.9p15:
- // "An array with element type compatible with a qualified or unqualified
- // version of wchar_t, char16_t, or char32_t may be initialized by a wide
- // string literal with the corresponding encoding prefix (L, u, or U,
- // respectively), optionally enclosed in braces.
- case StringLiteral::UTF16:
- if (Context.typesAreCompatible(Context.Char16Ty, ElemTy))
- return SIF_None;
- if (ElemTy->isCharType() || ElemTy->isChar8Type())
- return SIF_WideStringIntoChar;
- if (IsWideCharCompatible(ElemTy, Context))
- return SIF_IncompatWideStringIntoWideChar;
- return SIF_Other;
- case StringLiteral::UTF32:
- if (Context.typesAreCompatible(Context.Char32Ty, ElemTy))
- return SIF_None;
- if (ElemTy->isCharType() || ElemTy->isChar8Type())
- return SIF_WideStringIntoChar;
- if (IsWideCharCompatible(ElemTy, Context))
- return SIF_IncompatWideStringIntoWideChar;
- return SIF_Other;
- case StringLiteral::Wide:
- if (Context.typesAreCompatible(Context.getWideCharType(), ElemTy))
- return SIF_None;
- if (ElemTy->isCharType() || ElemTy->isChar8Type())
- return SIF_WideStringIntoChar;
- if (IsWideCharCompatible(ElemTy, Context))
- return SIF_IncompatWideStringIntoWideChar;
- return SIF_Other;
- }
- llvm_unreachable("missed a StringLiteral kind?");
- }
- static StringInitFailureKind IsStringInit(Expr *init, QualType declType,
- ASTContext &Context) {
- const ArrayType *arrayType = Context.getAsArrayType(declType);
- if (!arrayType)
- return SIF_Other;
- return IsStringInit(init, arrayType, Context);
- }
- bool Sema::IsStringInit(Expr *Init, const ArrayType *AT) {
- return ::IsStringInit(Init, AT, Context) == SIF_None;
- }
- /// Update the type of a string literal, including any surrounding parentheses,
- /// to match the type of the object which it is initializing.
- static void updateStringLiteralType(Expr *E, QualType Ty) {
- while (true) {
- E->setType(Ty);
- E->setValueKind(VK_PRValue);
- if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) {
- break;
- } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- E = PE->getSubExpr();
- } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
- assert(UO->getOpcode() == UO_Extension);
- E = UO->getSubExpr();
- } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
- E = GSE->getResultExpr();
- } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
- E = CE->getChosenSubExpr();
- } else {
- llvm_unreachable("unexpected expr in string literal init");
- }
- }
- }
- /// Fix a compound literal initializing an array so it's correctly marked
- /// as an rvalue.
- static void updateGNUCompoundLiteralRValue(Expr *E) {
- while (true) {
- E->setValueKind(VK_PRValue);
- if (isa<CompoundLiteralExpr>(E)) {
- break;
- } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- E = PE->getSubExpr();
- } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
- assert(UO->getOpcode() == UO_Extension);
- E = UO->getSubExpr();
- } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
- E = GSE->getResultExpr();
- } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
- E = CE->getChosenSubExpr();
- } else {
- llvm_unreachable("unexpected expr in array compound literal init");
- }
- }
- }
- static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
- Sema &S) {
- // Get the length of the string as parsed.
- auto *ConstantArrayTy =
- cast<ConstantArrayType>(Str->getType()->getAsArrayTypeUnsafe());
- uint64_t StrLength = ConstantArrayTy->getSize().getZExtValue();
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
- // C99 6.7.8p14. We have an array of character type with unknown size
- // being initialized to a string literal.
- llvm::APInt ConstVal(32, StrLength);
- // Return a new array type (C99 6.7.8p22).
- DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
- ConstVal, nullptr,
- ArrayType::Normal, 0);
- updateStringLiteralType(Str, DeclT);
- return;
- }
- const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
- // We have an array of character type with known size. However,
- // the size may be smaller or larger than the string we are initializing.
- // FIXME: Avoid truncation for 64-bit length strings.
- if (S.getLangOpts().CPlusPlus) {
- if (StringLiteral *SL = dyn_cast<StringLiteral>(Str->IgnoreParens())) {
- // For Pascal strings it's OK to strip off the terminating null character,
- // so the example below is valid:
- //
- // unsigned char a[2] = "\pa";
- if (SL->isPascal())
- StrLength--;
- }
- // [dcl.init.string]p2
- if (StrLength > CAT->getSize().getZExtValue())
- S.Diag(Str->getBeginLoc(),
- diag::err_initializer_string_for_char_array_too_long)
- << CAT->getSize().getZExtValue() << StrLength
- << Str->getSourceRange();
- } else {
- // C99 6.7.8p14.
- if (StrLength-1 > CAT->getSize().getZExtValue())
- S.Diag(Str->getBeginLoc(),
- diag::ext_initializer_string_for_char_array_too_long)
- << Str->getSourceRange();
- }
- // Set the type to the actual size that we are initializing. If we have
- // something like:
- // char x[1] = "foo";
- // then this will set the string literal's type to char[1].
- updateStringLiteralType(Str, DeclT);
- }
- //===----------------------------------------------------------------------===//
- // Semantic checking for initializer lists.
- //===----------------------------------------------------------------------===//
- namespace {
- /// Semantic checking for initializer lists.
- ///
- /// The InitListChecker class contains a set of routines that each
- /// handle the initialization of a certain kind of entity, e.g.,
- /// arrays, vectors, struct/union types, scalars, etc. The
- /// InitListChecker itself performs a recursive walk of the subobject
- /// structure of the type to be initialized, while stepping through
- /// the initializer list one element at a time. The IList and Index
- /// parameters to each of the Check* routines contain the active
- /// (syntactic) initializer list and the index into that initializer
- /// list that represents the current initializer. Each routine is
- /// responsible for moving that Index forward as it consumes elements.
- ///
- /// Each Check* routine also has a StructuredList/StructuredIndex
- /// arguments, which contains the current "structured" (semantic)
- /// initializer list and the index into that initializer list where we
- /// are copying initializers as we map them over to the semantic
- /// list. Once we have completed our recursive walk of the subobject
- /// structure, we will have constructed a full semantic initializer
- /// list.
- ///
- /// C99 designators cause changes in the initializer list traversal,
- /// because they make the initialization "jump" into a specific
- /// subobject and then continue the initialization from that
- /// point. CheckDesignatedInitializer() recursively steps into the
- /// designated subobject and manages backing out the recursion to
- /// initialize the subobjects after the one designated.
- ///
- /// If an initializer list contains any designators, we build a placeholder
- /// structured list even in 'verify only' mode, so that we can track which
- /// elements need 'empty' initializtion.
- class InitListChecker {
- Sema &SemaRef;
- bool hadError = false;
- bool VerifyOnly; // No diagnostics.
- bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.
- bool InOverloadResolution;
- InitListExpr *FullyStructuredList = nullptr;
- NoInitExpr *DummyExpr = nullptr;
- NoInitExpr *getDummyInit() {
- if (!DummyExpr)
- DummyExpr = new (SemaRef.Context) NoInitExpr(SemaRef.Context.VoidTy);
- return DummyExpr;
- }
- void CheckImplicitInitList(const InitializedEntity &Entity,
- InitListExpr *ParentIList, QualType T,
- unsigned &Index, InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- void CheckExplicitInitList(const InitializedEntity &Entity,
- InitListExpr *IList, QualType &T,
- InitListExpr *StructuredList,
- bool TopLevelObject = false);
- void CheckListElementTypes(const InitializedEntity &Entity,
- InitListExpr *IList, QualType &DeclType,
- bool SubobjectIsDesignatorContext,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool TopLevelObject = false);
- void CheckSubElementType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType ElemType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool DirectlyDesignated = false);
- void CheckComplexType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- void CheckScalarType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- void CheckReferenceType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- void CheckVectorType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType, unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- void CheckStructUnionTypes(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- CXXRecordDecl::base_class_range Bases,
- RecordDecl::field_iterator Field,
- bool SubobjectIsDesignatorContext, unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool TopLevelObject = false);
- void CheckArrayType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType &DeclType,
- llvm::APSInt elementIndex,
- bool SubobjectIsDesignatorContext, unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex);
- bool CheckDesignatedInitializer(const InitializedEntity &Entity,
- InitListExpr *IList, DesignatedInitExpr *DIE,
- unsigned DesigIdx,
- QualType &CurrentObjectType,
- RecordDecl::field_iterator *NextField,
- llvm::APSInt *NextElementIndex,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool FinishSubobjectInit,
- bool TopLevelObject);
- InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
- QualType CurrentObjectType,
- InitListExpr *StructuredList,
- unsigned StructuredIndex,
- SourceRange InitRange,
- bool IsFullyOverwritten = false);
- void UpdateStructuredListElement(InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- Expr *expr);
- InitListExpr *createInitListExpr(QualType CurrentObjectType,
- SourceRange InitRange,
- unsigned ExpectedNumInits);
- int numArrayElements(QualType DeclType);
- int numStructUnionElements(QualType DeclType);
- ExprResult PerformEmptyInit(SourceLocation Loc,
- const InitializedEntity &Entity);
- /// Diagnose that OldInit (or part thereof) has been overridden by NewInit.
- void diagnoseInitOverride(Expr *OldInit, SourceRange NewInitRange,
- bool FullyOverwritten = true) {
- // Overriding an initializer via a designator is valid with C99 designated
- // initializers, but ill-formed with C++20 designated initializers.
- unsigned DiagID = SemaRef.getLangOpts().CPlusPlus
- ? diag::ext_initializer_overrides
- : diag::warn_initializer_overrides;
- if (InOverloadResolution && SemaRef.getLangOpts().CPlusPlus) {
- // In overload resolution, we have to strictly enforce the rules, and so
- // don't allow any overriding of prior initializers. This matters for a
- // case such as:
- //
- // union U { int a, b; };
- // struct S { int a, b; };
- // void f(U), f(S);
- //
- // Here, f({.a = 1, .b = 2}) is required to call the struct overload. For
- // consistency, we disallow all overriding of prior initializers in
- // overload resolution, not only overriding of union members.
- hadError = true;
- } else if (OldInit->getType().isDestructedType() && !FullyOverwritten) {
- // If we'll be keeping around the old initializer but overwriting part of
- // the object it initialized, and that object is not trivially
- // destructible, this can leak. Don't allow that, not even as an
- // extension.
- //
- // FIXME: It might be reasonable to allow this in cases where the part of
- // the initializer that we're overriding has trivial destruction.
- DiagID = diag::err_initializer_overrides_destructed;
- } else if (!OldInit->getSourceRange().isValid()) {
- // We need to check on source range validity because the previous
- // initializer does not have to be an explicit initializer. e.g.,
- //
- // struct P { int a, b; };
- // struct PP { struct P p } l = { { .a = 2 }, .p.b = 3 };
- //
- // There is an overwrite taking place because the first braced initializer
- // list "{ .a = 2 }" already provides value for .p.b (which is zero).
- //
- // Such overwrites are harmless, so we don't diagnose them. (Note that in
- // C++, this cannot be reached unless we've already seen and diagnosed a
- // different conformance issue, such as a mixture of designated and
- // non-designated initializers or a multi-level designator.)
- return;
- }
- if (!VerifyOnly) {
- SemaRef.Diag(NewInitRange.getBegin(), DiagID)
- << NewInitRange << FullyOverwritten << OldInit->getType();
- SemaRef.Diag(OldInit->getBeginLoc(), diag::note_previous_initializer)
- << (OldInit->HasSideEffects(SemaRef.Context) && FullyOverwritten)
- << OldInit->getSourceRange();
- }
- }
- // Explanation on the "FillWithNoInit" mode:
- //
- // Assume we have the following definitions (Case#1):
- // struct P { char x[6][6]; } xp = { .x[1] = "bar" };
- // struct PP { struct P lp; } l = { .lp = xp, .lp.x[1][2] = 'f' };
- //
- // l.lp.x[1][0..1] should not be filled with implicit initializers because the
- // "base" initializer "xp" will provide values for them; l.lp.x[1] will be "baf".
- //
- // But if we have (Case#2):
- // struct PP l = { .lp = xp, .lp.x[1] = { [2] = 'f' } };
- //
- // l.lp.x[1][0..1] are implicitly initialized and do not use values from the
- // "base" initializer; l.lp.x[1] will be "\0\0f\0\0\0".
- //
- // To distinguish Case#1 from Case#2, and also to avoid leaving many "holes"
- // in the InitListExpr, the "holes" in Case#1 are filled not with empty
- // initializers but with special "NoInitExpr" place holders, which tells the
- // CodeGen not to generate any initializers for these parts.
- void FillInEmptyInitForBase(unsigned Init, const CXXBaseSpecifier &Base,
- const InitializedEntity &ParentEntity,
- InitListExpr *ILE, bool &RequiresSecondPass,
- bool FillWithNoInit);
- void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
- const InitializedEntity &ParentEntity,
- InitListExpr *ILE, bool &RequiresSecondPass,
- bool FillWithNoInit = false);
- void FillInEmptyInitializations(const InitializedEntity &Entity,
- InitListExpr *ILE, bool &RequiresSecondPass,
- InitListExpr *OuterILE, unsigned OuterIndex,
- bool FillWithNoInit = false);
- bool CheckFlexibleArrayInit(const InitializedEntity &Entity,
- Expr *InitExpr, FieldDecl *Field,
- bool TopLevelObject);
- void CheckEmptyInitializable(const InitializedEntity &Entity,
- SourceLocation Loc);
- public:
- InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL,
- QualType &T, bool VerifyOnly, bool TreatUnavailableAsInvalid,
- bool InOverloadResolution = false);
- bool HadError() { return hadError; }
- // Retrieves the fully-structured initializer list used for
- // semantic analysis and code generation.
- InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
- };
- } // end anonymous namespace
- ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc,
- const InitializedEntity &Entity) {
- InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
- true);
- MultiExprArg SubInit;
- Expr *InitExpr;
- InitListExpr DummyInitList(SemaRef.Context, Loc, std::nullopt, Loc);
- // C++ [dcl.init.aggr]p7:
- // If there are fewer initializer-clauses in the list than there are
- // members in the aggregate, then each member not explicitly initialized
- // ...
- bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 &&
- Entity.getType()->getBaseElementTypeUnsafe()->isRecordType();
- if (EmptyInitList) {
- // C++1y / DR1070:
- // shall be initialized [...] from an empty initializer list.
- //
- // We apply the resolution of this DR to C++11 but not C++98, since C++98
- // does not have useful semantics for initialization from an init list.
- // We treat this as copy-initialization, because aggregate initialization
- // always performs copy-initialization on its elements.
- //
- // Only do this if we're initializing a class type, to avoid filling in
- // the initializer list where possible.
- InitExpr = VerifyOnly
- ? &DummyInitList
- : new (SemaRef.Context)
- InitListExpr(SemaRef.Context, Loc, std::nullopt, Loc);
- InitExpr->setType(SemaRef.Context.VoidTy);
- SubInit = InitExpr;
- Kind = InitializationKind::CreateCopy(Loc, Loc);
- } else {
- // C++03:
- // shall be value-initialized.
- }
- InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);
- // libstdc++4.6 marks the vector default constructor as explicit in
- // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.
- // stlport does so too. Look for std::__debug for libstdc++, and for
- // std:: for stlport. This is effectively a compiler-side implementation of
- // LWG2193.
- if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
- InitializationSequence::FK_ExplicitConstructor) {
- OverloadCandidateSet::iterator Best;
- OverloadingResult O =
- InitSeq.getFailedCandidateSet()
- .BestViableFunction(SemaRef, Kind.getLocation(), Best);
- (void)O;
- assert(O == OR_Success && "Inconsistent overload resolution");
- CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
- CXXRecordDecl *R = CtorDecl->getParent();
- if (CtorDecl->getMinRequiredArguments() == 0 &&
- CtorDecl->isExplicit() && R->getDeclName() &&
- SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) {
- bool IsInStd = false;
- for (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(R->getDeclContext());
- ND && !IsInStd; ND = dyn_cast<NamespaceDecl>(ND->getParent())) {
- if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND))
- IsInStd = true;
- }
- if (IsInStd && llvm::StringSwitch<bool>(R->getName())
- .Cases("basic_string", "deque", "forward_list", true)
- .Cases("list", "map", "multimap", "multiset", true)
- .Cases("priority_queue", "queue", "set", "stack", true)
- .Cases("unordered_map", "unordered_set", "vector", true)
- .Default(false)) {
- InitSeq.InitializeFrom(
- SemaRef, Entity,
- InitializationKind::CreateValue(Loc, Loc, Loc, true),
- MultiExprArg(), /*TopLevelOfInitList=*/false,
- TreatUnavailableAsInvalid);
- // Emit a warning for this. System header warnings aren't shown
- // by default, but people working on system headers should see it.
- if (!VerifyOnly) {
- SemaRef.Diag(CtorDecl->getLocation(),
- diag::warn_invalid_initializer_from_system_header);
- if (Entity.getKind() == InitializedEntity::EK_Member)
- SemaRef.Diag(Entity.getDecl()->getLocation(),
- diag::note_used_in_initialization_here);
- else if (Entity.getKind() == InitializedEntity::EK_ArrayElement)
- SemaRef.Diag(Loc, diag::note_used_in_initialization_here);
- }
- }
- }
- }
- if (!InitSeq) {
- if (!VerifyOnly) {
- InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);
- if (Entity.getKind() == InitializedEntity::EK_Member)
- SemaRef.Diag(Entity.getDecl()->getLocation(),
- diag::note_in_omitted_aggregate_initializer)
- << /*field*/1 << Entity.getDecl();
- else if (Entity.getKind() == InitializedEntity::EK_ArrayElement) {
- bool IsTrailingArrayNewMember =
- Entity.getParent() &&
- Entity.getParent()->isVariableLengthArrayNew();
- SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)
- << (IsTrailingArrayNewMember ? 2 : /*array element*/0)
- << Entity.getElementIndex();
- }
- }
- hadError = true;
- return ExprError();
- }
- return VerifyOnly ? ExprResult()
- : InitSeq.Perform(SemaRef, Entity, Kind, SubInit);
- }
- void InitListChecker::CheckEmptyInitializable(const InitializedEntity &Entity,
- SourceLocation Loc) {
- // If we're building a fully-structured list, we'll check this at the end
- // once we know which elements are actually initialized. Otherwise, we know
- // that there are no designators so we can just check now.
- if (FullyStructuredList)
- return;
- PerformEmptyInit(Loc, Entity);
- }
- void InitListChecker::FillInEmptyInitForBase(
- unsigned Init, const CXXBaseSpecifier &Base,
- const InitializedEntity &ParentEntity, InitListExpr *ILE,
- bool &RequiresSecondPass, bool FillWithNoInit) {
- InitializedEntity BaseEntity = InitializedEntity::InitializeBase(
- SemaRef.Context, &Base, false, &ParentEntity);
- if (Init >= ILE->getNumInits() || !ILE->getInit(Init)) {
- ExprResult BaseInit = FillWithNoInit
- ? new (SemaRef.Context) NoInitExpr(Base.getType())
- : PerformEmptyInit(ILE->getEndLoc(), BaseEntity);
- if (BaseInit.isInvalid()) {
- hadError = true;
- return;
- }
- if (!VerifyOnly) {
- assert(Init < ILE->getNumInits() && "should have been expanded");
- ILE->setInit(Init, BaseInit.getAs<Expr>());
- }
- } else if (InitListExpr *InnerILE =
- dyn_cast<InitListExpr>(ILE->getInit(Init))) {
- FillInEmptyInitializations(BaseEntity, InnerILE, RequiresSecondPass,
- ILE, Init, FillWithNoInit);
- } else if (DesignatedInitUpdateExpr *InnerDIUE =
- dyn_cast<DesignatedInitUpdateExpr>(ILE->getInit(Init))) {
- FillInEmptyInitializations(BaseEntity, InnerDIUE->getUpdater(),
- RequiresSecondPass, ILE, Init,
- /*FillWithNoInit =*/true);
- }
- }
- void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
- const InitializedEntity &ParentEntity,
- InitListExpr *ILE,
- bool &RequiresSecondPass,
- bool FillWithNoInit) {
- SourceLocation Loc = ILE->getEndLoc();
- unsigned NumInits = ILE->getNumInits();
- InitializedEntity MemberEntity
- = InitializedEntity::InitializeMember(Field, &ParentEntity);
- if (Init >= NumInits || !ILE->getInit(Init)) {
- if (const RecordType *RType = ILE->getType()->getAs<RecordType>())
- if (!RType->getDecl()->isUnion())
- assert((Init < NumInits || VerifyOnly) &&
- "This ILE should have been expanded");
- if (FillWithNoInit) {
- assert(!VerifyOnly && "should not fill with no-init in verify-only mode");
- Expr *Filler = new (SemaRef.Context) NoInitExpr(Field->getType());
- if (Init < NumInits)
- ILE->setInit(Init, Filler);
- else
- ILE->updateInit(SemaRef.Context, Init, Filler);
- return;
- }
- // C++1y [dcl.init.aggr]p7:
- // If there are fewer initializer-clauses in the list than there are
- // members in the aggregate, then each member not explicitly initialized
- // shall be initialized from its brace-or-equal-initializer [...]
- if (Field->hasInClassInitializer()) {
- if (VerifyOnly)
- return;
- ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field);
- if (DIE.isInvalid()) {
- hadError = true;
- return;
- }
- SemaRef.checkInitializerLifetime(MemberEntity, DIE.get());
- if (Init < NumInits)
- ILE->setInit(Init, DIE.get());
- else {
- ILE->updateInit(SemaRef.Context, Init, DIE.get());
- RequiresSecondPass = true;
- }
- return;
- }
- if (Field->getType()->isReferenceType()) {
- if (!VerifyOnly) {
- // C++ [dcl.init.aggr]p9:
- // If an incomplete or empty initializer-list leaves a
- // member of reference type uninitialized, the program is
- // ill-formed.
- SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized)
- << Field->getType()
- << (ILE->isSyntacticForm() ? ILE : ILE->getSyntacticForm())
- ->getSourceRange();
- SemaRef.Diag(Field->getLocation(), diag::note_uninit_reference_member);
- }
- hadError = true;
- return;
- }
- ExprResult MemberInit = PerformEmptyInit(Loc, MemberEntity);
- if (MemberInit.isInvalid()) {
- hadError = true;
- return;
- }
- if (hadError || VerifyOnly) {
- // Do nothing
- } else if (Init < NumInits) {
- ILE->setInit(Init, MemberInit.getAs<Expr>());
- } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
- // Empty initialization requires a constructor call, so
- // extend the initializer list to include the constructor
- // call and make a note that we'll need to take another pass
- // through the initializer list.
- ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
- RequiresSecondPass = true;
- }
- } else if (InitListExpr *InnerILE
- = dyn_cast<InitListExpr>(ILE->getInit(Init))) {
- FillInEmptyInitializations(MemberEntity, InnerILE,
- RequiresSecondPass, ILE, Init, FillWithNoInit);
- } else if (DesignatedInitUpdateExpr *InnerDIUE =
- dyn_cast<DesignatedInitUpdateExpr>(ILE->getInit(Init))) {
- FillInEmptyInitializations(MemberEntity, InnerDIUE->getUpdater(),
- RequiresSecondPass, ILE, Init,
- /*FillWithNoInit =*/true);
- }
- }
- /// Recursively replaces NULL values within the given initializer list
- /// with expressions that perform value-initialization of the
- /// appropriate type, and finish off the InitListExpr formation.
- void
- InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
- InitListExpr *ILE,
- bool &RequiresSecondPass,
- InitListExpr *OuterILE,
- unsigned OuterIndex,
- bool FillWithNoInit) {
- assert((ILE->getType() != SemaRef.Context.VoidTy) &&
- "Should not have void type");
- // We don't need to do any checks when just filling NoInitExprs; that can't
- // fail.
- if (FillWithNoInit && VerifyOnly)
- return;
- // If this is a nested initializer list, we might have changed its contents
- // (and therefore some of its properties, such as instantiation-dependence)
- // while filling it in. Inform the outer initializer list so that its state
- // can be updated to match.
- // FIXME: We should fully build the inner initializers before constructing
- // the outer InitListExpr instead of mutating AST nodes after they have
- // been used as subexpressions of other nodes.
- struct UpdateOuterILEWithUpdatedInit {
- InitListExpr *Outer;
- unsigned OuterIndex;
- ~UpdateOuterILEWithUpdatedInit() {
- if (Outer)
- Outer->setInit(OuterIndex, Outer->getInit(OuterIndex));
- }
- } UpdateOuterRAII = {OuterILE, OuterIndex};
- // A transparent ILE is not performing aggregate initialization and should
- // not be filled in.
- if (ILE->isTransparent())
- return;
- if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
- const RecordDecl *RDecl = RType->getDecl();
- if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
- FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),
- Entity, ILE, RequiresSecondPass, FillWithNoInit);
- else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
- cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
- for (auto *Field : RDecl->fields()) {
- if (Field->hasInClassInitializer()) {
- FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass,
- FillWithNoInit);
- break;
- }
- }
- } else {
- // The fields beyond ILE->getNumInits() are default initialized, so in
- // order to leave them uninitialized, the ILE is expanded and the extra
- // fields are then filled with NoInitExpr.
- unsigned NumElems = numStructUnionElements(ILE->getType());
- if (RDecl->hasFlexibleArrayMember())
- ++NumElems;
- if (!VerifyOnly && ILE->getNumInits() < NumElems)
- ILE->resizeInits(SemaRef.Context, NumElems);
- unsigned Init = 0;
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RDecl)) {
- for (auto &Base : CXXRD->bases()) {
- if (hadError)
- return;
- FillInEmptyInitForBase(Init, Base, Entity, ILE, RequiresSecondPass,
- FillWithNoInit);
- ++Init;
- }
- }
- for (auto *Field : RDecl->fields()) {
- if (Field->isUnnamedBitfield())
- continue;
- if (hadError)
- return;
- FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass,
- FillWithNoInit);
- if (hadError)
- return;
- ++Init;
- // Only look at the first initialization of a union.
- if (RDecl->isUnion())
- break;
- }
- }
- return;
- }
- QualType ElementType;
- InitializedEntity ElementEntity = Entity;
- unsigned NumInits = ILE->getNumInits();
- unsigned NumElements = NumInits;
- if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) {
- ElementType = AType->getElementType();
- if (const auto *CAType = dyn_cast<ConstantArrayType>(AType))
- NumElements = CAType->getSize().getZExtValue();
- // For an array new with an unknown bound, ask for one additional element
- // in order to populate the array filler.
- if (Entity.isVariableLengthArrayNew())
- ++NumElements;
- ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
- 0, Entity);
- } else if (const VectorType *VType = ILE->getType()->getAs<VectorType>()) {
- ElementType = VType->getElementType();
- NumElements = VType->getNumElements();
- ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context,
- 0, Entity);
- } else
- ElementType = ILE->getType();
- bool SkipEmptyInitChecks = false;
- for (unsigned Init = 0; Init != NumElements; ++Init) {
- if (hadError)
- return;
- if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement ||
- ElementEntity.getKind() == InitializedEntity::EK_VectorElement)
- ElementEntity.setElementIndex(Init);
- if (Init >= NumInits && (ILE->hasArrayFiller() || SkipEmptyInitChecks))
- return;
- Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : nullptr);
- if (!InitExpr && Init < NumInits && ILE->hasArrayFiller())
- ILE->setInit(Init, ILE->getArrayFiller());
- else if (!InitExpr && !ILE->hasArrayFiller()) {
- // In VerifyOnly mode, there's no point performing empty initialization
- // more than once.
- if (SkipEmptyInitChecks)
- continue;
- Expr *Filler = nullptr;
- if (FillWithNoInit)
- Filler = new (SemaRef.Context) NoInitExpr(ElementType);
- else {
- ExprResult ElementInit =
- PerformEmptyInit(ILE->getEndLoc(), ElementEntity);
- if (ElementInit.isInvalid()) {
- hadError = true;
- return;
- }
- Filler = ElementInit.getAs<Expr>();
- }
- if (hadError) {
- // Do nothing
- } else if (VerifyOnly) {
- SkipEmptyInitChecks = true;
- } else if (Init < NumInits) {
- // For arrays, just set the expression used for value-initialization
- // of the "holes" in the array.
- if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement)
- ILE->setArrayFiller(Filler);
- else
- ILE->setInit(Init, Filler);
- } else {
- // For arrays, just set the expression used for value-initialization
- // of the rest of elements and exit.
- if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) {
- ILE->setArrayFiller(Filler);
- return;
- }
- if (!isa<ImplicitValueInitExpr>(Filler) && !isa<NoInitExpr>(Filler)) {
- // Empty initialization requires a constructor call, so
- // extend the initializer list to include the constructor
- // call and make a note that we'll need to take another pass
- // through the initializer list.
- ILE->updateInit(SemaRef.Context, Init, Filler);
- RequiresSecondPass = true;
- }
- }
- } else if (InitListExpr *InnerILE
- = dyn_cast_or_null<InitListExpr>(InitExpr)) {
- FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass,
- ILE, Init, FillWithNoInit);
- } else if (DesignatedInitUpdateExpr *InnerDIUE =
- dyn_cast_or_null<DesignatedInitUpdateExpr>(InitExpr)) {
- FillInEmptyInitializations(ElementEntity, InnerDIUE->getUpdater(),
- RequiresSecondPass, ILE, Init,
- /*FillWithNoInit =*/true);
- }
- }
- }
- static bool hasAnyDesignatedInits(const InitListExpr *IL) {
- for (const Stmt *Init : *IL)
- if (Init && isa<DesignatedInitExpr>(Init))
- return true;
- return false;
- }
- InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
- InitListExpr *IL, QualType &T, bool VerifyOnly,
- bool TreatUnavailableAsInvalid,
- bool InOverloadResolution)
- : SemaRef(S), VerifyOnly(VerifyOnly),
- TreatUnavailableAsInvalid(TreatUnavailableAsInvalid),
- InOverloadResolution(InOverloadResolution) {
- if (!VerifyOnly || hasAnyDesignatedInits(IL)) {
- FullyStructuredList =
- createInitListExpr(T, IL->getSourceRange(), IL->getNumInits());
- // FIXME: Check that IL isn't already the semantic form of some other
- // InitListExpr. If it is, we'd create a broken AST.
- if (!VerifyOnly)
- FullyStructuredList->setSyntacticForm(IL);
- }
- CheckExplicitInitList(Entity, IL, T, FullyStructuredList,
- /*TopLevelObject=*/true);
- if (!hadError && FullyStructuredList) {
- bool RequiresSecondPass = false;
- FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass,
- /*OuterILE=*/nullptr, /*OuterIndex=*/0);
- if (RequiresSecondPass && !hadError)
- FillInEmptyInitializations(Entity, FullyStructuredList,
- RequiresSecondPass, nullptr, 0);
- }
- if (hadError && FullyStructuredList)
- FullyStructuredList->markError();
- }
- int InitListChecker::numArrayElements(QualType DeclType) {
- // FIXME: use a proper constant
- int maxElements = 0x7FFFFFFF;
- if (const ConstantArrayType *CAT =
- SemaRef.Context.getAsConstantArrayType(DeclType)) {
- maxElements = static_cast<int>(CAT->getSize().getZExtValue());
- }
- return maxElements;
- }
- int InitListChecker::numStructUnionElements(QualType DeclType) {
- RecordDecl *structDecl = DeclType->castAs<RecordType>()->getDecl();
- int InitializableMembers = 0;
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(structDecl))
- InitializableMembers += CXXRD->getNumBases();
- for (const auto *Field : structDecl->fields())
- if (!Field->isUnnamedBitfield())
- ++InitializableMembers;
- if (structDecl->isUnion())
- return std::min(InitializableMembers, 1);
- return InitializableMembers - structDecl->hasFlexibleArrayMember();
- }
- /// Determine whether Entity is an entity for which it is idiomatic to elide
- /// the braces in aggregate initialization.
- static bool isIdiomaticBraceElisionEntity(const InitializedEntity &Entity) {
- // Recursive initialization of the one and only field within an aggregate
- // class is considered idiomatic. This case arises in particular for
- // initialization of std::array, where the C++ standard suggests the idiom of
- //
- // std::array<T, N> arr = {1, 2, 3};
- //
- // (where std::array is an aggregate struct containing a single array field.
- if (!Entity.getParent())
- return false;
- // Allows elide brace initialization for aggregates with empty base.
- if (Entity.getKind() == InitializedEntity::EK_Base) {
- auto *ParentRD =
- Entity.getParent()->getType()->castAs<RecordType>()->getDecl();
- CXXRecordDecl *CXXRD = cast<CXXRecordDecl>(ParentRD);
- return CXXRD->getNumBases() == 1 && CXXRD->field_empty();
- }
- // Allow brace elision if the only subobject is a field.
- if (Entity.getKind() == InitializedEntity::EK_Member) {
- auto *ParentRD =
- Entity.getParent()->getType()->castAs<RecordType>()->getDecl();
- if (CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(ParentRD)) {
- if (CXXRD->getNumBases()) {
- return false;
- }
- }
- auto FieldIt = ParentRD->field_begin();
- assert(FieldIt != ParentRD->field_end() &&
- "no fields but have initializer for member?");
- return ++FieldIt == ParentRD->field_end();
- }
- return false;
- }
- /// Check whether the range of the initializer \p ParentIList from element
- /// \p Index onwards can be used to initialize an object of type \p T. Update
- /// \p Index to indicate how many elements of the list were consumed.
- ///
- /// This also fills in \p StructuredList, from element \p StructuredIndex
- /// onwards, with the fully-braced, desugared form of the initialization.
- void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity,
- InitListExpr *ParentIList,
- QualType T, unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- int maxElements = 0;
- if (T->isArrayType())
- maxElements = numArrayElements(T);
- else if (T->isRecordType())
- maxElements = numStructUnionElements(T);
- else if (T->isVectorType())
- maxElements = T->castAs<VectorType>()->getNumElements();
- else
- llvm_unreachable("CheckImplicitInitList(): Illegal type");
- if (maxElements == 0) {
- if (!VerifyOnly)
- SemaRef.Diag(ParentIList->getInit(Index)->getBeginLoc(),
- diag::err_implicit_empty_initializer);
- ++Index;
- hadError = true;
- return;
- }
- // Build a structured initializer list corresponding to this subobject.
- InitListExpr *StructuredSubobjectInitList = getStructuredSubobjectInit(
- ParentIList, Index, T, StructuredList, StructuredIndex,
- SourceRange(ParentIList->getInit(Index)->getBeginLoc(),
- ParentIList->getSourceRange().getEnd()));
- unsigned StructuredSubobjectInitIndex = 0;
- // Check the element types and build the structural subobject.
- unsigned StartIndex = Index;
- CheckListElementTypes(Entity, ParentIList, T,
- /*SubobjectIsDesignatorContext=*/false, Index,
- StructuredSubobjectInitList,
- StructuredSubobjectInitIndex);
- if (StructuredSubobjectInitList) {
- StructuredSubobjectInitList->setType(T);
- unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1);
- // Update the structured sub-object initializer so that it's ending
- // range corresponds with the end of the last initializer it used.
- if (EndIndex < ParentIList->getNumInits() &&
- ParentIList->getInit(EndIndex)) {
- SourceLocation EndLoc
- = ParentIList->getInit(EndIndex)->getSourceRange().getEnd();
- StructuredSubobjectInitList->setRBraceLoc(EndLoc);
- }
- // Complain about missing braces.
- if (!VerifyOnly && (T->isArrayType() || T->isRecordType()) &&
- !ParentIList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) &&
- !isIdiomaticBraceElisionEntity(Entity)) {
- SemaRef.Diag(StructuredSubobjectInitList->getBeginLoc(),
- diag::warn_missing_braces)
- << StructuredSubobjectInitList->getSourceRange()
- << FixItHint::CreateInsertion(
- StructuredSubobjectInitList->getBeginLoc(), "{")
- << FixItHint::CreateInsertion(
- SemaRef.getLocForEndOfToken(
- StructuredSubobjectInitList->getEndLoc()),
- "}");
- }
- // Warn if this type won't be an aggregate in future versions of C++.
- auto *CXXRD = T->getAsCXXRecordDecl();
- if (!VerifyOnly && CXXRD && CXXRD->hasUserDeclaredConstructor()) {
- SemaRef.Diag(StructuredSubobjectInitList->getBeginLoc(),
- diag::warn_cxx20_compat_aggregate_init_with_ctors)
- << StructuredSubobjectInitList->getSourceRange() << T;
- }
- }
- }
- /// Warn that \p Entity was of scalar type and was initialized by a
- /// single-element braced initializer list.
- static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
- SourceRange Braces) {
- // Don't warn during template instantiation. If the initialization was
- // non-dependent, we warned during the initial parse; otherwise, the
- // type might not be scalar in some uses of the template.
- if (S.inTemplateInstantiation())
- return;
- unsigned DiagID = 0;
- switch (Entity.getKind()) {
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- case InitializedEntity::EK_ArrayElement:
- case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
- case InitializedEntity::EK_TemplateParameter:
- case InitializedEntity::EK_Result:
- // Extra braces here are suspicious.
- DiagID = diag::warn_braces_around_init;
- break;
- case InitializedEntity::EK_Member:
- // Warn on aggregate initialization but not on ctor init list or
- // default member initializer.
- if (Entity.getParent())
- DiagID = diag::warn_braces_around_init;
- break;
- case InitializedEntity::EK_Variable:
- case InitializedEntity::EK_LambdaCapture:
- // No warning, might be direct-list-initialization.
- // FIXME: Should we warn for copy-list-initialization in these cases?
- break;
- case InitializedEntity::EK_New:
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_CompoundLiteralInit:
- // No warning, braces are part of the syntax of the underlying construct.
- break;
- case InitializedEntity::EK_RelatedResult:
- // No warning, we already warned when initializing the result.
- break;
- case InitializedEntity::EK_Exception:
- case InitializedEntity::EK_Base:
- case InitializedEntity::EK_Delegating:
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_Binding:
- case InitializedEntity::EK_StmtExprResult:
- llvm_unreachable("unexpected braced scalar init");
- }
- if (DiagID) {
- S.Diag(Braces.getBegin(), DiagID)
- << Entity.getType()->isSizelessBuiltinType() << Braces
- << FixItHint::CreateRemoval(Braces.getBegin())
- << FixItHint::CreateRemoval(Braces.getEnd());
- }
- }
- /// Check whether the initializer \p IList (that was written with explicit
- /// braces) can be used to initialize an object of type \p T.
- ///
- /// This also fills in \p StructuredList with the fully-braced, desugared
- /// form of the initialization.
- void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
- InitListExpr *IList, QualType &T,
- InitListExpr *StructuredList,
- bool TopLevelObject) {
- unsigned Index = 0, StructuredIndex = 0;
- CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
- Index, StructuredList, StructuredIndex, TopLevelObject);
- if (StructuredList) {
- QualType ExprTy = T;
- if (!ExprTy->isArrayType())
- ExprTy = ExprTy.getNonLValueExprType(SemaRef.Context);
- if (!VerifyOnly)
- IList->setType(ExprTy);
- StructuredList->setType(ExprTy);
- }
- if (hadError)
- return;
- // Don't complain for incomplete types, since we'll get an error elsewhere.
- if (Index < IList->getNumInits() && !T->isIncompleteType()) {
- // We have leftover initializers
- bool ExtraInitsIsError = SemaRef.getLangOpts().CPlusPlus ||
- (SemaRef.getLangOpts().OpenCL && T->isVectorType());
- hadError = ExtraInitsIsError;
- if (VerifyOnly) {
- return;
- } else if (StructuredIndex == 1 &&
- IsStringInit(StructuredList->getInit(0), T, SemaRef.Context) ==
- SIF_None) {
- unsigned DK =
- ExtraInitsIsError
- ? diag::err_excess_initializers_in_char_array_initializer
- : diag::ext_excess_initializers_in_char_array_initializer;
- SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
- << IList->getInit(Index)->getSourceRange();
- } else if (T->isSizelessBuiltinType()) {
- unsigned DK = ExtraInitsIsError
- ? diag::err_excess_initializers_for_sizeless_type
- : diag::ext_excess_initializers_for_sizeless_type;
- SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
- << T << IList->getInit(Index)->getSourceRange();
- } else {
- int initKind = T->isArrayType() ? 0 :
- T->isVectorType() ? 1 :
- T->isScalarType() ? 2 :
- T->isUnionType() ? 3 :
- 4;
- unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers
- : diag::ext_excess_initializers;
- SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
- << initKind << IList->getInit(Index)->getSourceRange();
- }
- }
- if (!VerifyOnly) {
- if (T->isScalarType() && IList->getNumInits() == 1 &&
- !isa<InitListExpr>(IList->getInit(0)))
- warnBracedScalarInit(SemaRef, Entity, IList->getSourceRange());
- // Warn if this is a class type that won't be an aggregate in future
- // versions of C++.
- auto *CXXRD = T->getAsCXXRecordDecl();
- if (CXXRD && CXXRD->hasUserDeclaredConstructor()) {
- // Don't warn if there's an equivalent default constructor that would be
- // used instead.
- bool HasEquivCtor = false;
- if (IList->getNumInits() == 0) {
- auto *CD = SemaRef.LookupDefaultConstructor(CXXRD);
- HasEquivCtor = CD && !CD->isDeleted();
- }
- if (!HasEquivCtor) {
- SemaRef.Diag(IList->getBeginLoc(),
- diag::warn_cxx20_compat_aggregate_init_with_ctors)
- << IList->getSourceRange() << T;
- }
- }
- }
- }
- void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
- InitListExpr *IList,
- QualType &DeclType,
- bool SubobjectIsDesignatorContext,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool TopLevelObject) {
- if (DeclType->isAnyComplexType() && SubobjectIsDesignatorContext) {
- // Explicitly braced initializer for complex type can be real+imaginary
- // parts.
- CheckComplexType(Entity, IList, DeclType, Index,
- StructuredList, StructuredIndex);
- } else if (DeclType->isScalarType()) {
- CheckScalarType(Entity, IList, DeclType, Index,
- StructuredList, StructuredIndex);
- } else if (DeclType->isVectorType()) {
- CheckVectorType(Entity, IList, DeclType, Index,
- StructuredList, StructuredIndex);
- } else if (DeclType->isRecordType()) {
- assert(DeclType->isAggregateType() &&
- "non-aggregate records should be handed in CheckSubElementType");
- RecordDecl *RD = DeclType->castAs<RecordType>()->getDecl();
- auto Bases =
- CXXRecordDecl::base_class_range(CXXRecordDecl::base_class_iterator(),
- CXXRecordDecl::base_class_iterator());
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
- Bases = CXXRD->bases();
- CheckStructUnionTypes(Entity, IList, DeclType, Bases, RD->field_begin(),
- SubobjectIsDesignatorContext, Index, StructuredList,
- StructuredIndex, TopLevelObject);
- } else if (DeclType->isArrayType()) {
- llvm::APSInt Zero(
- SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
- false);
- CheckArrayType(Entity, IList, DeclType, Zero,
- SubobjectIsDesignatorContext, Index,
- StructuredList, StructuredIndex);
- } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
- // This type is invalid, issue a diagnostic.
- ++Index;
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(), diag::err_illegal_initializer_type)
- << DeclType;
- hadError = true;
- } else if (DeclType->isReferenceType()) {
- CheckReferenceType(Entity, IList, DeclType, Index,
- StructuredList, StructuredIndex);
- } else if (DeclType->isObjCObjectType()) {
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(), diag::err_init_objc_class) << DeclType;
- hadError = true;
- } else if (DeclType->isOCLIntelSubgroupAVCType() ||
- DeclType->isSizelessBuiltinType()) {
- // Checks for scalar type are sufficient for these types too.
- CheckScalarType(Entity, IList, DeclType, Index, StructuredList,
- StructuredIndex);
- } else {
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(), diag::err_illegal_initializer_type)
- << DeclType;
- hadError = true;
- }
- }
- void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
- InitListExpr *IList,
- QualType ElemType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool DirectlyDesignated) {
- Expr *expr = IList->getInit(Index);
- if (ElemType->isReferenceType())
- return CheckReferenceType(Entity, IList, ElemType, Index,
- StructuredList, StructuredIndex);
- if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
- if (SubInitList->getNumInits() == 1 &&
- IsStringInit(SubInitList->getInit(0), ElemType, SemaRef.Context) ==
- SIF_None) {
- // FIXME: It would be more faithful and no less correct to include an
- // InitListExpr in the semantic form of the initializer list in this case.
- expr = SubInitList->getInit(0);
- }
- // Nested aggregate initialization and C++ initialization are handled later.
- } else if (isa<ImplicitValueInitExpr>(expr)) {
- // This happens during template instantiation when we see an InitListExpr
- // that we've already checked once.
- assert(SemaRef.Context.hasSameType(expr->getType(), ElemType) &&
- "found implicit initialization for the wrong type");
- UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
- ++Index;
- return;
- }
- if (SemaRef.getLangOpts().CPlusPlus || isa<InitListExpr>(expr)) {
- // C++ [dcl.init.aggr]p2:
- // Each member is copy-initialized from the corresponding
- // initializer-clause.
- // FIXME: Better EqualLoc?
- InitializationKind Kind =
- InitializationKind::CreateCopy(expr->getBeginLoc(), SourceLocation());
- // Vector elements can be initialized from other vectors in which case
- // we need initialization entity with a type of a vector (and not a vector
- // element!) initializing multiple vector elements.
- auto TmpEntity =
- (ElemType->isExtVectorType() && !Entity.getType()->isExtVectorType())
- ? InitializedEntity::InitializeTemporary(ElemType)
- : Entity;
- InitializationSequence Seq(SemaRef, TmpEntity, Kind, expr,
- /*TopLevelOfInitList*/ true);
- // C++14 [dcl.init.aggr]p13:
- // If the assignment-expression can initialize a member, the member is
- // initialized. Otherwise [...] brace elision is assumed
- //
- // Brace elision is never performed if the element is not an
- // assignment-expression.
- if (Seq || isa<InitListExpr>(expr)) {
- if (!VerifyOnly) {
- ExprResult Result = Seq.Perform(SemaRef, TmpEntity, Kind, expr);
- if (Result.isInvalid())
- hadError = true;
- UpdateStructuredListElement(StructuredList, StructuredIndex,
- Result.getAs<Expr>());
- } else if (!Seq) {
- hadError = true;
- } else if (StructuredList) {
- UpdateStructuredListElement(StructuredList, StructuredIndex,
- getDummyInit());
- }
- ++Index;
- return;
- }
- // Fall through for subaggregate initialization
- } else if (ElemType->isScalarType() || ElemType->isAtomicType()) {
- // FIXME: Need to handle atomic aggregate types with implicit init lists.
- return CheckScalarType(Entity, IList, ElemType, Index,
- StructuredList, StructuredIndex);
- } else if (const ArrayType *arrayType =
- SemaRef.Context.getAsArrayType(ElemType)) {
- // arrayType can be incomplete if we're initializing a flexible
- // array member. There's nothing we can do with the completed
- // type here, though.
- if (IsStringInit(expr, arrayType, SemaRef.Context) == SIF_None) {
- // FIXME: Should we do this checking in verify-only mode?
- if (!VerifyOnly)
- CheckStringInit(expr, ElemType, arrayType, SemaRef);
- if (StructuredList)
- UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
- ++Index;
- return;
- }
- // Fall through for subaggregate initialization.
- } else {
- assert((ElemType->isRecordType() || ElemType->isVectorType() ||
- ElemType->isOpenCLSpecificType()) && "Unexpected type");
- // C99 6.7.8p13:
- //
- // The initializer for a structure or union object that has
- // automatic storage duration shall be either an initializer
- // list as described below, or a single expression that has
- // compatible structure or union type. In the latter case, the
- // initial value of the object, including unnamed members, is
- // that of the expression.
- ExprResult ExprRes = expr;
- if (SemaRef.CheckSingleAssignmentConstraints(
- ElemType, ExprRes, !VerifyOnly) != Sema::Incompatible) {
- if (ExprRes.isInvalid())
- hadError = true;
- else {
- ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.get());
- if (ExprRes.isInvalid())
- hadError = true;
- }
- UpdateStructuredListElement(StructuredList, StructuredIndex,
- ExprRes.getAs<Expr>());
- ++Index;
- return;
- }
- ExprRes.get();
- // Fall through for subaggregate initialization
- }
- // C++ [dcl.init.aggr]p12:
- //
- // [...] Otherwise, if the member is itself a non-empty
- // subaggregate, brace elision is assumed and the initializer is
- // considered for the initialization of the first member of
- // the subaggregate.
- // OpenCL vector initializer is handled elsewhere.
- if ((!SemaRef.getLangOpts().OpenCL && ElemType->isVectorType()) ||
- ElemType->isAggregateType()) {
- CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList,
- StructuredIndex);
- ++StructuredIndex;
- // In C++20, brace elision is not permitted for a designated initializer.
- if (DirectlyDesignated && SemaRef.getLangOpts().CPlusPlus && !hadError) {
- if (InOverloadResolution)
- hadError = true;
- if (!VerifyOnly) {
- SemaRef.Diag(expr->getBeginLoc(),
- diag::ext_designated_init_brace_elision)
- << expr->getSourceRange()
- << FixItHint::CreateInsertion(expr->getBeginLoc(), "{")
- << FixItHint::CreateInsertion(
- SemaRef.getLocForEndOfToken(expr->getEndLoc()), "}");
- }
- }
- } else {
- if (!VerifyOnly) {
- // We cannot initialize this element, so let PerformCopyInitialization
- // produce the appropriate diagnostic. We already checked that this
- // initialization will fail.
- ExprResult Copy =
- SemaRef.PerformCopyInitialization(Entity, SourceLocation(), expr,
- /*TopLevelOfInitList=*/true);
- (void)Copy;
- assert(Copy.isInvalid() &&
- "expected non-aggregate initialization to fail");
- }
- hadError = true;
- ++Index;
- ++StructuredIndex;
- }
- }
- void InitListChecker::CheckComplexType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- assert(Index == 0 && "Index in explicit init list must be zero");
- // As an extension, clang supports complex initializers, which initialize
- // a complex number component-wise. When an explicit initializer list for
- // a complex number contains two initializers, this extension kicks in:
- // it expects the initializer list to contain two elements convertible to
- // the element type of the complex type. The first element initializes
- // the real part, and the second element intitializes the imaginary part.
- if (IList->getNumInits() != 2)
- return CheckScalarType(Entity, IList, DeclType, Index, StructuredList,
- StructuredIndex);
- // This is an extension in C. (The builtin _Complex type does not exist
- // in the C++ standard.)
- if (!SemaRef.getLangOpts().CPlusPlus && !VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(), diag::ext_complex_component_init)
- << IList->getSourceRange();
- // Initialize the complex number.
- QualType elementType = DeclType->castAs<ComplexType>()->getElementType();
- InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
- for (unsigned i = 0; i < 2; ++i) {
- ElementEntity.setElementIndex(Index);
- CheckSubElementType(ElementEntity, IList, elementType, Index,
- StructuredList, StructuredIndex);
- }
- }
- void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- if (Index >= IList->getNumInits()) {
- if (!VerifyOnly) {
- if (DeclType->isSizelessBuiltinType())
- SemaRef.Diag(IList->getBeginLoc(),
- SemaRef.getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_empty_sizeless_initializer
- : diag::err_empty_sizeless_initializer)
- << DeclType << IList->getSourceRange();
- else
- SemaRef.Diag(IList->getBeginLoc(),
- SemaRef.getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_empty_scalar_initializer
- : diag::err_empty_scalar_initializer)
- << IList->getSourceRange();
- }
- hadError = !SemaRef.getLangOpts().CPlusPlus11;
- ++Index;
- ++StructuredIndex;
- return;
- }
- Expr *expr = IList->getInit(Index);
- if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) {
- // FIXME: This is invalid, and accepting it causes overload resolution
- // to pick the wrong overload in some corner cases.
- if (!VerifyOnly)
- SemaRef.Diag(SubIList->getBeginLoc(), diag::ext_many_braces_around_init)
- << DeclType->isSizelessBuiltinType() << SubIList->getSourceRange();
- CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
- StructuredIndex);
- return;
- } else if (isa<DesignatedInitExpr>(expr)) {
- if (!VerifyOnly)
- SemaRef.Diag(expr->getBeginLoc(),
- diag::err_designator_for_scalar_or_sizeless_init)
- << DeclType->isSizelessBuiltinType() << DeclType
- << expr->getSourceRange();
- hadError = true;
- ++Index;
- ++StructuredIndex;
- return;
- }
- ExprResult Result;
- if (VerifyOnly) {
- if (SemaRef.CanPerformCopyInitialization(Entity, expr))
- Result = getDummyInit();
- else
- Result = ExprError();
- } else {
- Result =
- SemaRef.PerformCopyInitialization(Entity, expr->getBeginLoc(), expr,
- /*TopLevelOfInitList=*/true);
- }
- Expr *ResultExpr = nullptr;
- if (Result.isInvalid())
- hadError = true; // types weren't compatible.
- else {
- ResultExpr = Result.getAs<Expr>();
- if (ResultExpr != expr && !VerifyOnly) {
- // The type was promoted, update initializer list.
- // FIXME: Why are we updating the syntactic init list?
- IList->setInit(Index, ResultExpr);
- }
- }
- UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr);
- ++Index;
- }
- void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- if (Index >= IList->getNumInits()) {
- // FIXME: It would be wonderful if we could point at the actual member. In
- // general, it would be useful to pass location information down the stack,
- // so that we know the location (or decl) of the "current object" being
- // initialized.
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(),
- diag::err_init_reference_member_uninitialized)
- << DeclType << IList->getSourceRange();
- hadError = true;
- ++Index;
- ++StructuredIndex;
- return;
- }
- Expr *expr = IList->getInit(Index);
- if (isa<InitListExpr>(expr) && !SemaRef.getLangOpts().CPlusPlus11) {
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(), diag::err_init_non_aggr_init_list)
- << DeclType << IList->getSourceRange();
- hadError = true;
- ++Index;
- ++StructuredIndex;
- return;
- }
- ExprResult Result;
- if (VerifyOnly) {
- if (SemaRef.CanPerformCopyInitialization(Entity,expr))
- Result = getDummyInit();
- else
- Result = ExprError();
- } else {
- Result =
- SemaRef.PerformCopyInitialization(Entity, expr->getBeginLoc(), expr,
- /*TopLevelOfInitList=*/true);
- }
- if (Result.isInvalid())
- hadError = true;
- expr = Result.getAs<Expr>();
- // FIXME: Why are we updating the syntactic init list?
- if (!VerifyOnly && expr)
- IList->setInit(Index, expr);
- UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
- ++Index;
- }
- void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType DeclType,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- const VectorType *VT = DeclType->castAs<VectorType>();
- unsigned maxElements = VT->getNumElements();
- unsigned numEltsInit = 0;
- QualType elementType = VT->getElementType();
- if (Index >= IList->getNumInits()) {
- // Make sure the element type can be value-initialized.
- CheckEmptyInitializable(
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),
- IList->getEndLoc());
- return;
- }
- if (!SemaRef.getLangOpts().OpenCL && !SemaRef.getLangOpts().HLSL ) {
- // If the initializing element is a vector, try to copy-initialize
- // instead of breaking it apart (which is doomed to failure anyway).
- Expr *Init = IList->getInit(Index);
- if (!isa<InitListExpr>(Init) && Init->getType()->isVectorType()) {
- ExprResult Result;
- if (VerifyOnly) {
- if (SemaRef.CanPerformCopyInitialization(Entity, Init))
- Result = getDummyInit();
- else
- Result = ExprError();
- } else {
- Result =
- SemaRef.PerformCopyInitialization(Entity, Init->getBeginLoc(), Init,
- /*TopLevelOfInitList=*/true);
- }
- Expr *ResultExpr = nullptr;
- if (Result.isInvalid())
- hadError = true; // types weren't compatible.
- else {
- ResultExpr = Result.getAs<Expr>();
- if (ResultExpr != Init && !VerifyOnly) {
- // The type was promoted, update initializer list.
- // FIXME: Why are we updating the syntactic init list?
- IList->setInit(Index, ResultExpr);
- }
- }
- UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr);
- ++Index;
- return;
- }
- InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
- for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) {
- // Don't attempt to go past the end of the init list
- if (Index >= IList->getNumInits()) {
- CheckEmptyInitializable(ElementEntity, IList->getEndLoc());
- break;
- }
- ElementEntity.setElementIndex(Index);
- CheckSubElementType(ElementEntity, IList, elementType, Index,
- StructuredList, StructuredIndex);
- }
- if (VerifyOnly)
- return;
- bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
- const VectorType *T = Entity.getType()->castAs<VectorType>();
- if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
- T->getVectorKind() == VectorType::NeonPolyVector)) {
- // The ability to use vector initializer lists is a GNU vector extension
- // and is unrelated to the NEON intrinsics in arm_neon.h. On little
- // endian machines it works fine, however on big endian machines it
- // exhibits surprising behaviour:
- //
- // uint32x2_t x = {42, 64};
- // return vget_lane_u32(x, 0); // Will return 64.
- //
- // Because of this, explicitly call out that it is non-portable.
- //
- SemaRef.Diag(IList->getBeginLoc(),
- diag::warn_neon_vector_initializer_non_portable);
- const char *typeCode;
- unsigned typeSize = SemaRef.Context.getTypeSize(elementType);
- if (elementType->isFloatingType())
- typeCode = "f";
- else if (elementType->isSignedIntegerType())
- typeCode = "s";
- else if (elementType->isUnsignedIntegerType())
- typeCode = "u";
- else
- llvm_unreachable("Invalid element type!");
- SemaRef.Diag(IList->getBeginLoc(),
- SemaRef.Context.getTypeSize(VT) > 64
- ? diag::note_neon_vector_initializer_non_portable_q
- : diag::note_neon_vector_initializer_non_portable)
- << typeCode << typeSize;
- }
- return;
- }
- InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
- // OpenCL and HLSL initializers allow vectors to be constructed from vectors.
- for (unsigned i = 0; i < maxElements; ++i) {
- // Don't attempt to go past the end of the init list
- if (Index >= IList->getNumInits())
- break;
- ElementEntity.setElementIndex(Index);
- QualType IType = IList->getInit(Index)->getType();
- if (!IType->isVectorType()) {
- CheckSubElementType(ElementEntity, IList, elementType, Index,
- StructuredList, StructuredIndex);
- ++numEltsInit;
- } else {
- QualType VecType;
- const VectorType *IVT = IType->castAs<VectorType>();
- unsigned numIElts = IVT->getNumElements();
- if (IType->isExtVectorType())
- VecType = SemaRef.Context.getExtVectorType(elementType, numIElts);
- else
- VecType = SemaRef.Context.getVectorType(elementType, numIElts,
- IVT->getVectorKind());
- CheckSubElementType(ElementEntity, IList, VecType, Index,
- StructuredList, StructuredIndex);
- numEltsInit += numIElts;
- }
- }
- // OpenCL and HLSL require all elements to be initialized.
- if (numEltsInit != maxElements) {
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(),
- diag::err_vector_incorrect_num_initializers)
- << (numEltsInit < maxElements) << maxElements << numEltsInit;
- hadError = true;
- }
- }
- /// Check if the type of a class element has an accessible destructor, and marks
- /// it referenced. Returns true if we shouldn't form a reference to the
- /// destructor.
- ///
- /// Aggregate initialization requires a class element's destructor be
- /// accessible per 11.6.1 [dcl.init.aggr]:
- ///
- /// The destructor for each element of class type is potentially invoked
- /// (15.4 [class.dtor]) from the context where the aggregate initialization
- /// occurs.
- static bool checkDestructorReference(QualType ElementType, SourceLocation Loc,
- Sema &SemaRef) {
- auto *CXXRD = ElementType->getAsCXXRecordDecl();
- if (!CXXRD)
- return false;
- CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(CXXRD);
- SemaRef.CheckDestructorAccess(Loc, Destructor,
- SemaRef.PDiag(diag::err_access_dtor_temp)
- << ElementType);
- SemaRef.MarkFunctionReferenced(Loc, Destructor);
- return SemaRef.DiagnoseUseOfDecl(Destructor, Loc);
- }
- void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
- InitListExpr *IList, QualType &DeclType,
- llvm::APSInt elementIndex,
- bool SubobjectIsDesignatorContext,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex) {
- const ArrayType *arrayType = SemaRef.Context.getAsArrayType(DeclType);
- if (!VerifyOnly) {
- if (checkDestructorReference(arrayType->getElementType(),
- IList->getEndLoc(), SemaRef)) {
- hadError = true;
- return;
- }
- }
- // Check for the special-case of initializing an array with a string.
- if (Index < IList->getNumInits()) {
- if (IsStringInit(IList->getInit(Index), arrayType, SemaRef.Context) ==
- SIF_None) {
- // We place the string literal directly into the resulting
- // initializer list. This is the only place where the structure
- // of the structured initializer list doesn't match exactly,
- // because doing so would involve allocating one character
- // constant for each string.
- // FIXME: Should we do these checks in verify-only mode too?
- if (!VerifyOnly)
- CheckStringInit(IList->getInit(Index), DeclType, arrayType, SemaRef);
- if (StructuredList) {
- UpdateStructuredListElement(StructuredList, StructuredIndex,
- IList->getInit(Index));
- StructuredList->resizeInits(SemaRef.Context, StructuredIndex);
- }
- ++Index;
- return;
- }
- }
- if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(arrayType)) {
- // Check for VLAs; in standard C it would be possible to check this
- // earlier, but I don't know where clang accepts VLAs (gcc accepts
- // them in all sorts of strange places).
- if (!VerifyOnly)
- SemaRef.Diag(VAT->getSizeExpr()->getBeginLoc(),
- diag::err_variable_object_no_init)
- << VAT->getSizeExpr()->getSourceRange();
- hadError = true;
- ++Index;
- ++StructuredIndex;
- return;
- }
- // We might know the maximum number of elements in advance.
- llvm::APSInt maxElements(elementIndex.getBitWidth(),
- elementIndex.isUnsigned());
- bool maxElementsKnown = false;
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(arrayType)) {
- maxElements = CAT->getSize();
- elementIndex = elementIndex.extOrTrunc(maxElements.getBitWidth());
- elementIndex.setIsUnsigned(maxElements.isUnsigned());
- maxElementsKnown = true;
- }
- QualType elementType = arrayType->getElementType();
- while (Index < IList->getNumInits()) {
- Expr *Init = IList->getInit(Index);
- if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Init)) {
- // If we're not the subobject that matches up with the '{' for
- // the designator, we shouldn't be handling the
- // designator. Return immediately.
- if (!SubobjectIsDesignatorContext)
- return;
- // Handle this designated initializer. elementIndex will be
- // updated to be the next array element we'll initialize.
- if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
- DeclType, nullptr, &elementIndex, Index,
- StructuredList, StructuredIndex, true,
- false)) {
- hadError = true;
- continue;
- }
- if (elementIndex.getBitWidth() > maxElements.getBitWidth())
- maxElements = maxElements.extend(elementIndex.getBitWidth());
- else if (elementIndex.getBitWidth() < maxElements.getBitWidth())
- elementIndex = elementIndex.extend(maxElements.getBitWidth());
- elementIndex.setIsUnsigned(maxElements.isUnsigned());
- // If the array is of incomplete type, keep track of the number of
- // elements in the initializer.
- if (!maxElementsKnown && elementIndex > maxElements)
- maxElements = elementIndex;
- continue;
- }
- // If we know the maximum number of elements, and we've already
- // hit it, stop consuming elements in the initializer list.
- if (maxElementsKnown && elementIndex == maxElements)
- break;
- InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex,
- Entity);
- // Check this element.
- CheckSubElementType(ElementEntity, IList, elementType, Index,
- StructuredList, StructuredIndex);
- ++elementIndex;
- // If the array is of incomplete type, keep track of the number of
- // elements in the initializer.
- if (!maxElementsKnown && elementIndex > maxElements)
- maxElements = elementIndex;
- }
- if (!hadError && DeclType->isIncompleteArrayType() && !VerifyOnly) {
- // If this is an incomplete array type, the actual type needs to
- // be calculated here.
- llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned());
- if (maxElements == Zero && !Entity.isVariableLengthArrayNew()) {
- // Sizing an array implicitly to zero is not allowed by ISO C,
- // but is supported by GNU.
- SemaRef.Diag(IList->getBeginLoc(), diag::ext_typecheck_zero_array_size);
- }
- DeclType = SemaRef.Context.getConstantArrayType(
- elementType, maxElements, nullptr, ArrayType::Normal, 0);
- }
- if (!hadError) {
- // If there are any members of the array that get value-initialized, check
- // that is possible. That happens if we know the bound and don't have
- // enough elements, or if we're performing an array new with an unknown
- // bound.
- if ((maxElementsKnown && elementIndex < maxElements) ||
- Entity.isVariableLengthArrayNew())
- CheckEmptyInitializable(
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),
- IList->getEndLoc());
- }
- }
- bool InitListChecker::CheckFlexibleArrayInit(const InitializedEntity &Entity,
- Expr *InitExpr,
- FieldDecl *Field,
- bool TopLevelObject) {
- // Handle GNU flexible array initializers.
- unsigned FlexArrayDiag;
- if (isa<InitListExpr>(InitExpr) &&
- cast<InitListExpr>(InitExpr)->getNumInits() == 0) {
- // Empty flexible array init always allowed as an extension
- FlexArrayDiag = diag::ext_flexible_array_init;
- } else if (!TopLevelObject) {
- // Disallow flexible array init on non-top-level object
- FlexArrayDiag = diag::err_flexible_array_init;
- } else if (Entity.getKind() != InitializedEntity::EK_Variable) {
- // Disallow flexible array init on anything which is not a variable.
- FlexArrayDiag = diag::err_flexible_array_init;
- } else if (cast<VarDecl>(Entity.getDecl())->hasLocalStorage()) {
- // Disallow flexible array init on local variables.
- FlexArrayDiag = diag::err_flexible_array_init;
- } else {
- // Allow other cases.
- FlexArrayDiag = diag::ext_flexible_array_init;
- }
- if (!VerifyOnly) {
- SemaRef.Diag(InitExpr->getBeginLoc(), FlexArrayDiag)
- << InitExpr->getBeginLoc();
- SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
- << Field;
- }
- return FlexArrayDiag != diag::ext_flexible_array_init;
- }
- void InitListChecker::CheckStructUnionTypes(
- const InitializedEntity &Entity, InitListExpr *IList, QualType DeclType,
- CXXRecordDecl::base_class_range Bases, RecordDecl::field_iterator Field,
- bool SubobjectIsDesignatorContext, unsigned &Index,
- InitListExpr *StructuredList, unsigned &StructuredIndex,
- bool TopLevelObject) {
- RecordDecl *structDecl = DeclType->castAs<RecordType>()->getDecl();
- // If the record is invalid, some of it's members are invalid. To avoid
- // confusion, we forgo checking the initializer for the entire record.
- if (structDecl->isInvalidDecl()) {
- // Assume it was supposed to consume a single initializer.
- ++Index;
- hadError = true;
- return;
- }
- if (DeclType->isUnionType() && IList->getNumInits() == 0) {
- RecordDecl *RD = DeclType->castAs<RecordType>()->getDecl();
- if (!VerifyOnly)
- for (FieldDecl *FD : RD->fields()) {
- QualType ET = SemaRef.Context.getBaseElementType(FD->getType());
- if (checkDestructorReference(ET, IList->getEndLoc(), SemaRef)) {
- hadError = true;
- return;
- }
- }
- // If there's a default initializer, use it.
- if (isa<CXXRecordDecl>(RD) &&
- cast<CXXRecordDecl>(RD)->hasInClassInitializer()) {
- if (!StructuredList)
- return;
- for (RecordDecl::field_iterator FieldEnd = RD->field_end();
- Field != FieldEnd; ++Field) {
- if (Field->hasInClassInitializer()) {
- StructuredList->setInitializedFieldInUnion(*Field);
- // FIXME: Actually build a CXXDefaultInitExpr?
- return;
- }
- }
- }
- // Value-initialize the first member of the union that isn't an unnamed
- // bitfield.
- for (RecordDecl::field_iterator FieldEnd = RD->field_end();
- Field != FieldEnd; ++Field) {
- if (!Field->isUnnamedBitfield()) {
- CheckEmptyInitializable(
- InitializedEntity::InitializeMember(*Field, &Entity),
- IList->getEndLoc());
- if (StructuredList)
- StructuredList->setInitializedFieldInUnion(*Field);
- break;
- }
- }
- return;
- }
- bool InitializedSomething = false;
- // If we have any base classes, they are initialized prior to the fields.
- for (auto &Base : Bases) {
- Expr *Init = Index < IList->getNumInits() ? IList->getInit(Index) : nullptr;
- // Designated inits always initialize fields, so if we see one, all
- // remaining base classes have no explicit initializer.
- if (Init && isa<DesignatedInitExpr>(Init))
- Init = nullptr;
- SourceLocation InitLoc = Init ? Init->getBeginLoc() : IList->getEndLoc();
- InitializedEntity BaseEntity = InitializedEntity::InitializeBase(
- SemaRef.Context, &Base, false, &Entity);
- if (Init) {
- CheckSubElementType(BaseEntity, IList, Base.getType(), Index,
- StructuredList, StructuredIndex);
- InitializedSomething = true;
- } else {
- CheckEmptyInitializable(BaseEntity, InitLoc);
- }
- if (!VerifyOnly)
- if (checkDestructorReference(Base.getType(), InitLoc, SemaRef)) {
- hadError = true;
- return;
- }
- }
- // If structDecl is a forward declaration, this loop won't do
- // anything except look at designated initializers; That's okay,
- // because an error should get printed out elsewhere. It might be
- // worthwhile to skip over the rest of the initializer, though.
- RecordDecl *RD = DeclType->castAs<RecordType>()->getDecl();
- RecordDecl::field_iterator FieldEnd = RD->field_end();
- size_t NumRecordDecls = llvm::count_if(RD->decls(), [&](const Decl *D) {
- return isa<FieldDecl>(D) || isa<RecordDecl>(D);
- });
- bool CheckForMissingFields =
- !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
- bool HasDesignatedInit = false;
- while (Index < IList->getNumInits()) {
- Expr *Init = IList->getInit(Index);
- SourceLocation InitLoc = Init->getBeginLoc();
- if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Init)) {
- // If we're not the subobject that matches up with the '{' for
- // the designator, we shouldn't be handling the
- // designator. Return immediately.
- if (!SubobjectIsDesignatorContext)
- return;
- HasDesignatedInit = true;
- // Handle this designated initializer. Field will be updated to
- // the next field that we'll be initializing.
- if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
- DeclType, &Field, nullptr, Index,
- StructuredList, StructuredIndex,
- true, TopLevelObject))
- hadError = true;
- else if (!VerifyOnly) {
- // Find the field named by the designated initializer.
- RecordDecl::field_iterator F = RD->field_begin();
- while (std::next(F) != Field)
- ++F;
- QualType ET = SemaRef.Context.getBaseElementType(F->getType());
- if (checkDestructorReference(ET, InitLoc, SemaRef)) {
- hadError = true;
- return;
- }
- }
- InitializedSomething = true;
- // Disable check for missing fields when designators are used.
- // This matches gcc behaviour.
- CheckForMissingFields = false;
- continue;
- }
- // Check if this is an initializer of forms:
- //
- // struct foo f = {};
- // struct foo g = {0};
- //
- // These are okay for randomized structures. [C99 6.7.8p19]
- //
- // Also, if there is only one element in the structure, we allow something
- // like this, because it's really not randomized in the tranditional sense.
- //
- // struct foo h = {bar};
- auto IsZeroInitializer = [&](const Expr *I) {
- if (IList->getNumInits() == 1) {
- if (NumRecordDecls == 1)
- return true;
- if (const auto *IL = dyn_cast<IntegerLiteral>(I))
- return IL->getValue().isZero();
- }
- return false;
- };
- // Don't allow non-designated initializers on randomized structures.
- if (RD->isRandomized() && !IsZeroInitializer(Init)) {
- if (!VerifyOnly)
- SemaRef.Diag(InitLoc, diag::err_non_designated_init_used);
- hadError = true;
- break;
- }
- if (Field == FieldEnd) {
- // We've run out of fields. We're done.
- break;
- }
- // We've already initialized a member of a union. We're done.
- if (InitializedSomething && DeclType->isUnionType())
- break;
- // If we've hit the flexible array member at the end, we're done.
- if (Field->getType()->isIncompleteArrayType())
- break;
- if (Field->isUnnamedBitfield()) {
- // Don't initialize unnamed bitfields, e.g. "int : 20;"
- ++Field;
- continue;
- }
- // Make sure we can use this declaration.
- bool InvalidUse;
- if (VerifyOnly)
- InvalidUse = !SemaRef.CanUseDecl(*Field, TreatUnavailableAsInvalid);
- else
- InvalidUse = SemaRef.DiagnoseUseOfDecl(
- *Field, IList->getInit(Index)->getBeginLoc());
- if (InvalidUse) {
- ++Index;
- ++Field;
- hadError = true;
- continue;
- }
- if (!VerifyOnly) {
- QualType ET = SemaRef.Context.getBaseElementType(Field->getType());
- if (checkDestructorReference(ET, InitLoc, SemaRef)) {
- hadError = true;
- return;
- }
- }
- InitializedEntity MemberEntity =
- InitializedEntity::InitializeMember(*Field, &Entity);
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
- StructuredList, StructuredIndex);
- InitializedSomething = true;
- if (DeclType->isUnionType() && StructuredList) {
- // Initialize the first field within the union.
- StructuredList->setInitializedFieldInUnion(*Field);
- }
- ++Field;
- }
- // Emit warnings for missing struct field initializers.
- if (!VerifyOnly && InitializedSomething && CheckForMissingFields &&
- Field != FieldEnd && !Field->getType()->isIncompleteArrayType() &&
- !DeclType->isUnionType()) {
- // It is possible we have one or more unnamed bitfields remaining.
- // Find first (if any) named field and emit warning.
- for (RecordDecl::field_iterator it = Field, end = RD->field_end();
- it != end; ++it) {
- if (!it->isUnnamedBitfield() && !it->hasInClassInitializer()) {
- SemaRef.Diag(IList->getSourceRange().getEnd(),
- diag::warn_missing_field_initializers) << *it;
- break;
- }
- }
- }
- // Check that any remaining fields can be value-initialized if we're not
- // building a structured list. (If we are, we'll check this later.)
- if (!StructuredList && Field != FieldEnd && !DeclType->isUnionType() &&
- !Field->getType()->isIncompleteArrayType()) {
- for (; Field != FieldEnd && !hadError; ++Field) {
- if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())
- CheckEmptyInitializable(
- InitializedEntity::InitializeMember(*Field, &Entity),
- IList->getEndLoc());
- }
- }
- // Check that the types of the remaining fields have accessible destructors.
- if (!VerifyOnly) {
- // If the initializer expression has a designated initializer, check the
- // elements for which a designated initializer is not provided too.
- RecordDecl::field_iterator I = HasDesignatedInit ? RD->field_begin()
- : Field;
- for (RecordDecl::field_iterator E = RD->field_end(); I != E; ++I) {
- QualType ET = SemaRef.Context.getBaseElementType(I->getType());
- if (checkDestructorReference(ET, IList->getEndLoc(), SemaRef)) {
- hadError = true;
- return;
- }
- }
- }
- if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
- Index >= IList->getNumInits())
- return;
- if (CheckFlexibleArrayInit(Entity, IList->getInit(Index), *Field,
- TopLevelObject)) {
- hadError = true;
- ++Index;
- return;
- }
- InitializedEntity MemberEntity =
- InitializedEntity::InitializeMember(*Field, &Entity);
- if (isa<InitListExpr>(IList->getInit(Index)))
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
- StructuredList, StructuredIndex);
- else
- CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index,
- StructuredList, StructuredIndex);
- }
- /// Expand a field designator that refers to a member of an
- /// anonymous struct or union into a series of field designators that
- /// refers to the field within the appropriate subobject.
- ///
- static void ExpandAnonymousFieldDesignator(Sema &SemaRef,
- DesignatedInitExpr *DIE,
- unsigned DesigIdx,
- IndirectFieldDecl *IndirectField) {
- typedef DesignatedInitExpr::Designator Designator;
- // Build the replacement designators.
- SmallVector<Designator, 4> Replacements;
- for (IndirectFieldDecl::chain_iterator PI = IndirectField->chain_begin(),
- PE = IndirectField->chain_end(); PI != PE; ++PI) {
- if (PI + 1 == PE)
- Replacements.push_back(Designator((IdentifierInfo *)nullptr,
- DIE->getDesignator(DesigIdx)->getDotLoc(),
- DIE->getDesignator(DesigIdx)->getFieldLoc()));
- else
- Replacements.push_back(Designator((IdentifierInfo *)nullptr,
- SourceLocation(), SourceLocation()));
- assert(isa<FieldDecl>(*PI));
- Replacements.back().setField(cast<FieldDecl>(*PI));
- }
- // Expand the current designator into the set of replacement
- // designators, so we have a full subobject path down to where the
- // member of the anonymous struct/union is actually stored.
- DIE->ExpandDesignator(SemaRef.Context, DesigIdx, &Replacements[0],
- &Replacements[0] + Replacements.size());
- }
- static DesignatedInitExpr *CloneDesignatedInitExpr(Sema &SemaRef,
- DesignatedInitExpr *DIE) {
- unsigned NumIndexExprs = DIE->getNumSubExprs() - 1;
- SmallVector<Expr*, 4> IndexExprs(NumIndexExprs);
- for (unsigned I = 0; I < NumIndexExprs; ++I)
- IndexExprs[I] = DIE->getSubExpr(I + 1);
- return DesignatedInitExpr::Create(SemaRef.Context, DIE->designators(),
- IndexExprs,
- DIE->getEqualOrColonLoc(),
- DIE->usesGNUSyntax(), DIE->getInit());
- }
- namespace {
- // Callback to only accept typo corrections that are for field members of
- // the given struct or union.
- class FieldInitializerValidatorCCC final : public CorrectionCandidateCallback {
- public:
- explicit FieldInitializerValidatorCCC(RecordDecl *RD)
- : Record(RD) {}
- bool ValidateCandidate(const TypoCorrection &candidate) override {
- FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>();
- return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record);
- }
- std::unique_ptr<CorrectionCandidateCallback> clone() override {
- return std::make_unique<FieldInitializerValidatorCCC>(*this);
- }
- private:
- RecordDecl *Record;
- };
- } // end anonymous namespace
- /// Check the well-formedness of a C99 designated initializer.
- ///
- /// Determines whether the designated initializer @p DIE, which
- /// resides at the given @p Index within the initializer list @p
- /// IList, is well-formed for a current object of type @p DeclType
- /// (C99 6.7.8). The actual subobject that this designator refers to
- /// within the current subobject is returned in either
- /// @p NextField or @p NextElementIndex (whichever is appropriate).
- ///
- /// @param IList The initializer list in which this designated
- /// initializer occurs.
- ///
- /// @param DIE The designated initializer expression.
- ///
- /// @param DesigIdx The index of the current designator.
- ///
- /// @param CurrentObjectType The type of the "current object" (C99 6.7.8p17),
- /// into which the designation in @p DIE should refer.
- ///
- /// @param NextField If non-NULL and the first designator in @p DIE is
- /// a field, this will be set to the field declaration corresponding
- /// to the field named by the designator. On input, this is expected to be
- /// the next field that would be initialized in the absence of designation,
- /// if the complete object being initialized is a struct.
- ///
- /// @param NextElementIndex If non-NULL and the first designator in @p
- /// DIE is an array designator or GNU array-range designator, this
- /// will be set to the last index initialized by this designator.
- ///
- /// @param Index Index into @p IList where the designated initializer
- /// @p DIE occurs.
- ///
- /// @param StructuredList The initializer list expression that
- /// describes all of the subobject initializers in the order they'll
- /// actually be initialized.
- ///
- /// @returns true if there was an error, false otherwise.
- bool
- InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
- InitListExpr *IList,
- DesignatedInitExpr *DIE,
- unsigned DesigIdx,
- QualType &CurrentObjectType,
- RecordDecl::field_iterator *NextField,
- llvm::APSInt *NextElementIndex,
- unsigned &Index,
- InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- bool FinishSubobjectInit,
- bool TopLevelObject) {
- if (DesigIdx == DIE->size()) {
- // C++20 designated initialization can result in direct-list-initialization
- // of the designated subobject. This is the only way that we can end up
- // performing direct initialization as part of aggregate initialization, so
- // it needs special handling.
- if (DIE->isDirectInit()) {
- Expr *Init = DIE->getInit();
- assert(isa<InitListExpr>(Init) &&
- "designator result in direct non-list initialization?");
- InitializationKind Kind = InitializationKind::CreateDirectList(
- DIE->getBeginLoc(), Init->getBeginLoc(), Init->getEndLoc());
- InitializationSequence Seq(SemaRef, Entity, Kind, Init,
- /*TopLevelOfInitList*/ true);
- if (StructuredList) {
- ExprResult Result = VerifyOnly
- ? getDummyInit()
- : Seq.Perform(SemaRef, Entity, Kind, Init);
- UpdateStructuredListElement(StructuredList, StructuredIndex,
- Result.get());
- }
- ++Index;
- return !Seq;
- }
- // Check the actual initialization for the designated object type.
- bool prevHadError = hadError;
- // Temporarily remove the designator expression from the
- // initializer list that the child calls see, so that we don't try
- // to re-process the designator.
- unsigned OldIndex = Index;
- IList->setInit(OldIndex, DIE->getInit());
- CheckSubElementType(Entity, IList, CurrentObjectType, Index, StructuredList,
- StructuredIndex, /*DirectlyDesignated=*/true);
- // Restore the designated initializer expression in the syntactic
- // form of the initializer list.
- if (IList->getInit(OldIndex) != DIE->getInit())
- DIE->setInit(IList->getInit(OldIndex));
- IList->setInit(OldIndex, DIE);
- return hadError && !prevHadError;
- }
- DesignatedInitExpr::Designator *D = DIE->getDesignator(DesigIdx);
- bool IsFirstDesignator = (DesigIdx == 0);
- if (IsFirstDesignator ? FullyStructuredList : StructuredList) {
- // Determine the structural initializer list that corresponds to the
- // current subobject.
- if (IsFirstDesignator)
- StructuredList = FullyStructuredList;
- else {
- Expr *ExistingInit = StructuredIndex < StructuredList->getNumInits() ?
- StructuredList->getInit(StructuredIndex) : nullptr;
- if (!ExistingInit && StructuredList->hasArrayFiller())
- ExistingInit = StructuredList->getArrayFiller();
- if (!ExistingInit)
- StructuredList = getStructuredSubobjectInit(
- IList, Index, CurrentObjectType, StructuredList, StructuredIndex,
- SourceRange(D->getBeginLoc(), DIE->getEndLoc()));
- else if (InitListExpr *Result = dyn_cast<InitListExpr>(ExistingInit))
- StructuredList = Result;
- else {
- // We are creating an initializer list that initializes the
- // subobjects of the current object, but there was already an
- // initialization that completely initialized the current
- // subobject, e.g., by a compound literal:
- //
- // struct X { int a, b; };
- // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };
- //
- // Here, xs[0].a == 1 and xs[0].b == 3, since the second,
- // designated initializer re-initializes only its current object
- // subobject [0].b.
- diagnoseInitOverride(ExistingInit,
- SourceRange(D->getBeginLoc(), DIE->getEndLoc()),
- /*FullyOverwritten=*/false);
- if (!VerifyOnly) {
- if (DesignatedInitUpdateExpr *E =
- dyn_cast<DesignatedInitUpdateExpr>(ExistingInit))
- StructuredList = E->getUpdater();
- else {
- DesignatedInitUpdateExpr *DIUE = new (SemaRef.Context)
- DesignatedInitUpdateExpr(SemaRef.Context, D->getBeginLoc(),
- ExistingInit, DIE->getEndLoc());
- StructuredList->updateInit(SemaRef.Context, StructuredIndex, DIUE);
- StructuredList = DIUE->getUpdater();
- }
- } else {
- // We don't need to track the structured representation of a
- // designated init update of an already-fully-initialized object in
- // verify-only mode. The only reason we would need the structure is
- // to determine where the uninitialized "holes" are, and in this
- // case, we know there aren't any and we can't introduce any.
- StructuredList = nullptr;
- }
- }
- }
- }
- if (D->isFieldDesignator()) {
- // C99 6.7.8p7:
- //
- // If a designator has the form
- //
- // . identifier
- //
- // then the current object (defined below) shall have
- // structure or union type and the identifier shall be the
- // name of a member of that type.
- const RecordType *RT = CurrentObjectType->getAs<RecordType>();
- if (!RT) {
- SourceLocation Loc = D->getDotLoc();
- if (Loc.isInvalid())
- Loc = D->getFieldLoc();
- if (!VerifyOnly)
- SemaRef.Diag(Loc, diag::err_field_designator_non_aggr)
- << SemaRef.getLangOpts().CPlusPlus << CurrentObjectType;
- ++Index;
- return true;
- }
- FieldDecl *KnownField = D->getField();
- if (!KnownField) {
- IdentifierInfo *FieldName = D->getFieldName();
- DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
- for (NamedDecl *ND : Lookup) {
- if (auto *FD = dyn_cast<FieldDecl>(ND)) {
- KnownField = FD;
- break;
- }
- if (auto *IFD = dyn_cast<IndirectFieldDecl>(ND)) {
- // In verify mode, don't modify the original.
- if (VerifyOnly)
- DIE = CloneDesignatedInitExpr(SemaRef, DIE);
- ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IFD);
- D = DIE->getDesignator(DesigIdx);
- KnownField = cast<FieldDecl>(*IFD->chain_begin());
- break;
- }
- }
- if (!KnownField) {
- if (VerifyOnly) {
- ++Index;
- return true; // No typo correction when just trying this out.
- }
- // Name lookup found something, but it wasn't a field.
- if (!Lookup.empty()) {
- SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
- << FieldName;
- SemaRef.Diag(Lookup.front()->getLocation(),
- diag::note_field_designator_found);
- ++Index;
- return true;
- }
- // Name lookup didn't find anything.
- // Determine whether this was a typo for another field name.
- FieldInitializerValidatorCCC CCC(RT->getDecl());
- if (TypoCorrection Corrected = SemaRef.CorrectTypo(
- DeclarationNameInfo(FieldName, D->getFieldLoc()),
- Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, CCC,
- Sema::CTK_ErrorRecovery, RT->getDecl())) {
- SemaRef.diagnoseTypo(
- Corrected,
- SemaRef.PDiag(diag::err_field_designator_unknown_suggest)
- << FieldName << CurrentObjectType);
- KnownField = Corrected.getCorrectionDeclAs<FieldDecl>();
- hadError = true;
- } else {
- // Typo correction didn't find anything.
- SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
- << FieldName << CurrentObjectType;
- ++Index;
- return true;
- }
- }
- }
- unsigned NumBases = 0;
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- NumBases = CXXRD->getNumBases();
- unsigned FieldIndex = NumBases;
- for (auto *FI : RT->getDecl()->fields()) {
- if (FI->isUnnamedBitfield())
- continue;
- if (declaresSameEntity(KnownField, FI)) {
- KnownField = FI;
- break;
- }
- ++FieldIndex;
- }
- RecordDecl::field_iterator Field =
- RecordDecl::field_iterator(DeclContext::decl_iterator(KnownField));
- // All of the fields of a union are located at the same place in
- // the initializer list.
- if (RT->getDecl()->isUnion()) {
- FieldIndex = 0;
- if (StructuredList) {
- FieldDecl *CurrentField = StructuredList->getInitializedFieldInUnion();
- if (CurrentField && !declaresSameEntity(CurrentField, *Field)) {
- assert(StructuredList->getNumInits() == 1
- && "A union should never have more than one initializer!");
- Expr *ExistingInit = StructuredList->getInit(0);
- if (ExistingInit) {
- // We're about to throw away an initializer, emit warning.
- diagnoseInitOverride(
- ExistingInit, SourceRange(D->getBeginLoc(), DIE->getEndLoc()));
- }
- // remove existing initializer
- StructuredList->resizeInits(SemaRef.Context, 0);
- StructuredList->setInitializedFieldInUnion(nullptr);
- }
- StructuredList->setInitializedFieldInUnion(*Field);
- }
- }
- // Make sure we can use this declaration.
- bool InvalidUse;
- if (VerifyOnly)
- InvalidUse = !SemaRef.CanUseDecl(*Field, TreatUnavailableAsInvalid);
- else
- InvalidUse = SemaRef.DiagnoseUseOfDecl(*Field, D->getFieldLoc());
- if (InvalidUse) {
- ++Index;
- return true;
- }
- // C++20 [dcl.init.list]p3:
- // The ordered identifiers in the designators of the designated-
- // initializer-list shall form a subsequence of the ordered identifiers
- // in the direct non-static data members of T.
- //
- // Note that this is not a condition on forming the aggregate
- // initialization, only on actually performing initialization,
- // so it is not checked in VerifyOnly mode.
- //
- // FIXME: This is the only reordering diagnostic we produce, and it only
- // catches cases where we have a top-level field designator that jumps
- // backwards. This is the only such case that is reachable in an
- // otherwise-valid C++20 program, so is the only case that's required for
- // conformance, but for consistency, we should diagnose all the other
- // cases where a designator takes us backwards too.
- if (IsFirstDesignator && !VerifyOnly && SemaRef.getLangOpts().CPlusPlus &&
- NextField &&
- (*NextField == RT->getDecl()->field_end() ||
- (*NextField)->getFieldIndex() > Field->getFieldIndex() + 1)) {
- // Find the field that we just initialized.
- FieldDecl *PrevField = nullptr;
- for (auto FI = RT->getDecl()->field_begin();
- FI != RT->getDecl()->field_end(); ++FI) {
- if (FI->isUnnamedBitfield())
- continue;
- if (*NextField != RT->getDecl()->field_end() &&
- declaresSameEntity(*FI, **NextField))
- break;
- PrevField = *FI;
- }
- if (PrevField &&
- PrevField->getFieldIndex() > KnownField->getFieldIndex()) {
- SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
- << KnownField << PrevField << DIE->getSourceRange();
- unsigned OldIndex = NumBases + PrevField->getFieldIndex();
- if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
- if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
- SemaRef.Diag(PrevInit->getBeginLoc(),
- diag::note_previous_field_init)
- << PrevField << PrevInit->getSourceRange();
- }
- }
- }
- }
- // Update the designator with the field declaration.
- if (!VerifyOnly)
- D->setField(*Field);
- // Make sure that our non-designated initializer list has space
- // for a subobject corresponding to this field.
- if (StructuredList && FieldIndex >= StructuredList->getNumInits())
- StructuredList->resizeInits(SemaRef.Context, FieldIndex + 1);
- // This designator names a flexible array member.
- if (Field->getType()->isIncompleteArrayType()) {
- bool Invalid = false;
- if ((DesigIdx + 1) != DIE->size()) {
- // We can't designate an object within the flexible array
- // member (because GCC doesn't allow it).
- if (!VerifyOnly) {
- DesignatedInitExpr::Designator *NextD
- = DIE->getDesignator(DesigIdx + 1);
- SemaRef.Diag(NextD->getBeginLoc(),
- diag::err_designator_into_flexible_array_member)
- << SourceRange(NextD->getBeginLoc(), DIE->getEndLoc());
- SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
- << *Field;
- }
- Invalid = true;
- }
- if (!hadError && !isa<InitListExpr>(DIE->getInit()) &&
- !isa<StringLiteral>(DIE->getInit())) {
- // The initializer is not an initializer list.
- if (!VerifyOnly) {
- SemaRef.Diag(DIE->getInit()->getBeginLoc(),
- diag::err_flexible_array_init_needs_braces)
- << DIE->getInit()->getSourceRange();
- SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
- << *Field;
- }
- Invalid = true;
- }
- // Check GNU flexible array initializer.
- if (!Invalid && CheckFlexibleArrayInit(Entity, DIE->getInit(), *Field,
- TopLevelObject))
- Invalid = true;
- if (Invalid) {
- ++Index;
- return true;
- }
- // Initialize the array.
- bool prevHadError = hadError;
- unsigned newStructuredIndex = FieldIndex;
- unsigned OldIndex = Index;
- IList->setInit(Index, DIE->getInit());
- InitializedEntity MemberEntity =
- InitializedEntity::InitializeMember(*Field, &Entity);
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
- StructuredList, newStructuredIndex);
- IList->setInit(OldIndex, DIE);
- if (hadError && !prevHadError) {
- ++Field;
- ++FieldIndex;
- if (NextField)
- *NextField = Field;
- StructuredIndex = FieldIndex;
- return true;
- }
- } else {
- // Recurse to check later designated subobjects.
- QualType FieldType = Field->getType();
- unsigned newStructuredIndex = FieldIndex;
- InitializedEntity MemberEntity =
- InitializedEntity::InitializeMember(*Field, &Entity);
- if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1,
- FieldType, nullptr, nullptr, Index,
- StructuredList, newStructuredIndex,
- FinishSubobjectInit, false))
- return true;
- }
- // Find the position of the next field to be initialized in this
- // subobject.
- ++Field;
- ++FieldIndex;
- // If this the first designator, our caller will continue checking
- // the rest of this struct/class/union subobject.
- if (IsFirstDesignator) {
- if (NextField)
- *NextField = Field;
- StructuredIndex = FieldIndex;
- return false;
- }
- if (!FinishSubobjectInit)
- return false;
- // We've already initialized something in the union; we're done.
- if (RT->getDecl()->isUnion())
- return hadError;
- // Check the remaining fields within this class/struct/union subobject.
- bool prevHadError = hadError;
- auto NoBases =
- CXXRecordDecl::base_class_range(CXXRecordDecl::base_class_iterator(),
- CXXRecordDecl::base_class_iterator());
- CheckStructUnionTypes(Entity, IList, CurrentObjectType, NoBases, Field,
- false, Index, StructuredList, FieldIndex);
- return hadError && !prevHadError;
- }
- // C99 6.7.8p6:
- //
- // If a designator has the form
- //
- // [ constant-expression ]
- //
- // then the current object (defined below) shall have array
- // type and the expression shall be an integer constant
- // expression. If the array is of unknown size, any
- // nonnegative value is valid.
- //
- // Additionally, cope with the GNU extension that permits
- // designators of the form
- //
- // [ constant-expression ... constant-expression ]
- const ArrayType *AT = SemaRef.Context.getAsArrayType(CurrentObjectType);
- if (!AT) {
- if (!VerifyOnly)
- SemaRef.Diag(D->getLBracketLoc(), diag::err_array_designator_non_array)
- << CurrentObjectType;
- ++Index;
- return true;
- }
- Expr *IndexExpr = nullptr;
- llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
- if (D->isArrayDesignator()) {
- IndexExpr = DIE->getArrayIndex(*D);
- DesignatedStartIndex = IndexExpr->EvaluateKnownConstInt(SemaRef.Context);
- DesignatedEndIndex = DesignatedStartIndex;
- } else {
- assert(D->isArrayRangeDesignator() && "Need array-range designator");
- DesignatedStartIndex =
- DIE->getArrayRangeStart(*D)->EvaluateKnownConstInt(SemaRef.Context);
- DesignatedEndIndex =
- DIE->getArrayRangeEnd(*D)->EvaluateKnownConstInt(SemaRef.Context);
- IndexExpr = DIE->getArrayRangeEnd(*D);
- // Codegen can't handle evaluating array range designators that have side
- // effects, because we replicate the AST value for each initialized element.
- // As such, set the sawArrayRangeDesignator() bit if we initialize multiple
- // elements with something that has a side effect, so codegen can emit an
- // "error unsupported" error instead of miscompiling the app.
- if (DesignatedStartIndex.getZExtValue()!=DesignatedEndIndex.getZExtValue()&&
- DIE->getInit()->HasSideEffects(SemaRef.Context) && !VerifyOnly)
- FullyStructuredList->sawArrayRangeDesignator();
- }
- if (isa<ConstantArrayType>(AT)) {
- llvm::APSInt MaxElements(cast<ConstantArrayType>(AT)->getSize(), false);
- DesignatedStartIndex
- = DesignatedStartIndex.extOrTrunc(MaxElements.getBitWidth());
- DesignatedStartIndex.setIsUnsigned(MaxElements.isUnsigned());
- DesignatedEndIndex
- = DesignatedEndIndex.extOrTrunc(MaxElements.getBitWidth());
- DesignatedEndIndex.setIsUnsigned(MaxElements.isUnsigned());
- if (DesignatedEndIndex >= MaxElements) {
- if (!VerifyOnly)
- SemaRef.Diag(IndexExpr->getBeginLoc(),
- diag::err_array_designator_too_large)
- << toString(DesignatedEndIndex, 10) << toString(MaxElements, 10)
- << IndexExpr->getSourceRange();
- ++Index;
- return true;
- }
- } else {
- unsigned DesignatedIndexBitWidth =
- ConstantArrayType::getMaxSizeBits(SemaRef.Context);
- DesignatedStartIndex =
- DesignatedStartIndex.extOrTrunc(DesignatedIndexBitWidth);
- DesignatedEndIndex =
- DesignatedEndIndex.extOrTrunc(DesignatedIndexBitWidth);
- DesignatedStartIndex.setIsUnsigned(true);
- DesignatedEndIndex.setIsUnsigned(true);
- }
- bool IsStringLiteralInitUpdate =
- StructuredList && StructuredList->isStringLiteralInit();
- if (IsStringLiteralInitUpdate && VerifyOnly) {
- // We're just verifying an update to a string literal init. We don't need
- // to split the string up into individual characters to do that.
- StructuredList = nullptr;
- } else if (IsStringLiteralInitUpdate) {
- // We're modifying a string literal init; we have to decompose the string
- // so we can modify the individual characters.
- ASTContext &Context = SemaRef.Context;
- Expr *SubExpr = StructuredList->getInit(0)->IgnoreParenImpCasts();
- // Compute the character type
- QualType CharTy = AT->getElementType();
- // Compute the type of the integer literals.
- QualType PromotedCharTy = CharTy;
- if (Context.isPromotableIntegerType(CharTy))
- PromotedCharTy = Context.getPromotedIntegerType(CharTy);
- unsigned PromotedCharTyWidth = Context.getTypeSize(PromotedCharTy);
- if (StringLiteral *SL = dyn_cast<StringLiteral>(SubExpr)) {
- // Get the length of the string.
- uint64_t StrLen = SL->getLength();
- if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
- StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
- StructuredList->resizeInits(Context, StrLen);
- // Build a literal for each character in the string, and put them into
- // the init list.
- for (unsigned i = 0, e = StrLen; i != e; ++i) {
- llvm::APInt CodeUnit(PromotedCharTyWidth, SL->getCodeUnit(i));
- Expr *Init = new (Context) IntegerLiteral(
- Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
- if (CharTy != PromotedCharTy)
- Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
- Init, nullptr, VK_PRValue,
- FPOptionsOverride());
- StructuredList->updateInit(Context, i, Init);
- }
- } else {
- ObjCEncodeExpr *E = cast<ObjCEncodeExpr>(SubExpr);
- std::string Str;
- Context.getObjCEncodingForType(E->getEncodedType(), Str);
- // Get the length of the string.
- uint64_t StrLen = Str.size();
- if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
- StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
- StructuredList->resizeInits(Context, StrLen);
- // Build a literal for each character in the string, and put them into
- // the init list.
- for (unsigned i = 0, e = StrLen; i != e; ++i) {
- llvm::APInt CodeUnit(PromotedCharTyWidth, Str[i]);
- Expr *Init = new (Context) IntegerLiteral(
- Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
- if (CharTy != PromotedCharTy)
- Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
- Init, nullptr, VK_PRValue,
- FPOptionsOverride());
- StructuredList->updateInit(Context, i, Init);
- }
- }
- }
- // Make sure that our non-designated initializer list has space
- // for a subobject corresponding to this array element.
- if (StructuredList &&
- DesignatedEndIndex.getZExtValue() >= StructuredList->getNumInits())
- StructuredList->resizeInits(SemaRef.Context,
- DesignatedEndIndex.getZExtValue() + 1);
- // Repeatedly perform subobject initializations in the range
- // [DesignatedStartIndex, DesignatedEndIndex].
- // Move to the next designator
- unsigned ElementIndex = DesignatedStartIndex.getZExtValue();
- unsigned OldIndex = Index;
- InitializedEntity ElementEntity =
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity);
- while (DesignatedStartIndex <= DesignatedEndIndex) {
- // Recurse to check later designated subobjects.
- QualType ElementType = AT->getElementType();
- Index = OldIndex;
- ElementEntity.setElementIndex(ElementIndex);
- if (CheckDesignatedInitializer(
- ElementEntity, IList, DIE, DesigIdx + 1, ElementType, nullptr,
- nullptr, Index, StructuredList, ElementIndex,
- FinishSubobjectInit && (DesignatedStartIndex == DesignatedEndIndex),
- false))
- return true;
- // Move to the next index in the array that we'll be initializing.
- ++DesignatedStartIndex;
- ElementIndex = DesignatedStartIndex.getZExtValue();
- }
- // If this the first designator, our caller will continue checking
- // the rest of this array subobject.
- if (IsFirstDesignator) {
- if (NextElementIndex)
- *NextElementIndex = DesignatedStartIndex;
- StructuredIndex = ElementIndex;
- return false;
- }
- if (!FinishSubobjectInit)
- return false;
- // Check the remaining elements within this array subobject.
- bool prevHadError = hadError;
- CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex,
- /*SubobjectIsDesignatorContext=*/false, Index,
- StructuredList, ElementIndex);
- return hadError && !prevHadError;
- }
- // Get the structured initializer list for a subobject of type
- // @p CurrentObjectType.
- InitListExpr *
- InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
- QualType CurrentObjectType,
- InitListExpr *StructuredList,
- unsigned StructuredIndex,
- SourceRange InitRange,
- bool IsFullyOverwritten) {
- if (!StructuredList)
- return nullptr;
- Expr *ExistingInit = nullptr;
- if (StructuredIndex < StructuredList->getNumInits())
- ExistingInit = StructuredList->getInit(StructuredIndex);
- if (InitListExpr *Result = dyn_cast_or_null<InitListExpr>(ExistingInit))
- // There might have already been initializers for subobjects of the current
- // object, but a subsequent initializer list will overwrite the entirety
- // of the current object. (See DR 253 and C99 6.7.8p21). e.g.,
- //
- // struct P { char x[6]; };
- // struct P l = { .x[2] = 'x', .x = { [0] = 'f' } };
- //
- // The first designated initializer is ignored, and l.x is just "f".
- if (!IsFullyOverwritten)
- return Result;
- if (ExistingInit) {
- // We are creating an initializer list that initializes the
- // subobjects of the current object, but there was already an
- // initialization that completely initialized the current
- // subobject:
- //
- // struct X { int a, b; };
- // struct X xs[] = { [0] = { 1, 2 }, [0].b = 3 };
- //
- // Here, xs[0].a == 1 and xs[0].b == 3, since the second,
- // designated initializer overwrites the [0].b initializer
- // from the prior initialization.
- //
- // When the existing initializer is an expression rather than an
- // initializer list, we cannot decompose and update it in this way.
- // For example:
- //
- // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };
- //
- // This case is handled by CheckDesignatedInitializer.
- diagnoseInitOverride(ExistingInit, InitRange);
- }
- unsigned ExpectedNumInits = 0;
- if (Index < IList->getNumInits()) {
- if (auto *Init = dyn_cast_or_null<InitListExpr>(IList->getInit(Index)))
- ExpectedNumInits = Init->getNumInits();
- else
- ExpectedNumInits = IList->getNumInits() - Index;
- }
- InitListExpr *Result =
- createInitListExpr(CurrentObjectType, InitRange, ExpectedNumInits);
- // Link this new initializer list into the structured initializer
- // lists.
- StructuredList->updateInit(SemaRef.Context, StructuredIndex, Result);
- return Result;
- }
- InitListExpr *
- InitListChecker::createInitListExpr(QualType CurrentObjectType,
- SourceRange InitRange,
- unsigned ExpectedNumInits) {
- InitListExpr *Result = new (SemaRef.Context) InitListExpr(
- SemaRef.Context, InitRange.getBegin(), std::nullopt, InitRange.getEnd());
- QualType ResultType = CurrentObjectType;
- if (!ResultType->isArrayType())
- ResultType = ResultType.getNonLValueExprType(SemaRef.Context);
- Result->setType(ResultType);
- // Pre-allocate storage for the structured initializer list.
- unsigned NumElements = 0;
- if (const ArrayType *AType
- = SemaRef.Context.getAsArrayType(CurrentObjectType)) {
- if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) {
- NumElements = CAType->getSize().getZExtValue();
- // Simple heuristic so that we don't allocate a very large
- // initializer with many empty entries at the end.
- if (NumElements > ExpectedNumInits)
- NumElements = 0;
- }
- } else if (const VectorType *VType = CurrentObjectType->getAs<VectorType>()) {
- NumElements = VType->getNumElements();
- } else if (CurrentObjectType->isRecordType()) {
- NumElements = numStructUnionElements(CurrentObjectType);
- }
- Result->reserveInits(SemaRef.Context, NumElements);
- return Result;
- }
- /// Update the initializer at index @p StructuredIndex within the
- /// structured initializer list to the value @p expr.
- void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
- unsigned &StructuredIndex,
- Expr *expr) {
- // No structured initializer list to update
- if (!StructuredList)
- return;
- if (Expr *PrevInit = StructuredList->updateInit(SemaRef.Context,
- StructuredIndex, expr)) {
- // This initializer overwrites a previous initializer.
- // No need to diagnose when `expr` is nullptr because a more relevant
- // diagnostic has already been issued and this diagnostic is potentially
- // noise.
- if (expr)
- diagnoseInitOverride(PrevInit, expr->getSourceRange());
- }
- ++StructuredIndex;
- }
- /// Determine whether we can perform aggregate initialization for the purposes
- /// of overload resolution.
- bool Sema::CanPerformAggregateInitializationForOverloadResolution(
- const InitializedEntity &Entity, InitListExpr *From) {
- QualType Type = Entity.getType();
- InitListChecker Check(*this, Entity, From, Type, /*VerifyOnly=*/true,
- /*TreatUnavailableAsInvalid=*/false,
- /*InOverloadResolution=*/true);
- return !Check.HadError();
- }
- /// Check that the given Index expression is a valid array designator
- /// value. This is essentially just a wrapper around
- /// VerifyIntegerConstantExpression that also checks for negative values
- /// and produces a reasonable diagnostic if there is a
- /// failure. Returns the index expression, possibly with an implicit cast
- /// added, on success. If everything went okay, Value will receive the
- /// value of the constant expression.
- static ExprResult
- CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
- SourceLocation Loc = Index->getBeginLoc();
- // Make sure this is an integer constant expression.
- ExprResult Result =
- S.VerifyIntegerConstantExpression(Index, &Value, Sema::AllowFold);
- if (Result.isInvalid())
- return Result;
- if (Value.isSigned() && Value.isNegative())
- return S.Diag(Loc, diag::err_array_designator_negative)
- << toString(Value, 10) << Index->getSourceRange();
- Value.setIsUnsigned(true);
- return Result;
- }
- ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
- SourceLocation EqualOrColonLoc,
- bool GNUSyntax,
- ExprResult Init) {
- typedef DesignatedInitExpr::Designator ASTDesignator;
- bool Invalid = false;
- SmallVector<ASTDesignator, 32> Designators;
- SmallVector<Expr *, 32> InitExpressions;
- // Build designators and check array designator expressions.
- for (unsigned Idx = 0; Idx < Desig.getNumDesignators(); ++Idx) {
- const Designator &D = Desig.getDesignator(Idx);
- switch (D.getKind()) {
- case Designator::FieldDesignator:
- Designators.push_back(ASTDesignator(D.getField(), D.getDotLoc(),
- D.getFieldLoc()));
- break;
- case Designator::ArrayDesignator: {
- Expr *Index = static_cast<Expr *>(D.getArrayIndex());
- llvm::APSInt IndexValue;
- if (!Index->isTypeDependent() && !Index->isValueDependent())
- Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).get();
- if (!Index)
- Invalid = true;
- else {
- Designators.push_back(ASTDesignator(InitExpressions.size(),
- D.getLBracketLoc(),
- D.getRBracketLoc()));
- InitExpressions.push_back(Index);
- }
- break;
- }
- case Designator::ArrayRangeDesignator: {
- Expr *StartIndex = static_cast<Expr *>(D.getArrayRangeStart());
- Expr *EndIndex = static_cast<Expr *>(D.getArrayRangeEnd());
- llvm::APSInt StartValue;
- llvm::APSInt EndValue;
- bool StartDependent = StartIndex->isTypeDependent() ||
- StartIndex->isValueDependent();
- bool EndDependent = EndIndex->isTypeDependent() ||
- EndIndex->isValueDependent();
- if (!StartDependent)
- StartIndex =
- CheckArrayDesignatorExpr(*this, StartIndex, StartValue).get();
- if (!EndDependent)
- EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).get();
- if (!StartIndex || !EndIndex)
- Invalid = true;
- else {
- // Make sure we're comparing values with the same bit width.
- if (StartDependent || EndDependent) {
- // Nothing to compute.
- } else if (StartValue.getBitWidth() > EndValue.getBitWidth())
- EndValue = EndValue.extend(StartValue.getBitWidth());
- else if (StartValue.getBitWidth() < EndValue.getBitWidth())
- StartValue = StartValue.extend(EndValue.getBitWidth());
- if (!StartDependent && !EndDependent && EndValue < StartValue) {
- Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range)
- << toString(StartValue, 10) << toString(EndValue, 10)
- << StartIndex->getSourceRange() << EndIndex->getSourceRange();
- Invalid = true;
- } else {
- Designators.push_back(ASTDesignator(InitExpressions.size(),
- D.getLBracketLoc(),
- D.getEllipsisLoc(),
- D.getRBracketLoc()));
- InitExpressions.push_back(StartIndex);
- InitExpressions.push_back(EndIndex);
- }
- }
- break;
- }
- }
- }
- if (Invalid || Init.isInvalid())
- return ExprError();
- // Clear out the expressions within the designation.
- Desig.ClearExprs(*this);
- return DesignatedInitExpr::Create(Context, Designators, InitExpressions,
- EqualOrColonLoc, GNUSyntax,
- Init.getAs<Expr>());
- }
- //===----------------------------------------------------------------------===//
- // Initialization entity
- //===----------------------------------------------------------------------===//
- InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index,
- const InitializedEntity &Parent)
- : Parent(&Parent), Index(Index)
- {
- if (const ArrayType *AT = Context.getAsArrayType(Parent.getType())) {
- Kind = EK_ArrayElement;
- Type = AT->getElementType();
- } else if (const VectorType *VT = Parent.getType()->getAs<VectorType>()) {
- Kind = EK_VectorElement;
- Type = VT->getElementType();
- } else {
- const ComplexType *CT = Parent.getType()->getAs<ComplexType>();
- assert(CT && "Unexpected type");
- Kind = EK_ComplexElement;
- Type = CT->getElementType();
- }
- }
- InitializedEntity
- InitializedEntity::InitializeBase(ASTContext &Context,
- const CXXBaseSpecifier *Base,
- bool IsInheritedVirtualBase,
- const InitializedEntity *Parent) {
- InitializedEntity Result;
- Result.Kind = EK_Base;
- Result.Parent = Parent;
- Result.Base = {Base, IsInheritedVirtualBase};
- Result.Type = Base->getType();
- return Result;
- }
- DeclarationName InitializedEntity::getName() const {
- switch (getKind()) {
- case EK_Parameter:
- case EK_Parameter_CF_Audited: {
- ParmVarDecl *D = Parameter.getPointer();
- return (D ? D->getDeclName() : DeclarationName());
- }
- case EK_Variable:
- case EK_Member:
- case EK_Binding:
- case EK_TemplateParameter:
- return Variable.VariableOrMember->getDeclName();
- case EK_LambdaCapture:
- return DeclarationName(Capture.VarID);
- case EK_Result:
- case EK_StmtExprResult:
- case EK_Exception:
- case EK_New:
- case EK_Temporary:
- case EK_Base:
- case EK_Delegating:
- case EK_ArrayElement:
- case EK_VectorElement:
- case EK_ComplexElement:
- case EK_BlockElement:
- case EK_LambdaToBlockConversionBlockElement:
- case EK_CompoundLiteralInit:
- case EK_RelatedResult:
- return DeclarationName();
- }
- llvm_unreachable("Invalid EntityKind!");
- }
- ValueDecl *InitializedEntity::getDecl() const {
- switch (getKind()) {
- case EK_Variable:
- case EK_Member:
- case EK_Binding:
- case EK_TemplateParameter:
- return Variable.VariableOrMember;
- case EK_Parameter:
- case EK_Parameter_CF_Audited:
- return Parameter.getPointer();
- case EK_Result:
- case EK_StmtExprResult:
- case EK_Exception:
- case EK_New:
- case EK_Temporary:
- case EK_Base:
- case EK_Delegating:
- case EK_ArrayElement:
- case EK_VectorElement:
- case EK_ComplexElement:
- case EK_BlockElement:
- case EK_LambdaToBlockConversionBlockElement:
- case EK_LambdaCapture:
- case EK_CompoundLiteralInit:
- case EK_RelatedResult:
- return nullptr;
- }
- llvm_unreachable("Invalid EntityKind!");
- }
- bool InitializedEntity::allowsNRVO() const {
- switch (getKind()) {
- case EK_Result:
- case EK_Exception:
- return LocAndNRVO.NRVO;
- case EK_StmtExprResult:
- case EK_Variable:
- case EK_Parameter:
- case EK_Parameter_CF_Audited:
- case EK_TemplateParameter:
- case EK_Member:
- case EK_Binding:
- case EK_New:
- case EK_Temporary:
- case EK_CompoundLiteralInit:
- case EK_Base:
- case EK_Delegating:
- case EK_ArrayElement:
- case EK_VectorElement:
- case EK_ComplexElement:
- case EK_BlockElement:
- case EK_LambdaToBlockConversionBlockElement:
- case EK_LambdaCapture:
- case EK_RelatedResult:
- break;
- }
- return false;
- }
- unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const {
- assert(getParent() != this);
- unsigned Depth = getParent() ? getParent()->dumpImpl(OS) : 0;
- for (unsigned I = 0; I != Depth; ++I)
- OS << "`-";
- switch (getKind()) {
- case EK_Variable: OS << "Variable"; break;
- case EK_Parameter: OS << "Parameter"; break;
- case EK_Parameter_CF_Audited: OS << "CF audited function Parameter";
- break;
- case EK_TemplateParameter: OS << "TemplateParameter"; break;
- case EK_Result: OS << "Result"; break;
- case EK_StmtExprResult: OS << "StmtExprResult"; break;
- case EK_Exception: OS << "Exception"; break;
- case EK_Member: OS << "Member"; break;
- case EK_Binding: OS << "Binding"; break;
- case EK_New: OS << "New"; break;
- case EK_Temporary: OS << "Temporary"; break;
- case EK_CompoundLiteralInit: OS << "CompoundLiteral";break;
- case EK_RelatedResult: OS << "RelatedResult"; break;
- case EK_Base: OS << "Base"; break;
- case EK_Delegating: OS << "Delegating"; break;
- case EK_ArrayElement: OS << "ArrayElement " << Index; break;
- case EK_VectorElement: OS << "VectorElement " << Index; break;
- case EK_ComplexElement: OS << "ComplexElement " << Index; break;
- case EK_BlockElement: OS << "Block"; break;
- case EK_LambdaToBlockConversionBlockElement:
- OS << "Block (lambda)";
- break;
- case EK_LambdaCapture:
- OS << "LambdaCapture ";
- OS << DeclarationName(Capture.VarID);
- break;
- }
- if (auto *D = getDecl()) {
- OS << " ";
- D->printQualifiedName(OS);
- }
- OS << " '" << getType() << "'\n";
- return Depth + 1;
- }
- LLVM_DUMP_METHOD void InitializedEntity::dump() const {
- dumpImpl(llvm::errs());
- }
- //===----------------------------------------------------------------------===//
- // Initialization sequence
- //===----------------------------------------------------------------------===//
- void InitializationSequence::Step::Destroy() {
- switch (Kind) {
- case SK_ResolveAddressOfOverloadedFunction:
- case SK_CastDerivedToBasePRValue:
- case SK_CastDerivedToBaseXValue:
- case SK_CastDerivedToBaseLValue:
- case SK_BindReference:
- case SK_BindReferenceToTemporary:
- case SK_FinalCopy:
- case SK_ExtraneousCopyToTemporary:
- case SK_UserConversion:
- case SK_QualificationConversionPRValue:
- case SK_QualificationConversionXValue:
- case SK_QualificationConversionLValue:
- case SK_FunctionReferenceConversion:
- case SK_AtomicConversion:
- case SK_ListInitialization:
- case SK_UnwrapInitList:
- case SK_RewrapInitList:
- case SK_ConstructorInitialization:
- case SK_ConstructorInitializationFromList:
- case SK_ZeroInitialization:
- case SK_CAssignment:
- case SK_StringInit:
- case SK_ObjCObjectConversion:
- case SK_ArrayLoopIndex:
- case SK_ArrayLoopInit:
- case SK_ArrayInit:
- case SK_GNUArrayInit:
- case SK_ParenthesizedArrayInit:
- case SK_PassByIndirectCopyRestore:
- case SK_PassByIndirectRestore:
- case SK_ProduceObjCObject:
- case SK_StdInitializerList:
- case SK_StdInitializerListConstructorCall:
- case SK_OCLSamplerInit:
- case SK_OCLZeroOpaqueType:
- case SK_ParenthesizedListInit:
- break;
- case SK_ConversionSequence:
- case SK_ConversionSequenceNoNarrowing:
- delete ICS;
- }
- }
- bool InitializationSequence::isDirectReferenceBinding() const {
- // There can be some lvalue adjustments after the SK_BindReference step.
- for (const Step &S : llvm::reverse(Steps)) {
- if (S.Kind == SK_BindReference)
- return true;
- if (S.Kind == SK_BindReferenceToTemporary)
- return false;
- }
- return false;
- }
- bool InitializationSequence::isAmbiguous() const {
- if (!Failed())
- return false;
- switch (getFailureKind()) {
- case FK_TooManyInitsForReference:
- case FK_ParenthesizedListInitForReference:
- case FK_ArrayNeedsInitList:
- case FK_ArrayNeedsInitListOrStringLiteral:
- case FK_ArrayNeedsInitListOrWideStringLiteral:
- case FK_NarrowStringIntoWideCharArray:
- case FK_WideStringIntoCharArray:
- case FK_IncompatWideStringIntoWideChar:
- case FK_PlainStringIntoUTF8Char:
- case FK_UTF8StringIntoPlainChar:
- case FK_AddressOfOverloadFailed: // FIXME: Could do better
- case FK_NonConstLValueReferenceBindingToTemporary:
- case FK_NonConstLValueReferenceBindingToBitfield:
- case FK_NonConstLValueReferenceBindingToVectorElement:
- case FK_NonConstLValueReferenceBindingToMatrixElement:
- case FK_NonConstLValueReferenceBindingToUnrelated:
- case FK_RValueReferenceBindingToLValue:
- case FK_ReferenceAddrspaceMismatchTemporary:
- case FK_ReferenceInitDropsQualifiers:
- case FK_ReferenceInitFailed:
- case FK_ConversionFailed:
- case FK_ConversionFromPropertyFailed:
- case FK_TooManyInitsForScalar:
- case FK_ParenthesizedListInitForScalar:
- case FK_ReferenceBindingToInitList:
- case FK_InitListBadDestinationType:
- case FK_DefaultInitOfConst:
- case FK_Incomplete:
- case FK_ArrayTypeMismatch:
- case FK_NonConstantArrayInit:
- case FK_ListInitializationFailed:
- case FK_VariableLengthArrayHasInitializer:
- case FK_PlaceholderType:
- case FK_ExplicitConstructor:
- case FK_AddressOfUnaddressableFunction:
- case FK_ParenthesizedListInitFailed:
- return false;
- case FK_ReferenceInitOverloadFailed:
- case FK_UserConversionOverloadFailed:
- case FK_ConstructorOverloadFailed:
- case FK_ListConstructorOverloadFailed:
- return FailedOverloadResult == OR_Ambiguous;
- }
- llvm_unreachable("Invalid EntityKind!");
- }
- bool InitializationSequence::isConstructorInitialization() const {
- return !Steps.empty() && Steps.back().Kind == SK_ConstructorInitialization;
- }
- void
- InitializationSequence
- ::AddAddressOverloadResolutionStep(FunctionDecl *Function,
- DeclAccessPair Found,
- bool HadMultipleCandidates) {
- Step S;
- S.Kind = SK_ResolveAddressOfOverloadedFunction;
- S.Type = Function->getType();
- S.Function.HadMultipleCandidates = HadMultipleCandidates;
- S.Function.Function = Function;
- S.Function.FoundDecl = Found;
- Steps.push_back(S);
- }
- void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType,
- ExprValueKind VK) {
- Step S;
- switch (VK) {
- case VK_PRValue:
- S.Kind = SK_CastDerivedToBasePRValue;
- break;
- case VK_XValue: S.Kind = SK_CastDerivedToBaseXValue; break;
- case VK_LValue: S.Kind = SK_CastDerivedToBaseLValue; break;
- }
- S.Type = BaseType;
- Steps.push_back(S);
- }
- void InitializationSequence::AddReferenceBindingStep(QualType T,
- bool BindingTemporary) {
- Step S;
- S.Kind = BindingTemporary? SK_BindReferenceToTemporary : SK_BindReference;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddFinalCopy(QualType T) {
- Step S;
- S.Kind = SK_FinalCopy;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddExtraneousCopyToTemporary(QualType T) {
- Step S;
- S.Kind = SK_ExtraneousCopyToTemporary;
- S.Type = T;
- Steps.push_back(S);
- }
- void
- InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
- QualType T,
- bool HadMultipleCandidates) {
- Step S;
- S.Kind = SK_UserConversion;
- S.Type = T;
- S.Function.HadMultipleCandidates = HadMultipleCandidates;
- S.Function.Function = Function;
- S.Function.FoundDecl = FoundDecl;
- Steps.push_back(S);
- }
- void InitializationSequence::AddQualificationConversionStep(QualType Ty,
- ExprValueKind VK) {
- Step S;
- S.Kind = SK_QualificationConversionPRValue; // work around a gcc warning
- switch (VK) {
- case VK_PRValue:
- S.Kind = SK_QualificationConversionPRValue;
- break;
- case VK_XValue:
- S.Kind = SK_QualificationConversionXValue;
- break;
- case VK_LValue:
- S.Kind = SK_QualificationConversionLValue;
- break;
- }
- S.Type = Ty;
- Steps.push_back(S);
- }
- void InitializationSequence::AddFunctionReferenceConversionStep(QualType Ty) {
- Step S;
- S.Kind = SK_FunctionReferenceConversion;
- S.Type = Ty;
- Steps.push_back(S);
- }
- void InitializationSequence::AddAtomicConversionStep(QualType Ty) {
- Step S;
- S.Kind = SK_AtomicConversion;
- S.Type = Ty;
- Steps.push_back(S);
- }
- void InitializationSequence::AddConversionSequenceStep(
- const ImplicitConversionSequence &ICS, QualType T,
- bool TopLevelOfInitList) {
- Step S;
- S.Kind = TopLevelOfInitList ? SK_ConversionSequenceNoNarrowing
- : SK_ConversionSequence;
- S.Type = T;
- S.ICS = new ImplicitConversionSequence(ICS);
- Steps.push_back(S);
- }
- void InitializationSequence::AddListInitializationStep(QualType T) {
- Step S;
- S.Kind = SK_ListInitialization;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddConstructorInitializationStep(
- DeclAccessPair FoundDecl, CXXConstructorDecl *Constructor, QualType T,
- bool HadMultipleCandidates, bool FromInitList, bool AsInitList) {
- Step S;
- S.Kind = FromInitList ? AsInitList ? SK_StdInitializerListConstructorCall
- : SK_ConstructorInitializationFromList
- : SK_ConstructorInitialization;
- S.Type = T;
- S.Function.HadMultipleCandidates = HadMultipleCandidates;
- S.Function.Function = Constructor;
- S.Function.FoundDecl = FoundDecl;
- Steps.push_back(S);
- }
- void InitializationSequence::AddZeroInitializationStep(QualType T) {
- Step S;
- S.Kind = SK_ZeroInitialization;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddCAssignmentStep(QualType T) {
- Step S;
- S.Kind = SK_CAssignment;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddStringInitStep(QualType T) {
- Step S;
- S.Kind = SK_StringInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddObjCObjectConversionStep(QualType T) {
- Step S;
- S.Kind = SK_ObjCObjectConversion;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddArrayInitStep(QualType T, bool IsGNUExtension) {
- Step S;
- S.Kind = IsGNUExtension ? SK_GNUArrayInit : SK_ArrayInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddArrayInitLoopStep(QualType T, QualType EltT) {
- Step S;
- S.Kind = SK_ArrayLoopIndex;
- S.Type = EltT;
- Steps.insert(Steps.begin(), S);
- S.Kind = SK_ArrayLoopInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddParenthesizedArrayInitStep(QualType T) {
- Step S;
- S.Kind = SK_ParenthesizedArrayInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddPassByIndirectCopyRestoreStep(QualType type,
- bool shouldCopy) {
- Step s;
- s.Kind = (shouldCopy ? SK_PassByIndirectCopyRestore
- : SK_PassByIndirectRestore);
- s.Type = type;
- Steps.push_back(s);
- }
- void InitializationSequence::AddProduceObjCObjectStep(QualType T) {
- Step S;
- S.Kind = SK_ProduceObjCObject;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddStdInitializerListConstructionStep(QualType T) {
- Step S;
- S.Kind = SK_StdInitializerList;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddOCLSamplerInitStep(QualType T) {
- Step S;
- S.Kind = SK_OCLSamplerInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddOCLZeroOpaqueTypeStep(QualType T) {
- Step S;
- S.Kind = SK_OCLZeroOpaqueType;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::AddParenthesizedListInitStep(QualType T) {
- Step S;
- S.Kind = SK_ParenthesizedListInit;
- S.Type = T;
- Steps.push_back(S);
- }
- void InitializationSequence::RewrapReferenceInitList(QualType T,
- InitListExpr *Syntactic) {
- assert(Syntactic->getNumInits() == 1 &&
- "Can only rewrap trivial init lists.");
- Step S;
- S.Kind = SK_UnwrapInitList;
- S.Type = Syntactic->getInit(0)->getType();
- Steps.insert(Steps.begin(), S);
- S.Kind = SK_RewrapInitList;
- S.Type = T;
- S.WrappingSyntacticList = Syntactic;
- Steps.push_back(S);
- }
- void InitializationSequence::SetOverloadFailure(FailureKind Failure,
- OverloadingResult Result) {
- setSequenceKind(FailedSequence);
- this->Failure = Failure;
- this->FailedOverloadResult = Result;
- }
- //===----------------------------------------------------------------------===//
- // Attempt initialization
- //===----------------------------------------------------------------------===//
- /// Tries to add a zero initializer. Returns true if that worked.
- static bool
- maybeRecoverWithZeroInitialization(Sema &S, InitializationSequence &Sequence,
- const InitializedEntity &Entity) {
- if (Entity.getKind() != InitializedEntity::EK_Variable)
- return false;
- VarDecl *VD = cast<VarDecl>(Entity.getDecl());
- if (VD->getInit() || VD->getEndLoc().isMacroID())
- return false;
- QualType VariableTy = VD->getType().getCanonicalType();
- SourceLocation Loc = S.getLocForEndOfToken(VD->getEndLoc());
- std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);
- if (!Init.empty()) {
- Sequence.AddZeroInitializationStep(Entity.getType());
- Sequence.SetZeroInitializationFixit(Init, Loc);
- return true;
- }
- return false;
- }
- static void MaybeProduceObjCObject(Sema &S,
- InitializationSequence &Sequence,
- const InitializedEntity &Entity) {
- if (!S.getLangOpts().ObjCAutoRefCount) return;
- /// When initializing a parameter, produce the value if it's marked
- /// __attribute__((ns_consumed)).
- if (Entity.isParameterKind()) {
- if (!Entity.isParameterConsumed())
- return;
- assert(Entity.getType()->isObjCRetainableType() &&
- "consuming an object of unretainable type?");
- Sequence.AddProduceObjCObjectStep(Entity.getType());
- /// When initializing a return value, if the return type is a
- /// retainable type, then returns need to immediately retain the
- /// object. If an autorelease is required, it will be done at the
- /// last instant.
- } else if (Entity.getKind() == InitializedEntity::EK_Result ||
- Entity.getKind() == InitializedEntity::EK_StmtExprResult) {
- if (!Entity.getType()->isObjCRetainableType())
- return;
- Sequence.AddProduceObjCObjectStep(Entity.getType());
- }
- }
- static void TryListInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitListExpr *InitList,
- InitializationSequence &Sequence,
- bool TreatUnavailableAsInvalid);
- /// When initializing from init list via constructor, handle
- /// initialization of an object of type std::initializer_list<T>.
- ///
- /// \return true if we have handled initialization of an object of type
- /// std::initializer_list<T>, false otherwise.
- static bool TryInitializerListConstruction(Sema &S,
- InitListExpr *List,
- QualType DestType,
- InitializationSequence &Sequence,
- bool TreatUnavailableAsInvalid) {
- QualType E;
- if (!S.isStdInitializerList(DestType, &E))
- return false;
- if (!S.isCompleteType(List->getExprLoc(), E)) {
- Sequence.setIncompleteTypeFailure(E);
- return true;
- }
- // Try initializing a temporary array from the init list.
- QualType ArrayType = S.Context.getConstantArrayType(
- E.withConst(),
- llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
- List->getNumInits()),
- nullptr, clang::ArrayType::Normal, 0);
- InitializedEntity HiddenArray =
- InitializedEntity::InitializeTemporary(ArrayType);
- InitializationKind Kind = InitializationKind::CreateDirectList(
- List->getExprLoc(), List->getBeginLoc(), List->getEndLoc());
- TryListInitialization(S, HiddenArray, Kind, List, Sequence,
- TreatUnavailableAsInvalid);
- if (Sequence)
- Sequence.AddStdInitializerListConstructionStep(DestType);
- return true;
- }
- /// Determine if the constructor has the signature of a copy or move
- /// constructor for the type T of the class in which it was found. That is,
- /// determine if its first parameter is of type T or reference to (possibly
- /// cv-qualified) T.
- static bool hasCopyOrMoveCtorParam(ASTContext &Ctx,
- const ConstructorInfo &Info) {
- if (Info.Constructor->getNumParams() == 0)
- return false;
- QualType ParmT =
- Info.Constructor->getParamDecl(0)->getType().getNonReferenceType();
- QualType ClassT =
- Ctx.getRecordType(cast<CXXRecordDecl>(Info.FoundDecl->getDeclContext()));
- return Ctx.hasSameUnqualifiedType(ParmT, ClassT);
- }
- static OverloadingResult
- ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
- MultiExprArg Args,
- OverloadCandidateSet &CandidateSet,
- QualType DestType,
- DeclContext::lookup_result Ctors,
- OverloadCandidateSet::iterator &Best,
- bool CopyInitializing, bool AllowExplicit,
- bool OnlyListConstructors, bool IsListInit,
- bool SecondStepOfCopyInit = false) {
- CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor);
- CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
- for (NamedDecl *D : Ctors) {
- auto Info = getConstructorInfo(D);
- if (!Info.Constructor || Info.Constructor->isInvalidDecl())
- continue;
- if (OnlyListConstructors && !S.isInitListConstructor(Info.Constructor))
- continue;
- // C++11 [over.best.ics]p4:
- // ... and the constructor or user-defined conversion function is a
- // candidate by
- // - 13.3.1.3, when the argument is the temporary in the second step
- // of a class copy-initialization, or
- // - 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), [not handled here]
- // - the second phase of 13.3.1.7 when the initializer list has exactly
- // one element that is itself an initializer list, and the target is
- // the first parameter of a constructor of class X, and the conversion
- // is to X or reference to (possibly cv-qualified X),
- // user-defined conversion sequences are not considered.
- bool SuppressUserConversions =
- SecondStepOfCopyInit ||
- (IsListInit && Args.size() == 1 && isa<InitListExpr>(Args[0]) &&
- hasCopyOrMoveCtorParam(S.Context, Info));
- if (Info.ConstructorTmpl)
- S.AddTemplateOverloadCandidate(
- Info.ConstructorTmpl, Info.FoundDecl,
- /*ExplicitArgs*/ nullptr, Args, CandidateSet, SuppressUserConversions,
- /*PartialOverloading=*/false, AllowExplicit);
- else {
- // C++ [over.match.copy]p1:
- // - When initializing a temporary to be bound to the first parameter
- // of a constructor [for type T] that takes a reference to possibly
- // cv-qualified T as its first argument, called with a single
- // argument in the context of direct-initialization, explicit
- // conversion functions are also considered.
- // FIXME: What if a constructor template instantiates to such a signature?
- bool AllowExplicitConv = AllowExplicit && !CopyInitializing &&
- Args.size() == 1 &&
- hasCopyOrMoveCtorParam(S.Context, Info);
- S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args,
- CandidateSet, SuppressUserConversions,
- /*PartialOverloading=*/false, AllowExplicit,
- AllowExplicitConv);
- }
- }
- // FIXME: Work around a bug in C++17 guaranteed copy elision.
- //
- // When initializing an object of class type T by constructor
- // ([over.match.ctor]) or by list-initialization ([over.match.list])
- // from a single expression of class type U, conversion functions of
- // U that convert to the non-reference type cv T are candidates.
- // Explicit conversion functions are only candidates during
- // direct-initialization.
- //
- // Note: SecondStepOfCopyInit is only ever true in this case when
- // evaluating whether to produce a C++98 compatibility warning.
- if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 &&
- !SecondStepOfCopyInit) {
- Expr *Initializer = Args[0];
- auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl();
- if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) {
- const auto &Conversions = SourceRD->getVisibleConversionFunctions();
- for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
- NamedDecl *D = *I;
- CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
- D = D->getUnderlyingDecl();
- FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
- CXXConversionDecl *Conv;
- if (ConvTemplate)
- Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
- else
- Conv = cast<CXXConversionDecl>(D);
- if (ConvTemplate)
- S.AddTemplateConversionCandidate(
- ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
- CandidateSet, AllowExplicit, AllowExplicit,
- /*AllowResultConversion*/ false);
- else
- S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer,
- DestType, CandidateSet, AllowExplicit,
- AllowExplicit,
- /*AllowResultConversion*/ false);
- }
- }
- }
- // Perform overload resolution and return the result.
- return CandidateSet.BestViableFunction(S, DeclLoc, Best);
- }
- /// Attempt initialization by constructor (C++ [dcl.init]), which
- /// enumerates the constructors of the initialized entity and performs overload
- /// resolution to select the best.
- /// \param DestType The destination class type.
- /// \param DestArrayType The destination type, which is either DestType or
- /// a (possibly multidimensional) array of DestType.
- /// \param IsListInit Is this list-initialization?
- /// \param IsInitListCopy Is this non-list-initialization resulting from a
- /// list-initialization from {x} where x is the same
- /// type as the entity?
- static void TryConstructorInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args, QualType DestType,
- QualType DestArrayType,
- InitializationSequence &Sequence,
- bool IsListInit = false,
- bool IsInitListCopy = false) {
- assert(((!IsListInit && !IsInitListCopy) ||
- (Args.size() == 1 && isa<InitListExpr>(Args[0]))) &&
- "IsListInit/IsInitListCopy must come with a single initializer list "
- "argument.");
- InitListExpr *ILE =
- (IsListInit || IsInitListCopy) ? cast<InitListExpr>(Args[0]) : nullptr;
- MultiExprArg UnwrappedArgs =
- ILE ? MultiExprArg(ILE->getInits(), ILE->getNumInits()) : Args;
- // The type we're constructing needs to be complete.
- if (!S.isCompleteType(Kind.getLocation(), DestType)) {
- Sequence.setIncompleteTypeFailure(DestType);
- return;
- }
- // C++17 [dcl.init]p17:
- // - If the initializer expression is a prvalue and the cv-unqualified
- // version of the source type is the same class as the class of the
- // destination, the initializer expression is used to initialize the
- // destination object.
- // Per DR (no number yet), this does not apply when initializing a base
- // class or delegating to another constructor from a mem-initializer.
- // ObjC++: Lambda captured by the block in the lambda to block conversion
- // should avoid copy elision.
- if (S.getLangOpts().CPlusPlus17 &&
- Entity.getKind() != InitializedEntity::EK_Base &&
- Entity.getKind() != InitializedEntity::EK_Delegating &&
- Entity.getKind() !=
- InitializedEntity::EK_LambdaToBlockConversionBlockElement &&
- UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
- S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
- // Convert qualifications if necessary.
- Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
- if (ILE)
- Sequence.RewrapReferenceInitList(DestType, ILE);
- return;
- }
- const RecordType *DestRecordType = DestType->getAs<RecordType>();
- assert(DestRecordType && "Constructor initialization requires record type");
- CXXRecordDecl *DestRecordDecl
- = cast<CXXRecordDecl>(DestRecordType->getDecl());
- // Build the candidate set directly in the initialization sequence
- // structure, so that it will persist if we fail.
- OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
- // Determine whether we are allowed to call explicit constructors or
- // explicit conversion operators.
- bool AllowExplicit = Kind.AllowExplicit() || IsListInit;
- bool CopyInitialization = Kind.getKind() == InitializationKind::IK_Copy;
- // - Otherwise, if T is a class type, constructors are considered. The
- // applicable constructors are enumerated, and the best one is chosen
- // through overload resolution.
- DeclContext::lookup_result Ctors = S.LookupConstructors(DestRecordDecl);
- OverloadingResult Result = OR_No_Viable_Function;
- OverloadCandidateSet::iterator Best;
- bool AsInitializerList = false;
- // C++11 [over.match.list]p1, per DR1467:
- // When objects of non-aggregate type T are list-initialized, such that
- // 8.5.4 [dcl.init.list] specifies that overload resolution is performed
- // according to the rules in this section, overload resolution selects
- // the constructor in two phases:
- //
- // - Initially, the candidate functions are the initializer-list
- // constructors of the class T and the argument list consists of the
- // initializer list as a single argument.
- if (IsListInit) {
- AsInitializerList = true;
- // If the initializer list has no elements and T has a default constructor,
- // the first phase is omitted.
- if (!(UnwrappedArgs.empty() && S.LookupDefaultConstructor(DestRecordDecl)))
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/true,
- IsListInit);
- }
- // C++11 [over.match.list]p1:
- // - If no viable initializer-list constructor is found, overload resolution
- // is performed again, where the candidate functions are all the
- // constructors of the class T and the argument list consists of the
- // elements of the initializer list.
- if (Result == OR_No_Viable_Function) {
- AsInitializerList = false;
- Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/false,
- IsListInit);
- }
- if (Result) {
- Sequence.SetOverloadFailure(
- IsListInit ? InitializationSequence::FK_ListConstructorOverloadFailed
- : InitializationSequence::FK_ConstructorOverloadFailed,
- Result);
- if (Result != OR_Deleted)
- return;
- }
- bool HadMultipleCandidates = (CandidateSet.size() > 1);
- // In C++17, ResolveConstructorOverload can select a conversion function
- // instead of a constructor.
- if (auto *CD = dyn_cast<CXXConversionDecl>(Best->Function)) {
- // Add the user-defined conversion step that calls the conversion function.
- QualType ConvType = CD->getConversionType();
- assert(S.Context.hasSameUnqualifiedType(ConvType, DestType) &&
- "should not have selected this conversion function");
- Sequence.AddUserConversionStep(CD, Best->FoundDecl, ConvType,
- HadMultipleCandidates);
- if (!S.Context.hasSameType(ConvType, DestType))
- Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
- if (IsListInit)
- Sequence.RewrapReferenceInitList(Entity.getType(), ILE);
- return;
- }
- CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
- if (Result != OR_Deleted) {
- // C++11 [dcl.init]p6:
- // If a program calls for the default initialization of an object
- // of a const-qualified type T, T shall be a class type with a
- // user-provided default constructor.
- // C++ core issue 253 proposal:
- // If the implicit default constructor initializes all subobjects, no
- // initializer should be required.
- // The 253 proposal is for example needed to process libstdc++ headers
- // in 5.x.
- if (Kind.getKind() == InitializationKind::IK_Default &&
- Entity.getType().isConstQualified()) {
- if (!CtorDecl->getParent()->allowConstDefaultInit()) {
- if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
- Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
- return;
- }
- }
- // C++11 [over.match.list]p1:
- // In copy-list-initialization, if an explicit constructor is chosen, the
- // initializer is ill-formed.
- if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) {
- Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor);
- return;
- }
- }
- // [class.copy.elision]p3:
- // In some copy-initialization contexts, a two-stage overload resolution
- // is performed.
- // If the first overload resolution selects a deleted function, we also
- // need the initialization sequence to decide whether to perform the second
- // overload resolution.
- // For deleted functions in other contexts, there is no need to get the
- // initialization sequence.
- if (Result == OR_Deleted && Kind.getKind() != InitializationKind::IK_Copy)
- return;
- // Add the constructor initialization step. Any cv-qualification conversion is
- // subsumed by the initialization.
- Sequence.AddConstructorInitializationStep(
- Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates,
- IsListInit | IsInitListCopy, AsInitializerList);
- }
- static bool
- ResolveOverloadedFunctionForReferenceBinding(Sema &S,
- Expr *Initializer,
- QualType &SourceType,
- QualType &UnqualifiedSourceType,
- QualType UnqualifiedTargetType,
- InitializationSequence &Sequence) {
- if (S.Context.getCanonicalType(UnqualifiedSourceType) ==
- S.Context.OverloadTy) {
- DeclAccessPair Found;
- bool HadMultipleCandidates = false;
- if (FunctionDecl *Fn
- = S.ResolveAddressOfOverloadedFunction(Initializer,
- UnqualifiedTargetType,
- false, Found,
- &HadMultipleCandidates)) {
- Sequence.AddAddressOverloadResolutionStep(Fn, Found,
- HadMultipleCandidates);
- SourceType = Fn->getType();
- UnqualifiedSourceType = SourceType.getUnqualifiedType();
- } else if (!UnqualifiedTargetType->isRecordType()) {
- Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
- return true;
- }
- }
- return false;
- }
- static void TryReferenceInitializationCore(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr *Initializer,
- QualType cv1T1, QualType T1,
- Qualifiers T1Quals,
- QualType cv2T2, QualType T2,
- Qualifiers T2Quals,
- InitializationSequence &Sequence);
- static void TryValueInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitializationSequence &Sequence,
- InitListExpr *InitList = nullptr);
- /// Attempt list initialization of a reference.
- static void TryReferenceListInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitListExpr *InitList,
- InitializationSequence &Sequence,
- bool TreatUnavailableAsInvalid) {
- // First, catch C++03 where this isn't possible.
- if (!S.getLangOpts().CPlusPlus11) {
- Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
- return;
- }
- // Can't reference initialize a compound literal.
- if (Entity.getKind() == InitializedEntity::EK_CompoundLiteralInit) {
- Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
- return;
- }
- QualType DestType = Entity.getType();
- QualType cv1T1 = DestType->castAs<ReferenceType>()->getPointeeType();
- Qualifiers T1Quals;
- QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals);
- // Reference initialization via an initializer list works thus:
- // If the initializer list consists of a single element that is
- // reference-related to the referenced type, bind directly to that element
- // (possibly creating temporaries).
- // Otherwise, initialize a temporary with the initializer list and
- // bind to that.
- if (InitList->getNumInits() == 1) {
- Expr *Initializer = InitList->getInit(0);
- QualType cv2T2 = S.getCompletedType(Initializer);
- Qualifiers T2Quals;
- QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals);
- // If this fails, creating a temporary wouldn't work either.
- if (ResolveOverloadedFunctionForReferenceBinding(S, Initializer, cv2T2, T2,
- T1, Sequence))
- return;
- SourceLocation DeclLoc = Initializer->getBeginLoc();
- Sema::ReferenceCompareResult RefRelationship
- = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2);
- if (RefRelationship >= Sema::Ref_Related) {
- // Try to bind the reference here.
- TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1,
- T1Quals, cv2T2, T2, T2Quals, Sequence);
- if (Sequence)
- Sequence.RewrapReferenceInitList(cv1T1, InitList);
- return;
- }
- // Update the initializer if we've resolved an overloaded function.
- if (Sequence.step_begin() != Sequence.step_end())
- Sequence.RewrapReferenceInitList(cv1T1, InitList);
- }
- // Perform address space compatibility check.
- QualType cv1T1IgnoreAS = cv1T1;
- if (T1Quals.hasAddressSpace()) {
- Qualifiers T2Quals;
- (void)S.Context.getUnqualifiedArrayType(InitList->getType(), T2Quals);
- if (!T1Quals.isAddressSpaceSupersetOf(T2Quals)) {
- Sequence.SetFailed(
- InitializationSequence::FK_ReferenceInitDropsQualifiers);
- return;
- }
- // Ignore address space of reference type at this point and perform address
- // space conversion after the reference binding step.
- cv1T1IgnoreAS =
- S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace());
- }
- // Not reference-related. Create a temporary and bind to that.
- InitializedEntity TempEntity =
- InitializedEntity::InitializeTemporary(cv1T1IgnoreAS);
- TryListInitialization(S, TempEntity, Kind, InitList, Sequence,
- TreatUnavailableAsInvalid);
- if (Sequence) {
- if (DestType->isRValueReferenceType() ||
- (T1Quals.hasConst() && !T1Quals.hasVolatile())) {
- Sequence.AddReferenceBindingStep(cv1T1IgnoreAS,
- /*BindingTemporary=*/true);
- if (T1Quals.hasAddressSpace())
- Sequence.AddQualificationConversionStep(
- cv1T1, DestType->isRValueReferenceType() ? VK_XValue : VK_LValue);
- } else
- Sequence.SetFailed(
- InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary);
- }
- }
- /// Attempt list initialization (C++0x [dcl.init.list])
- static void TryListInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitListExpr *InitList,
- InitializationSequence &Sequence,
- bool TreatUnavailableAsInvalid) {
- QualType DestType = Entity.getType();
- // C++ doesn't allow scalar initialization with more than one argument.
- // But C99 complex numbers are scalars and it makes sense there.
- if (S.getLangOpts().CPlusPlus && DestType->isScalarType() &&
- !DestType->isAnyComplexType() && InitList->getNumInits() > 1) {
- Sequence.SetFailed(InitializationSequence::FK_TooManyInitsForScalar);
- return;
- }
- if (DestType->isReferenceType()) {
- TryReferenceListInitialization(S, Entity, Kind, InitList, Sequence,
- TreatUnavailableAsInvalid);
- return;
- }
- if (DestType->isRecordType() &&
- !S.isCompleteType(InitList->getBeginLoc(), DestType)) {
- Sequence.setIncompleteTypeFailure(DestType);
- return;
- }
- // C++11 [dcl.init.list]p3, per DR1467:
- // - If T is a class type and the initializer list has a single element of
- // type cv U, where U is T or a class derived from T, the object is
- // initialized from that element (by copy-initialization for
- // copy-list-initialization, or by direct-initialization for
- // direct-list-initialization).
- // - Otherwise, if T is a character array and the initializer list has a
- // single element that is an appropriately-typed string literal
- // (8.5.2 [dcl.init.string]), initialization is performed as described
- // in that section.
- // - Otherwise, if T is an aggregate, [...] (continue below).
- if (S.getLangOpts().CPlusPlus11 && InitList->getNumInits() == 1) {
- if (DestType->isRecordType()) {
- QualType InitType = InitList->getInit(0)->getType();
- if (S.Context.hasSameUnqualifiedType(InitType, DestType) ||
- S.IsDerivedFrom(InitList->getBeginLoc(), InitType, DestType)) {
- Expr *InitListAsExpr = InitList;
- TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,
- DestType, Sequence,
- /*InitListSyntax*/false,
- /*IsInitListCopy*/true);
- return;
- }
- }
- if (const ArrayType *DestAT = S.Context.getAsArrayType(DestType)) {
- Expr *SubInit[1] = {InitList->getInit(0)};
- if (!isa<VariableArrayType>(DestAT) &&
- IsStringInit(SubInit[0], DestAT, S.Context) == SIF_None) {
- InitializationKind SubKind =
- Kind.getKind() == InitializationKind::IK_DirectList
- ? InitializationKind::CreateDirect(Kind.getLocation(),
- InitList->getLBraceLoc(),
- InitList->getRBraceLoc())
- : Kind;
- Sequence.InitializeFrom(S, Entity, SubKind, SubInit,
- /*TopLevelOfInitList*/ true,
- TreatUnavailableAsInvalid);
- // TryStringLiteralInitialization() (in InitializeFrom()) will fail if
- // the element is not an appropriately-typed string literal, in which
- // case we should proceed as in C++11 (below).
- if (Sequence) {
- Sequence.RewrapReferenceInitList(Entity.getType(), InitList);
- return;
- }
- }
- }
- }
- // C++11 [dcl.init.list]p3:
- // - If T is an aggregate, aggregate initialization is performed.
- if ((DestType->isRecordType() && !DestType->isAggregateType()) ||
- (S.getLangOpts().CPlusPlus11 &&
- S.isStdInitializerList(DestType, nullptr))) {
- if (S.getLangOpts().CPlusPlus11) {
- // - Otherwise, if the initializer list has no elements and T is a
- // class type with a default constructor, the object is
- // value-initialized.
- if (InitList->getNumInits() == 0) {
- CXXRecordDecl *RD = DestType->getAsCXXRecordDecl();
- if (S.LookupDefaultConstructor(RD)) {
- TryValueInitialization(S, Entity, Kind, Sequence, InitList);
- return;
- }
- }
- // - Otherwise, if T is a specialization of std::initializer_list<E>,
- // an initializer_list object constructed [...]
- if (TryInitializerListConstruction(S, InitList, DestType, Sequence,
- TreatUnavailableAsInvalid))
- return;
- // - Otherwise, if T is a class type, constructors are considered.
- Expr *InitListAsExpr = InitList;
- TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,
- DestType, Sequence, /*InitListSyntax*/true);
- } else
- Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
- return;
- }
- if (S.getLangOpts().CPlusPlus && !DestType->isAggregateType() &&
- InitList->getNumInits() == 1) {
- Expr *E = InitList->getInit(0);
- // - Otherwise, if T is an enumeration with a fixed underlying type,
- // the initializer-list has a single element v, and the initialization
- // is direct-list-initialization, the object is initialized with the
- // value T(v); if a narrowing conversion is required to convert v to
- // the underlying type of T, the program is ill-formed.
- auto *ET = DestType->getAs<EnumType>();
- if (S.getLangOpts().CPlusPlus17 &&
- Kind.getKind() == InitializationKind::IK_DirectList &&
- ET && ET->getDecl()->isFixed() &&
- !S.Context.hasSameUnqualifiedType(E->getType(), DestType) &&
- (E->getType()->isIntegralOrUnscopedEnumerationType() ||
- E->getType()->isFloatingType())) {
- // There are two ways that T(v) can work when T is an enumeration type.
- // If there is either an implicit conversion sequence from v to T or
- // a conversion function that can convert from v to T, then we use that.
- // Otherwise, if v is of integral, unscoped enumeration, or floating-point
- // type, it is converted to the enumeration type via its underlying type.
- // There is no overlap possible between these two cases (except when the
- // source value is already of the destination type), and the first
- // case is handled by the general case for single-element lists below.
- ImplicitConversionSequence ICS;
- ICS.setStandard();
- ICS.Standard.setAsIdentityConversion();
- if (!E->isPRValue())
- ICS.Standard.First = ICK_Lvalue_To_Rvalue;
- // If E is of a floating-point type, then the conversion is ill-formed
- // due to narrowing, but go through the motions in order to produce the
- // right diagnostic.
- ICS.Standard.Second = E->getType()->isFloatingType()
- ? ICK_Floating_Integral
- : ICK_Integral_Conversion;
- ICS.Standard.setFromType(E->getType());
- ICS.Standard.setToType(0, E->getType());
- ICS.Standard.setToType(1, DestType);
- ICS.Standard.setToType(2, DestType);
- Sequence.AddConversionSequenceStep(ICS, ICS.Standard.getToType(2),
- /*TopLevelOfInitList*/true);
- Sequence.RewrapReferenceInitList(Entity.getType(), InitList);
- return;
- }
- // - Otherwise, if the initializer list has a single element of type E
- // [...references are handled above...], the object or reference is
- // initialized from that element (by copy-initialization for
- // copy-list-initialization, or by direct-initialization for
- // direct-list-initialization); if a narrowing conversion is required
- // to convert the element to T, the program is ill-formed.
- //
- // Per core-24034, this is direct-initialization if we were performing
- // direct-list-initialization and copy-initialization otherwise.
- // We can't use InitListChecker for this, because it always performs
- // copy-initialization. This only matters if we might use an 'explicit'
- // conversion operator, or for the special case conversion of nullptr_t to
- // bool, so we only need to handle those cases.
- //
- // FIXME: Why not do this in all cases?
- Expr *Init = InitList->getInit(0);
- if (Init->getType()->isRecordType() ||
- (Init->getType()->isNullPtrType() && DestType->isBooleanType())) {
- InitializationKind SubKind =
- Kind.getKind() == InitializationKind::IK_DirectList
- ? InitializationKind::CreateDirect(Kind.getLocation(),
- InitList->getLBraceLoc(),
- InitList->getRBraceLoc())
- : Kind;
- Expr *SubInit[1] = { Init };
- Sequence.InitializeFrom(S, Entity, SubKind, SubInit,
- /*TopLevelOfInitList*/true,
- TreatUnavailableAsInvalid);
- if (Sequence)
- Sequence.RewrapReferenceInitList(Entity.getType(), InitList);
- return;
- }
- }
- InitListChecker CheckInitList(S, Entity, InitList,
- DestType, /*VerifyOnly=*/true, TreatUnavailableAsInvalid);
- if (CheckInitList.HadError()) {
- Sequence.SetFailed(InitializationSequence::FK_ListInitializationFailed);
- return;
- }
- // Add the list initialization step with the built init list.
- Sequence.AddListInitializationStep(DestType);
- }
- /// Try a reference initialization that involves calling a conversion
- /// function.
- static OverloadingResult TryRefInitWithConversionFunction(
- Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
- Expr *Initializer, bool AllowRValues, bool IsLValueRef,
- InitializationSequence &Sequence) {
- QualType DestType = Entity.getType();
- QualType cv1T1 = DestType->castAs<ReferenceType>()->getPointeeType();
- QualType T1 = cv1T1.getUnqualifiedType();
- QualType cv2T2 = Initializer->getType();
- QualType T2 = cv2T2.getUnqualifiedType();
- assert(!S.CompareReferenceRelationship(Initializer->getBeginLoc(), T1, T2) &&
- "Must have incompatible references when binding via conversion");
- // Build the candidate set directly in the initialization sequence
- // structure, so that it will persist if we fail.
- OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
- CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
- // Determine whether we are allowed to call explicit conversion operators.
- // Note that none of [over.match.copy], [over.match.conv], nor
- // [over.match.ref] permit an explicit constructor to be chosen when
- // initializing a reference, not even for direct-initialization.
- bool AllowExplicitCtors = false;
- bool AllowExplicitConvs = Kind.allowExplicitConversionFunctionsInRefBinding();
- const RecordType *T1RecordType = nullptr;
- if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&
- S.isCompleteType(Kind.getLocation(), T1)) {
- // The type we're converting to is a class type. Enumerate its constructors
- // to see if there is a suitable conversion.
- CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
- for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) {
- auto Info = getConstructorInfo(D);
- if (!Info.Constructor)
- continue;
- if (!Info.Constructor->isInvalidDecl() &&
- Info.Constructor->isConvertingConstructor(/*AllowExplicit*/true)) {
- if (Info.ConstructorTmpl)
- S.AddTemplateOverloadCandidate(
- Info.ConstructorTmpl, Info.FoundDecl,
- /*ExplicitArgs*/ nullptr, Initializer, CandidateSet,
- /*SuppressUserConversions=*/true,
- /*PartialOverloading*/ false, AllowExplicitCtors);
- else
- S.AddOverloadCandidate(
- Info.Constructor, Info.FoundDecl, Initializer, CandidateSet,
- /*SuppressUserConversions=*/true,
- /*PartialOverloading*/ false, AllowExplicitCtors);
- }
- }
- }
- if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
- return OR_No_Viable_Function;
- const RecordType *T2RecordType = nullptr;
- if ((T2RecordType = T2->getAs<RecordType>()) &&
- S.isCompleteType(Kind.getLocation(), T2)) {
- // The type we're converting from is a class type, enumerate its conversion
- // functions.
- CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());
- const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions();
- for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
- NamedDecl *D = *I;
- CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
- if (isa<UsingShadowDecl>(D))
- D = cast<UsingShadowDecl>(D)->getTargetDecl();
- FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
- CXXConversionDecl *Conv;
- if (ConvTemplate)
- Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
- else
- Conv = cast<CXXConversionDecl>(D);
- // If the conversion function doesn't return a reference type,
- // it can't be considered for this conversion unless we're allowed to
- // consider rvalues.
- // FIXME: Do we need to make sure that we only consider conversion
- // candidates with reference-compatible results? That might be needed to
- // break recursion.
- if ((AllowRValues ||
- Conv->getConversionType()->isLValueReferenceType())) {
- if (ConvTemplate)
- S.AddTemplateConversionCandidate(
- ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
- CandidateSet,
- /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs);
- else
- S.AddConversionCandidate(
- Conv, I.getPair(), ActingDC, Initializer, DestType, CandidateSet,
- /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs);
- }
- }
- }
- if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
- return OR_No_Viable_Function;
- SourceLocation DeclLoc = Initializer->getBeginLoc();
- // Perform overload resolution. If it fails, return the failed result.
- OverloadCandidateSet::iterator Best;
- if (OverloadingResult Result
- = CandidateSet.BestViableFunction(S, DeclLoc, Best))
- return Result;
- FunctionDecl *Function = Best->Function;
- // This is the overload that will be used for this initialization step if we
- // use this initialization. Mark it as referenced.
- Function->setReferenced();
- // Compute the returned type and value kind of the conversion.
- QualType cv3T3;
- if (isa<CXXConversionDecl>(Function))
- cv3T3 = Function->getReturnType();
- else
- cv3T3 = T1;
- ExprValueKind VK = VK_PRValue;
- if (cv3T3->isLValueReferenceType())
- VK = VK_LValue;
- else if (const auto *RRef = cv3T3->getAs<RValueReferenceType>())
- VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
- cv3T3 = cv3T3.getNonLValueExprType(S.Context);
- // Add the user-defined conversion step.
- bool HadMultipleCandidates = (CandidateSet.size() > 1);
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, cv3T3,
- HadMultipleCandidates);
- // Determine whether we'll need to perform derived-to-base adjustments or
- // other conversions.
- Sema::ReferenceConversions RefConv;
- Sema::ReferenceCompareResult NewRefRelationship =
- S.CompareReferenceRelationship(DeclLoc, T1, cv3T3, &RefConv);
- // Add the final conversion sequence, if necessary.
- if (NewRefRelationship == Sema::Ref_Incompatible) {
- assert(!isa<CXXConstructorDecl>(Function) &&
- "should not have conversion after constructor");
- ImplicitConversionSequence ICS;
- ICS.setStandard();
- ICS.Standard = Best->FinalConversion;
- Sequence.AddConversionSequenceStep(ICS, ICS.Standard.getToType(2));
- // Every implicit conversion results in a prvalue, except for a glvalue
- // derived-to-base conversion, which we handle below.
- cv3T3 = ICS.Standard.getToType(2);
- VK = VK_PRValue;
- }
- // If the converted initializer is a prvalue, its type T4 is adjusted to
- // type "cv1 T4" and the temporary materialization conversion is applied.
- //
- // We adjust the cv-qualifications to match the reference regardless of
- // whether we have a prvalue so that the AST records the change. In this
- // case, T4 is "cv3 T3".
- QualType cv1T4 = S.Context.getQualifiedType(cv3T3, cv1T1.getQualifiers());
- if (cv1T4.getQualifiers() != cv3T3.getQualifiers())
- Sequence.AddQualificationConversionStep(cv1T4, VK);
- Sequence.AddReferenceBindingStep(cv1T4, VK == VK_PRValue);
- VK = IsLValueRef ? VK_LValue : VK_XValue;
- if (RefConv & Sema::ReferenceConversions::DerivedToBase)
- Sequence.AddDerivedToBaseCastStep(cv1T1, VK);
- else if (RefConv & Sema::ReferenceConversions::ObjC)
- Sequence.AddObjCObjectConversionStep(cv1T1);
- else if (RefConv & Sema::ReferenceConversions::Function)
- Sequence.AddFunctionReferenceConversionStep(cv1T1);
- else if (RefConv & Sema::ReferenceConversions::Qualification) {
- if (!S.Context.hasSameType(cv1T4, cv1T1))
- Sequence.AddQualificationConversionStep(cv1T1, VK);
- }
- return OR_Success;
- }
- static void CheckCXX98CompatAccessibleCopy(Sema &S,
- const InitializedEntity &Entity,
- Expr *CurInitExpr);
- /// Attempt reference initialization (C++0x [dcl.init.ref])
- static void TryReferenceInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr *Initializer,
- InitializationSequence &Sequence) {
- QualType DestType = Entity.getType();
- QualType cv1T1 = DestType->castAs<ReferenceType>()->getPointeeType();
- Qualifiers T1Quals;
- QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals);
- QualType cv2T2 = S.getCompletedType(Initializer);
- Qualifiers T2Quals;
- QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals);
- // If the initializer is the address of an overloaded function, try
- // to resolve the overloaded function. If all goes well, T2 is the
- // type of the resulting function.
- if (ResolveOverloadedFunctionForReferenceBinding(S, Initializer, cv2T2, T2,
- T1, Sequence))
- return;
- // Delegate everything else to a subfunction.
- TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1,
- T1Quals, cv2T2, T2, T2Quals, Sequence);
- }
- /// Determine whether an expression is a non-referenceable glvalue (one to
- /// which a reference can never bind). Attempting to bind a reference to
- /// such a glvalue will always create a temporary.
- static bool isNonReferenceableGLValue(Expr *E) {
- return E->refersToBitField() || E->refersToVectorElement() ||
- E->refersToMatrixElement();
- }
- /// Reference initialization without resolving overloaded functions.
- ///
- /// We also can get here in C if we call a builtin which is declared as
- /// a function with a parameter of reference type (such as __builtin_va_end()).
- static void TryReferenceInitializationCore(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr *Initializer,
- QualType cv1T1, QualType T1,
- Qualifiers T1Quals,
- QualType cv2T2, QualType T2,
- Qualifiers T2Quals,
- InitializationSequence &Sequence) {
- QualType DestType = Entity.getType();
- SourceLocation DeclLoc = Initializer->getBeginLoc();
- // Compute some basic properties of the types and the initializer.
- bool isLValueRef = DestType->isLValueReferenceType();
- bool isRValueRef = !isLValueRef;
- Expr::Classification InitCategory = Initializer->Classify(S.Context);
- Sema::ReferenceConversions RefConv;
- Sema::ReferenceCompareResult RefRelationship =
- S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, &RefConv);
- // C++0x [dcl.init.ref]p5:
- // A reference to type "cv1 T1" is initialized by an expression of type
- // "cv2 T2" as follows:
- //
- // - If the reference is an lvalue reference and the initializer
- // expression
- // Note the analogous bullet points for rvalue refs to functions. Because
- // there are no function rvalues in C++, rvalue refs to functions are treated
- // like lvalue refs.
- OverloadingResult ConvOvlResult = OR_Success;
- bool T1Function = T1->isFunctionType();
- if (isLValueRef || T1Function) {
- if (InitCategory.isLValue() && !isNonReferenceableGLValue(Initializer) &&
- (RefRelationship == Sema::Ref_Compatible ||
- (Kind.isCStyleOrFunctionalCast() &&
- RefRelationship == Sema::Ref_Related))) {
- // - is an lvalue (but is not a bit-field), and "cv1 T1" is
- // reference-compatible with "cv2 T2," or
- if (RefConv & (Sema::ReferenceConversions::DerivedToBase |
- Sema::ReferenceConversions::ObjC)) {
- // If we're converting the pointee, add any qualifiers first;
- // these qualifiers must all be top-level, so just convert to "cv1 T2".
- if (RefConv & (Sema::ReferenceConversions::Qualification))
- Sequence.AddQualificationConversionStep(
- S.Context.getQualifiedType(T2, T1Quals),
- Initializer->getValueKind());
- if (RefConv & Sema::ReferenceConversions::DerivedToBase)
- Sequence.AddDerivedToBaseCastStep(cv1T1, VK_LValue);
- else
- Sequence.AddObjCObjectConversionStep(cv1T1);
- } else if (RefConv & Sema::ReferenceConversions::Qualification) {
- // Perform a (possibly multi-level) qualification conversion.
- Sequence.AddQualificationConversionStep(cv1T1,
- Initializer->getValueKind());
- } else if (RefConv & Sema::ReferenceConversions::Function) {
- Sequence.AddFunctionReferenceConversionStep(cv1T1);
- }
- // We only create a temporary here when binding a reference to a
- // bit-field or vector element. Those cases are't supposed to be
- // handled by this bullet, but the outcome is the same either way.
- Sequence.AddReferenceBindingStep(cv1T1, false);
- return;
- }
- // - has a class type (i.e., T2 is a class type), where T1 is not
- // reference-related to T2, and can be implicitly converted to an
- // lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible
- // with "cv3 T3" (this conversion is selected by enumerating the
- // applicable conversion functions (13.3.1.6) and choosing the best
- // one through overload resolution (13.3)),
- // If we have an rvalue ref to function type here, the rhs must be
- // an rvalue. DR1287 removed the "implicitly" here.
- if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
- (isLValueRef || InitCategory.isRValue())) {
- if (S.getLangOpts().CPlusPlus) {
- // Try conversion functions only for C++.
- ConvOvlResult = TryRefInitWithConversionFunction(
- S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
- /*IsLValueRef*/ isLValueRef, Sequence);
- if (ConvOvlResult == OR_Success)
- return;
- if (ConvOvlResult != OR_No_Viable_Function)
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_ReferenceInitOverloadFailed,
- ConvOvlResult);
- } else {
- ConvOvlResult = OR_No_Viable_Function;
- }
- }
- }
- // - Otherwise, the reference shall be an lvalue reference to a
- // non-volatile const type (i.e., cv1 shall be const), or the reference
- // shall be an rvalue reference.
- // For address spaces, we interpret this to mean that an addr space
- // of a reference "cv1 T1" is a superset of addr space of "cv2 T2".
- if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile() &&
- T1Quals.isAddressSpaceSupersetOf(T2Quals))) {
- if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)
- Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
- else if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_ReferenceInitOverloadFailed,
- ConvOvlResult);
- else if (!InitCategory.isLValue())
- Sequence.SetFailed(
- T1Quals.isAddressSpaceSupersetOf(T2Quals)
- ? InitializationSequence::
- FK_NonConstLValueReferenceBindingToTemporary
- : InitializationSequence::FK_ReferenceInitDropsQualifiers);
- else {
- InitializationSequence::FailureKind FK;
- switch (RefRelationship) {
- case Sema::Ref_Compatible:
- if (Initializer->refersToBitField())
- FK = InitializationSequence::
- FK_NonConstLValueReferenceBindingToBitfield;
- else if (Initializer->refersToVectorElement())
- FK = InitializationSequence::
- FK_NonConstLValueReferenceBindingToVectorElement;
- else if (Initializer->refersToMatrixElement())
- FK = InitializationSequence::
- FK_NonConstLValueReferenceBindingToMatrixElement;
- else
- llvm_unreachable("unexpected kind of compatible initializer");
- break;
- case Sema::Ref_Related:
- FK = InitializationSequence::FK_ReferenceInitDropsQualifiers;
- break;
- case Sema::Ref_Incompatible:
- FK = InitializationSequence::
- FK_NonConstLValueReferenceBindingToUnrelated;
- break;
- }
- Sequence.SetFailed(FK);
- }
- return;
- }
- // - If the initializer expression
- // - is an
- // [<=14] xvalue (but not a bit-field), class prvalue, array prvalue, or
- // [1z] rvalue (but not a bit-field) or
- // function lvalue and "cv1 T1" is reference-compatible with "cv2 T2"
- //
- // Note: functions are handled above and below rather than here...
- if (!T1Function &&
- (RefRelationship == Sema::Ref_Compatible ||
- (Kind.isCStyleOrFunctionalCast() &&
- RefRelationship == Sema::Ref_Related)) &&
- ((InitCategory.isXValue() && !isNonReferenceableGLValue(Initializer)) ||
- (InitCategory.isPRValue() &&
- (S.getLangOpts().CPlusPlus17 || T2->isRecordType() ||
- T2->isArrayType())))) {
- ExprValueKind ValueKind = InitCategory.isXValue() ? VK_XValue : VK_PRValue;
- if (InitCategory.isPRValue() && T2->isRecordType()) {
- // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the
- // compiler the freedom to perform a copy here or bind to the
- // object, while C++0x requires that we bind directly to the
- // object. Hence, we always bind to the object without making an
- // extra copy. However, in C++03 requires that we check for the
- // presence of a suitable copy constructor:
- //
- // The constructor that would be used to make the copy shall
- // be callable whether or not the copy is actually done.
- if (!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().MicrosoftExt)
- Sequence.AddExtraneousCopyToTemporary(cv2T2);
- else if (S.getLangOpts().CPlusPlus11)
- CheckCXX98CompatAccessibleCopy(S, Entity, Initializer);
- }
- // C++1z [dcl.init.ref]/5.2.1.2:
- // If the converted initializer is a prvalue, its type T4 is adjusted
- // to type "cv1 T4" and the temporary materialization conversion is
- // applied.
- // Postpone address space conversions to after the temporary materialization
- // conversion to allow creating temporaries in the alloca address space.
- auto T1QualsIgnoreAS = T1Quals;
- auto T2QualsIgnoreAS = T2Quals;
- if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) {
- T1QualsIgnoreAS.removeAddressSpace();
- T2QualsIgnoreAS.removeAddressSpace();
- }
- QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1QualsIgnoreAS);
- if (T1QualsIgnoreAS != T2QualsIgnoreAS)
- Sequence.AddQualificationConversionStep(cv1T4, ValueKind);
- Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_PRValue);
- ValueKind = isLValueRef ? VK_LValue : VK_XValue;
- // Add addr space conversion if required.
- if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) {
- auto T4Quals = cv1T4.getQualifiers();
- T4Quals.addAddressSpace(T1Quals.getAddressSpace());
- QualType cv1T4WithAS = S.Context.getQualifiedType(T2, T4Quals);
- Sequence.AddQualificationConversionStep(cv1T4WithAS, ValueKind);
- cv1T4 = cv1T4WithAS;
- }
- // In any case, the reference is bound to the resulting glvalue (or to
- // an appropriate base class subobject).
- if (RefConv & Sema::ReferenceConversions::DerivedToBase)
- Sequence.AddDerivedToBaseCastStep(cv1T1, ValueKind);
- else if (RefConv & Sema::ReferenceConversions::ObjC)
- Sequence.AddObjCObjectConversionStep(cv1T1);
- else if (RefConv & Sema::ReferenceConversions::Qualification) {
- if (!S.Context.hasSameType(cv1T4, cv1T1))
- Sequence.AddQualificationConversionStep(cv1T1, ValueKind);
- }
- return;
- }
- // - has a class type (i.e., T2 is a class type), where T1 is not
- // reference-related to T2, and can be implicitly converted to an
- // xvalue, class prvalue, or function lvalue of type "cv3 T3",
- // where "cv1 T1" is reference-compatible with "cv3 T3",
- //
- // DR1287 removes the "implicitly" here.
- if (T2->isRecordType()) {
- if (RefRelationship == Sema::Ref_Incompatible) {
- ConvOvlResult = TryRefInitWithConversionFunction(
- S, Entity, Kind, Initializer, /*AllowRValues*/ true,
- /*IsLValueRef*/ isLValueRef, Sequence);
- if (ConvOvlResult)
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_ReferenceInitOverloadFailed,
- ConvOvlResult);
- return;
- }
- if (RefRelationship == Sema::Ref_Compatible &&
- isRValueRef && InitCategory.isLValue()) {
- Sequence.SetFailed(
- InitializationSequence::FK_RValueReferenceBindingToLValue);
- return;
- }
- Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
- return;
- }
- // - Otherwise, a temporary of type "cv1 T1" is created and initialized
- // from the initializer expression using the rules for a non-reference
- // copy-initialization (8.5). The reference is then bound to the
- // temporary. [...]
- // Ignore address space of reference type at this point and perform address
- // space conversion after the reference binding step.
- QualType cv1T1IgnoreAS =
- T1Quals.hasAddressSpace()
- ? S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace())
- : cv1T1;
- InitializedEntity TempEntity =
- InitializedEntity::InitializeTemporary(cv1T1IgnoreAS);
- // FIXME: Why do we use an implicit conversion here rather than trying
- // copy-initialization?
- ImplicitConversionSequence ICS
- = S.TryImplicitConversion(Initializer, TempEntity.getType(),
- /*SuppressUserConversions=*/false,
- Sema::AllowedExplicit::None,
- /*FIXME:InOverloadResolution=*/false,
- /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
- /*AllowObjCWritebackConversion=*/false);
- if (ICS.isBad()) {
- // FIXME: Use the conversion function set stored in ICS to turn
- // this into an overloading ambiguity diagnostic. However, we need
- // to keep that set as an OverloadCandidateSet rather than as some
- // other kind of set.
- if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_ReferenceInitOverloadFailed,
- ConvOvlResult);
- else if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)
- Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
- else
- Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed);
- return;
- } else {
- Sequence.AddConversionSequenceStep(ICS, TempEntity.getType());
- }
- // [...] If T1 is reference-related to T2, cv1 must be the
- // same cv-qualification as, or greater cv-qualification
- // than, cv2; otherwise, the program is ill-formed.
- unsigned T1CVRQuals = T1Quals.getCVRQualifiers();
- unsigned T2CVRQuals = T2Quals.getCVRQualifiers();
- if (RefRelationship == Sema::Ref_Related &&
- ((T1CVRQuals | T2CVRQuals) != T1CVRQuals ||
- !T1Quals.isAddressSpaceSupersetOf(T2Quals))) {
- Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
- return;
- }
- // [...] If T1 is reference-related to T2 and the reference is an rvalue
- // reference, the initializer expression shall not be an lvalue.
- if (RefRelationship >= Sema::Ref_Related && !isLValueRef &&
- InitCategory.isLValue()) {
- Sequence.SetFailed(
- InitializationSequence::FK_RValueReferenceBindingToLValue);
- return;
- }
- Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*BindingTemporary=*/true);
- if (T1Quals.hasAddressSpace()) {
- if (!Qualifiers::isAddressSpaceSupersetOf(T1Quals.getAddressSpace(),
- LangAS::Default)) {
- Sequence.SetFailed(
- InitializationSequence::FK_ReferenceAddrspaceMismatchTemporary);
- return;
- }
- Sequence.AddQualificationConversionStep(cv1T1, isLValueRef ? VK_LValue
- : VK_XValue);
- }
- }
- /// Attempt character array initialization from a string literal
- /// (C++ [dcl.init.string], C99 6.7.8).
- static void TryStringLiteralInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr *Initializer,
- InitializationSequence &Sequence) {
- Sequence.AddStringInitStep(Entity.getType());
- }
- /// Attempt value initialization (C++ [dcl.init]p7).
- static void TryValueInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitializationSequence &Sequence,
- InitListExpr *InitList) {
- assert((!InitList || InitList->getNumInits() == 0) &&
- "Shouldn't use value-init for non-empty init lists");
- // C++98 [dcl.init]p5, C++11 [dcl.init]p7:
- //
- // To value-initialize an object of type T means:
- QualType T = Entity.getType();
- // -- if T is an array type, then each element is value-initialized;
- T = S.Context.getBaseElementType(T);
- if (const RecordType *RT = T->getAs<RecordType>()) {
- if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- bool NeedZeroInitialization = true;
- // C++98:
- // -- if T is a class type (clause 9) with a user-declared constructor
- // (12.1), then the default constructor for T is called (and the
- // initialization is ill-formed if T has no accessible default
- // constructor);
- // C++11:
- // -- if T is a class type (clause 9) with either no default constructor
- // (12.1 [class.ctor]) or a default constructor that is user-provided
- // or deleted, then the object is default-initialized;
- //
- // Note that the C++11 rule is the same as the C++98 rule if there are no
- // defaulted or deleted constructors, so we just use it unconditionally.
- CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl);
- if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted())
- NeedZeroInitialization = false;
- // -- if T is a (possibly cv-qualified) non-union class type without a
- // user-provided or deleted default constructor, then the object is
- // zero-initialized and, if T has a non-trivial default constructor,
- // default-initialized;
- // The 'non-union' here was removed by DR1502. The 'non-trivial default
- // constructor' part was removed by DR1507.
- if (NeedZeroInitialization)
- Sequence.AddZeroInitializationStep(Entity.getType());
- // C++03:
- // -- if T is a non-union class type without a user-declared constructor,
- // then every non-static data member and base class component of T is
- // value-initialized;
- // [...] A program that calls for [...] value-initialization of an
- // entity of reference type is ill-formed.
- //
- // C++11 doesn't need this handling, because value-initialization does not
- // occur recursively there, and the implicit default constructor is
- // defined as deleted in the problematic cases.
- if (!S.getLangOpts().CPlusPlus11 &&
- ClassDecl->hasUninitializedReferenceMember()) {
- Sequence.SetFailed(InitializationSequence::FK_TooManyInitsForReference);
- return;
- }
- // If this is list-value-initialization, pass the empty init list on when
- // building the constructor call. This affects the semantics of a few
- // things (such as whether an explicit default constructor can be called).
- Expr *InitListAsExpr = InitList;
- MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0);
- bool InitListSyntax = InitList;
- // FIXME: Instead of creating a CXXConstructExpr of array type here,
- // wrap a class-typed CXXConstructExpr in an ArrayInitLoopExpr.
- return TryConstructorInitialization(
- S, Entity, Kind, Args, T, Entity.getType(), Sequence, InitListSyntax);
- }
- }
- Sequence.AddZeroInitializationStep(Entity.getType());
- }
- /// Attempt default initialization (C++ [dcl.init]p6).
- static void TryDefaultInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- InitializationSequence &Sequence) {
- assert(Kind.getKind() == InitializationKind::IK_Default);
- // C++ [dcl.init]p6:
- // To default-initialize an object of type T means:
- // - if T is an array type, each element is default-initialized;
- QualType DestType = S.Context.getBaseElementType(Entity.getType());
- // - if T is a (possibly cv-qualified) class type (Clause 9), the default
- // constructor for T is called (and the initialization is ill-formed if
- // T has no accessible default constructor);
- if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) {
- TryConstructorInitialization(S, Entity, Kind, std::nullopt, DestType,
- Entity.getType(), Sequence);
- return;
- }
- // - otherwise, no initialization is performed.
- // If a program calls for the default initialization of an object of
- // a const-qualified type T, T shall be a class type with a user-provided
- // default constructor.
- if (DestType.isConstQualified() && S.getLangOpts().CPlusPlus) {
- if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
- Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
- return;
- }
- // If the destination type has a lifetime property, zero-initialize it.
- if (DestType.getQualifiers().hasObjCLifetime()) {
- Sequence.AddZeroInitializationStep(Entity.getType());
- return;
- }
- }
- static void TryOrBuildParenListInitialization(
- Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
- ArrayRef<Expr *> Args, InitializationSequence &Sequence, bool VerifyOnly,
- ExprResult *Result = nullptr) {
- unsigned ArgIndexToProcess = 0;
- SmallVector<Expr *, 4> InitExprs;
- QualType ResultType;
- Expr *ArrayFiller = nullptr;
- FieldDecl *InitializedFieldInUnion = nullptr;
- // Process entities (i.e. array members, base classes, or class fields) by
- // adding an initialization expression to InitExprs for each entity to
- // initialize.
- auto ProcessEntities = [&](auto Range) -> bool {
- bool IsUnionType = Entity.getType()->isUnionType();
- for (InitializedEntity SubEntity : Range) {
- // Unions should only have one initializer expression.
- // If there are more initializers than it will be caught when we check
- // whether Index equals Args.size().
- if (ArgIndexToProcess == 1 && IsUnionType)
- return true;
- bool IsMember = SubEntity.getKind() == InitializedEntity::EK_Member;
- // Unnamed bitfields should not be initialized at all, either with an arg
- // or by default.
- if (IsMember && cast<FieldDecl>(SubEntity.getDecl())->isUnnamedBitfield())
- continue;
- if (ArgIndexToProcess < Args.size()) {
- // There are still expressions in Args that haven't been processed.
- // Let's match them to the current entity to initialize.
- Expr *E = Args[ArgIndexToProcess++];
- // Incomplete array types indicate flexible array members. Do not allow
- // paren list initializations of structs with these members, as GCC
- // doesn't either.
- if (IsMember) {
- auto *FD = cast<FieldDecl>(SubEntity.getDecl());
- if (FD->getType()->isIncompleteArrayType()) {
- if (!VerifyOnly) {
- S.Diag(E->getBeginLoc(), diag::err_flexible_array_init)
- << SourceRange(E->getBeginLoc(), E->getEndLoc());
- S.Diag(FD->getLocation(), diag::note_flexible_array_member) << FD;
- }
- Sequence.SetFailed(
- InitializationSequence::FK_ParenthesizedListInitFailed);
- return false;
- }
- }
- InitializationKind SubKind = InitializationKind::CreateForInit(
- E->getExprLoc(), /*isDirectInit=*/false, E);
- InitializationSequence SubSeq(S, SubEntity, SubKind, E);
- if (SubSeq.Failed()) {
- if (!VerifyOnly)
- SubSeq.Diagnose(S, SubEntity, SubKind, E);
- else
- Sequence.SetFailed(
- InitializationSequence::FK_ParenthesizedListInitFailed);
- return false;
- }
- if (!VerifyOnly) {
- ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, E);
- InitExprs.push_back(ER.get());
- if (IsMember && IsUnionType)
- InitializedFieldInUnion = cast<FieldDecl>(SubEntity.getDecl());
- }
- } else {
- // We've processed all of the args, but there are still entities that
- // have to be initialized.
- if (IsMember) {
- // C++ [dcl.init]p17.6.2.2
- // The remaining elements are initialized with their default member
- // initializers, if any
- auto *FD = cast<FieldDecl>(SubEntity.getDecl());
- if (Expr *ICE = FD->getInClassInitializer(); ICE && !VerifyOnly) {
- ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD);
- if (DIE.isInvalid())
- return false;
- S.checkInitializerLifetime(SubEntity, DIE.get());
- InitExprs.push_back(DIE.get());
- continue;
- };
- }
- // Remaining class elements without default member initializers and
- // array elements are value initialized:
- //
- // C++ [dcl.init]p17.6.2.2
- // The remaining elements...otherwise are value initialzed
- //
- // C++ [dcl.init]p17.5
- // if the destination type is an array, the object is initialized as
- // . follows. Let x1, . . . , xk be the elements of the expression-list
- // ...Let n denote the array size...the ith array element is...value-
- // initialized for each k < i <= n.
- InitializationKind SubKind = InitializationKind::CreateValue(
- Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), true);
- InitializationSequence SubSeq(S, SubEntity, SubKind, std::nullopt);
- if (SubSeq.Failed()) {
- if (!VerifyOnly)
- SubSeq.Diagnose(S, SubEntity, SubKind, std::nullopt);
- return false;
- }
- if (!VerifyOnly) {
- ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, std::nullopt);
- if (SubEntity.getKind() == InitializedEntity::EK_ArrayElement) {
- ArrayFiller = ER.get();
- return true;
- }
- InitExprs.push_back(ER.get());
- }
- }
- }
- return true;
- };
- if (const ArrayType *AT =
- S.getASTContext().getAsArrayType(Entity.getType())) {
- SmallVector<InitializedEntity, 4> ElementEntities;
- uint64_t ArrayLength;
- // C++ [dcl.init]p17.5
- // if the destination type is an array, the object is initialized as
- // follows. Let x1, . . . , xk be the elements of the expression-list. If
- // the destination type is an array of unknown bound, it is define as
- // having k elements.
- if (const ConstantArrayType *CAT =
- S.getASTContext().getAsConstantArrayType(Entity.getType()))
- ArrayLength = CAT->getSize().getZExtValue();
- else
- ArrayLength = Args.size();
- if (ArrayLength >= Args.size()) {
- for (uint64_t I = 0; I < ArrayLength; ++I)
- ElementEntities.push_back(
- InitializedEntity::InitializeElement(S.getASTContext(), I, Entity));
- if (!ProcessEntities(ElementEntities))
- return;
- ResultType = S.Context.getConstantArrayType(
- AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength),
- nullptr, ArrayType::Normal, 0);
- }
- } else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- auto BaseRange = map_range(RD->bases(), [&S](auto &base) {
- return InitializedEntity::InitializeBase(S.getASTContext(), &base, false);
- });
- auto FieldRange = map_range(RD->fields(), [](auto *field) {
- return InitializedEntity::InitializeMember(field);
- });
- if (!ProcessEntities(BaseRange))
- return;
- if (!ProcessEntities(FieldRange))
- return;
- ResultType = Entity.getType();
- }
- // Not all of the args have been processed, so there must've been more args
- // then were required to initialize the element.
- if (ArgIndexToProcess < Args.size()) {
- Sequence.SetFailed(InitializationSequence::FK_ParenthesizedListInitFailed);
- if (!VerifyOnly) {
- QualType T = Entity.getType();
- int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 3 : 4;
- SourceRange ExcessInitSR(Args[ArgIndexToProcess]->getBeginLoc(),
- Args.back()->getEndLoc());
- S.Diag(Kind.getLocation(), diag::err_excess_initializers)
- << InitKind << ExcessInitSR;
- }
- return;
- }
- if (VerifyOnly) {
- Sequence.setSequenceKind(InitializationSequence::NormalSequence);
- Sequence.AddParenthesizedListInitStep(Entity.getType());
- } else if (Result) {
- SourceRange SR = Kind.getParenOrBraceRange();
- auto *CPLIE = CXXParenListInitExpr::Create(
- S.getASTContext(), InitExprs, ResultType, Args.size(),
- Kind.getLocation(), SR.getBegin(), SR.getEnd());
- if (ArrayFiller)
- CPLIE->setArrayFiller(ArrayFiller);
- if (InitializedFieldInUnion)
- CPLIE->setInitializedFieldInUnion(InitializedFieldInUnion);
- *Result = CPLIE;
- S.Diag(Kind.getLocation(),
- diag::warn_cxx17_compat_aggregate_init_paren_list)
- << Kind.getLocation() << SR << ResultType;
- }
- return;
- }
- /// Attempt a user-defined conversion between two types (C++ [dcl.init]),
- /// which enumerates all conversion functions and performs overload resolution
- /// to select the best.
- static void TryUserDefinedConversion(Sema &S,
- QualType DestType,
- const InitializationKind &Kind,
- Expr *Initializer,
- InitializationSequence &Sequence,
- bool TopLevelOfInitList) {
- assert(!DestType->isReferenceType() && "References are handled elsewhere");
- QualType SourceType = Initializer->getType();
- assert((DestType->isRecordType() || SourceType->isRecordType()) &&
- "Must have a class type to perform a user-defined conversion");
- // Build the candidate set directly in the initialization sequence
- // structure, so that it will persist if we fail.
- OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
- CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
- CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
- // Determine whether we are allowed to call explicit constructors or
- // explicit conversion operators.
- bool AllowExplicit = Kind.AllowExplicit();
- if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) {
- // The type we're converting to is a class type. Enumerate its constructors
- // to see if there is a suitable conversion.
- CXXRecordDecl *DestRecordDecl
- = cast<CXXRecordDecl>(DestRecordType->getDecl());
- // Try to complete the type we're converting to.
- if (S.isCompleteType(Kind.getLocation(), DestType)) {
- for (NamedDecl *D : S.LookupConstructors(DestRecordDecl)) {
- auto Info = getConstructorInfo(D);
- if (!Info.Constructor)
- continue;
- if (!Info.Constructor->isInvalidDecl() &&
- Info.Constructor->isConvertingConstructor(/*AllowExplicit*/true)) {
- if (Info.ConstructorTmpl)
- S.AddTemplateOverloadCandidate(
- Info.ConstructorTmpl, Info.FoundDecl,
- /*ExplicitArgs*/ nullptr, Initializer, CandidateSet,
- /*SuppressUserConversions=*/true,
- /*PartialOverloading*/ false, AllowExplicit);
- else
- S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
- Initializer, CandidateSet,
- /*SuppressUserConversions=*/true,
- /*PartialOverloading*/ false, AllowExplicit);
- }
- }
- }
- }
- SourceLocation DeclLoc = Initializer->getBeginLoc();
- if (const RecordType *SourceRecordType = SourceType->getAs<RecordType>()) {
- // The type we're converting from is a class type, enumerate its conversion
- // functions.
- // We can only enumerate the conversion functions for a complete type; if
- // the type isn't complete, simply skip this step.
- if (S.isCompleteType(DeclLoc, SourceType)) {
- CXXRecordDecl *SourceRecordDecl
- = cast<CXXRecordDecl>(SourceRecordType->getDecl());
- const auto &Conversions =
- SourceRecordDecl->getVisibleConversionFunctions();
- for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
- NamedDecl *D = *I;
- CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
- if (isa<UsingShadowDecl>(D))
- D = cast<UsingShadowDecl>(D)->getTargetDecl();
- FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
- CXXConversionDecl *Conv;
- if (ConvTemplate)
- Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
- else
- Conv = cast<CXXConversionDecl>(D);
- if (ConvTemplate)
- S.AddTemplateConversionCandidate(
- ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
- CandidateSet, AllowExplicit, AllowExplicit);
- else
- S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer,
- DestType, CandidateSet, AllowExplicit,
- AllowExplicit);
- }
- }
- }
- // Perform overload resolution. If it fails, return the failed result.
- OverloadCandidateSet::iterator Best;
- if (OverloadingResult Result
- = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_UserConversionOverloadFailed, Result);
- // [class.copy.elision]p3:
- // In some copy-initialization contexts, a two-stage overload resolution
- // is performed.
- // If the first overload resolution selects a deleted function, we also
- // need the initialization sequence to decide whether to perform the second
- // overload resolution.
- if (!(Result == OR_Deleted &&
- Kind.getKind() == InitializationKind::IK_Copy))
- return;
- }
- FunctionDecl *Function = Best->Function;
- Function->setReferenced();
- bool HadMultipleCandidates = (CandidateSet.size() > 1);
- if (isa<CXXConstructorDecl>(Function)) {
- // Add the user-defined conversion step. Any cv-qualification conversion is
- // subsumed by the initialization. Per DR5, the created temporary is of the
- // cv-unqualified type of the destination.
- Sequence.AddUserConversionStep(Function, Best->FoundDecl,
- DestType.getUnqualifiedType(),
- HadMultipleCandidates);
- // C++14 and before:
- // - if the function is a constructor, the call initializes a temporary
- // of the cv-unqualified version of the destination type. The [...]
- // temporary [...] is then used to direct-initialize, according to the
- // rules above, the object that is the destination of the
- // copy-initialization.
- // Note that this just performs a simple object copy from the temporary.
- //
- // C++17:
- // - if the function is a constructor, the call is a prvalue of the
- // cv-unqualified version of the destination type whose return object
- // is initialized by the constructor. The call is used to
- // direct-initialize, according to the rules above, the object that
- // is the destination of the copy-initialization.
- // Therefore we need to do nothing further.
- //
- // FIXME: Mark this copy as extraneous.
- if (!S.getLangOpts().CPlusPlus17)
- Sequence.AddFinalCopy(DestType);
- else if (DestType.hasQualifiers())
- Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
- return;
- }
- // Add the user-defined conversion step that calls the conversion function.
- QualType ConvType = Function->getCallResultType();
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType,
- HadMultipleCandidates);
- if (ConvType->getAs<RecordType>()) {
- // The call is used to direct-initialize [...] the object that is the
- // destination of the copy-initialization.
- //
- // In C++17, this does not call a constructor if we enter /17.6.1:
- // - If the initializer expression is a prvalue and the cv-unqualified
- // version of the source type is the same as the class of the
- // destination [... do not make an extra copy]
- //
- // FIXME: Mark this copy as extraneous.
- if (!S.getLangOpts().CPlusPlus17 ||
- Function->getReturnType()->isReferenceType() ||
- !S.Context.hasSameUnqualifiedType(ConvType, DestType))
- Sequence.AddFinalCopy(DestType);
- else if (!S.Context.hasSameType(ConvType, DestType))
- Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
- return;
- }
- // If the conversion following the call to the conversion function
- // is interesting, add it as a separate step.
- if (Best->FinalConversion.First || Best->FinalConversion.Second ||
- Best->FinalConversion.Third) {
- ImplicitConversionSequence ICS;
- ICS.setStandard();
- ICS.Standard = Best->FinalConversion;
- Sequence.AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
- }
- }
- /// An egregious hack for compatibility with libstdc++-4.2: in <tr1/hashtable>,
- /// a function with a pointer return type contains a 'return false;' statement.
- /// In C++11, 'false' is not a null pointer, so this breaks the build of any
- /// code using that header.
- ///
- /// Work around this by treating 'return false;' as zero-initializing the result
- /// if it's used in a pointer-returning function in a system header.
- static bool isLibstdcxxPointerReturnFalseHack(Sema &S,
- const InitializedEntity &Entity,
- const Expr *Init) {
- return S.getLangOpts().CPlusPlus11 &&
- Entity.getKind() == InitializedEntity::EK_Result &&
- Entity.getType()->isPointerType() &&
- isa<CXXBoolLiteralExpr>(Init) &&
- !cast<CXXBoolLiteralExpr>(Init)->getValue() &&
- S.getSourceManager().isInSystemHeader(Init->getExprLoc());
- }
- /// The non-zero enum values here are indexes into diagnostic alternatives.
- enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar };
- /// Determines whether this expression is an acceptable ICR source.
- static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e,
- bool isAddressOf, bool &isWeakAccess) {
- // Skip parens.
- e = e->IgnoreParens();
- // Skip address-of nodes.
- if (UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
- if (op->getOpcode() == UO_AddrOf)
- return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true,
- isWeakAccess);
- // Skip certain casts.
- } else if (CastExpr *ce = dyn_cast<CastExpr>(e)) {
- switch (ce->getCastKind()) {
- case CK_Dependent:
- case CK_BitCast:
- case CK_LValueBitCast:
- case CK_NoOp:
- return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf, isWeakAccess);
- case CK_ArrayToPointerDecay:
- return IIK_nonscalar;
- case CK_NullToPointer:
- return IIK_okay;
- default:
- break;
- }
- // If we have a declaration reference, it had better be a local variable.
- } else if (isa<DeclRefExpr>(e)) {
- // set isWeakAccess to true, to mean that there will be an implicit
- // load which requires a cleanup.
- if (e->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
- isWeakAccess = true;
- if (!isAddressOf) return IIK_nonlocal;
- VarDecl *var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl());
- if (!var) return IIK_nonlocal;
- return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
- // If we have a conditional operator, check both sides.
- } else if (ConditionalOperator *cond = dyn_cast<ConditionalOperator>(e)) {
- if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf,
- isWeakAccess))
- return iik;
- return isInvalidICRSource(C, cond->getRHS(), isAddressOf, isWeakAccess);
- // These are never scalar.
- } else if (isa<ArraySubscriptExpr>(e)) {
- return IIK_nonscalar;
- // Otherwise, it needs to be a null pointer constant.
- } else {
- return (e->isNullPointerConstant(C, Expr::NPC_ValueDependentIsNull)
- ? IIK_okay : IIK_nonlocal);
- }
- return IIK_nonlocal;
- }
- /// Check whether the given expression is a valid operand for an
- /// indirect copy/restore.
- static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) {
- assert(src->isPRValue());
- bool isWeakAccess = false;
- InvalidICRKind iik = isInvalidICRSource(S.Context, src, false, isWeakAccess);
- // If isWeakAccess to true, there will be an implicit
- // load which requires a cleanup.
- if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess)
- S.Cleanup.setExprNeedsCleanups(true);
- if (iik == IIK_okay) return;
- S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
- << ((unsigned) iik - 1) // shift index into diagnostic explanations
- << src->getSourceRange();
- }
- /// Determine whether we have compatible array types for the
- /// purposes of GNU by-copy array initialization.
- static bool hasCompatibleArrayTypes(ASTContext &Context, const ArrayType *Dest,
- const ArrayType *Source) {
- // If the source and destination array types are equivalent, we're
- // done.
- if (Context.hasSameType(QualType(Dest, 0), QualType(Source, 0)))
- return true;
- // Make sure that the element types are the same.
- if (!Context.hasSameType(Dest->getElementType(), Source->getElementType()))
- return false;
- // The only mismatch we allow is when the destination is an
- // incomplete array type and the source is a constant array type.
- return Source->isConstantArrayType() && Dest->isIncompleteArrayType();
- }
- static bool tryObjCWritebackConversion(Sema &S,
- InitializationSequence &Sequence,
- const InitializedEntity &Entity,
- Expr *Initializer) {
- bool ArrayDecay = false;
- QualType ArgType = Initializer->getType();
- QualType ArgPointee;
- if (const ArrayType *ArgArrayType = S.Context.getAsArrayType(ArgType)) {
- ArrayDecay = true;
- ArgPointee = ArgArrayType->getElementType();
- ArgType = S.Context.getPointerType(ArgPointee);
- }
- // Handle write-back conversion.
- QualType ConvertedArgType;
- if (!S.isObjCWritebackConversion(ArgType, Entity.getType(),
- ConvertedArgType))
- return false;
- // We should copy unless we're passing to an argument explicitly
- // marked 'out'.
- bool ShouldCopy = true;
- if (ParmVarDecl *param = cast_or_null<ParmVarDecl>(Entity.getDecl()))
- ShouldCopy = (param->getObjCDeclQualifier() != ParmVarDecl::OBJC_TQ_Out);
- // Do we need an lvalue conversion?
- if (ArrayDecay || Initializer->isGLValue()) {
- ImplicitConversionSequence ICS;
- ICS.setStandard();
- ICS.Standard.setAsIdentityConversion();
- QualType ResultType;
- if (ArrayDecay) {
- ICS.Standard.First = ICK_Array_To_Pointer;
- ResultType = S.Context.getPointerType(ArgPointee);
- } else {
- ICS.Standard.First = ICK_Lvalue_To_Rvalue;
- ResultType = Initializer->getType().getNonLValueExprType(S.Context);
- }
- Sequence.AddConversionSequenceStep(ICS, ResultType);
- }
- Sequence.AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy);
- return true;
- }
- static bool TryOCLSamplerInitialization(Sema &S,
- InitializationSequence &Sequence,
- QualType DestType,
- Expr *Initializer) {
- if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() ||
- (!Initializer->isIntegerConstantExpr(S.Context) &&
- !Initializer->getType()->isSamplerT()))
- return false;
- Sequence.AddOCLSamplerInitStep(DestType);
- return true;
- }
- static bool IsZeroInitializer(Expr *Initializer, Sema &S) {
- return Initializer->isIntegerConstantExpr(S.getASTContext()) &&
- (Initializer->EvaluateKnownConstInt(S.getASTContext()) == 0);
- }
- static bool TryOCLZeroOpaqueTypeInitialization(Sema &S,
- InitializationSequence &Sequence,
- QualType DestType,
- Expr *Initializer) {
- if (!S.getLangOpts().OpenCL)
- return false;
- //
- // OpenCL 1.2 spec, s6.12.10
- //
- // The event argument can also be used to associate the
- // async_work_group_copy with a previous async copy allowing
- // an event to be shared by multiple async copies; otherwise
- // event should be zero.
- //
- if (DestType->isEventT() || DestType->isQueueT()) {
- if (!IsZeroInitializer(Initializer, S))
- return false;
- Sequence.AddOCLZeroOpaqueTypeStep(DestType);
- return true;
- }
- // We should allow zero initialization for all types defined in the
- // cl_intel_device_side_avc_motion_estimation extension, except
- // intel_sub_group_avc_mce_payload_t and intel_sub_group_avc_mce_result_t.
- if (S.getOpenCLOptions().isAvailableOption(
- "cl_intel_device_side_avc_motion_estimation", S.getLangOpts()) &&
- DestType->isOCLIntelSubgroupAVCType()) {
- if (DestType->isOCLIntelSubgroupAVCMcePayloadType() ||
- DestType->isOCLIntelSubgroupAVCMceResultType())
- return false;
- if (!IsZeroInitializer(Initializer, S))
- return false;
- Sequence.AddOCLZeroOpaqueTypeStep(DestType);
- return true;
- }
- return false;
- }
- InitializationSequence::InitializationSequence(
- Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
- MultiExprArg Args, bool TopLevelOfInitList, bool TreatUnavailableAsInvalid)
- : FailedOverloadResult(OR_Success),
- FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
- InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList,
- TreatUnavailableAsInvalid);
- }
- /// Tries to get a FunctionDecl out of `E`. If it succeeds and we can take the
- /// address of that function, this returns true. Otherwise, it returns false.
- static bool isExprAnUnaddressableFunction(Sema &S, const Expr *E) {
- auto *DRE = dyn_cast<DeclRefExpr>(E);
- if (!DRE || !isa<FunctionDecl>(DRE->getDecl()))
- return false;
- return !S.checkAddressOfFunctionIsAvailable(
- cast<FunctionDecl>(DRE->getDecl()));
- }
- /// Determine whether we can perform an elementwise array copy for this kind
- /// of entity.
- static bool canPerformArrayCopy(const InitializedEntity &Entity) {
- switch (Entity.getKind()) {
- case InitializedEntity::EK_LambdaCapture:
- // C++ [expr.prim.lambda]p24:
- // For array members, the array elements are direct-initialized in
- // increasing subscript order.
- return true;
- case InitializedEntity::EK_Variable:
- // C++ [dcl.decomp]p1:
- // [...] each element is copy-initialized or direct-initialized from the
- // corresponding element of the assignment-expression [...]
- return isa<DecompositionDecl>(Entity.getDecl());
- case InitializedEntity::EK_Member:
- // C++ [class.copy.ctor]p14:
- // - if the member is an array, each element is direct-initialized with
- // the corresponding subobject of x
- return Entity.isImplicitMemberInitializer();
- case InitializedEntity::EK_ArrayElement:
- // All the above cases are intended to apply recursively, even though none
- // of them actually say that.
- if (auto *E = Entity.getParent())
- return canPerformArrayCopy(*E);
- break;
- default:
- break;
- }
- return false;
- }
- void InitializationSequence::InitializeFrom(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- bool TopLevelOfInitList,
- bool TreatUnavailableAsInvalid) {
- ASTContext &Context = S.Context;
- // Eliminate non-overload placeholder types in the arguments. We
- // need to do this before checking whether types are dependent
- // because lowering a pseudo-object expression might well give us
- // something of dependent type.
- for (unsigned I = 0, E = Args.size(); I != E; ++I)
- if (Args[I]->getType()->isNonOverloadPlaceholderType()) {
- // FIXME: should we be doing this here?
- ExprResult result = S.CheckPlaceholderExpr(Args[I]);
- if (result.isInvalid()) {
- SetFailed(FK_PlaceholderType);
- return;
- }
- Args[I] = result.get();
- }
- // C++0x [dcl.init]p16:
- // The semantics of initializers are as follows. The destination type is
- // the type of the object or reference being initialized and the source
- // type is the type of the initializer expression. The source type is not
- // defined when the initializer is a braced-init-list or when it is a
- // parenthesized list of expressions.
- QualType DestType = Entity.getType();
- if (DestType->isDependentType() ||
- Expr::hasAnyTypeDependentArguments(Args)) {
- SequenceKind = DependentSequence;
- return;
- }
- // Almost everything is a normal sequence.
- setSequenceKind(NormalSequence);
- QualType SourceType;
- Expr *Initializer = nullptr;
- if (Args.size() == 1) {
- Initializer = Args[0];
- if (S.getLangOpts().ObjC) {
- if (S.CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(),
- DestType, Initializer->getType(),
- Initializer) ||
- S.CheckConversionToObjCLiteral(DestType, Initializer))
- Args[0] = Initializer;
- }
- if (!isa<InitListExpr>(Initializer))
- SourceType = Initializer->getType();
- }
- // - If the initializer is a (non-parenthesized) braced-init-list, the
- // object is list-initialized (8.5.4).
- if (Kind.getKind() != InitializationKind::IK_Direct) {
- if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
- TryListInitialization(S, Entity, Kind, InitList, *this,
- TreatUnavailableAsInvalid);
- return;
- }
- }
- // - If the destination type is a reference type, see 8.5.3.
- if (DestType->isReferenceType()) {
- // C++0x [dcl.init.ref]p1:
- // A variable declared to be a T& or T&&, that is, "reference to type T"
- // (8.3.2), shall be initialized by an object, or function, of type T or
- // by an object that can be converted into a T.
- // (Therefore, multiple arguments are not permitted.)
- if (Args.size() != 1)
- SetFailed(FK_TooManyInitsForReference);
- // C++17 [dcl.init.ref]p5:
- // A reference [...] is initialized by an expression [...] as follows:
- // If the initializer is not an expression, presumably we should reject,
- // but the standard fails to actually say so.
- else if (isa<InitListExpr>(Args[0]))
- SetFailed(FK_ParenthesizedListInitForReference);
- else
- TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
- return;
- }
- // - If the initializer is (), the object is value-initialized.
- if (Kind.getKind() == InitializationKind::IK_Value ||
- (Kind.getKind() == InitializationKind::IK_Direct && Args.empty())) {
- TryValueInitialization(S, Entity, Kind, *this);
- return;
- }
- // Handle default initialization.
- if (Kind.getKind() == InitializationKind::IK_Default) {
- TryDefaultInitialization(S, Entity, Kind, *this);
- return;
- }
- // - If the destination type is an array of characters, an array of
- // char16_t, an array of char32_t, or an array of wchar_t, and the
- // initializer is a string literal, see 8.5.2.
- // - Otherwise, if the destination type is an array, the program is
- // ill-formed.
- if (const ArrayType *DestAT = Context.getAsArrayType(DestType)) {
- if (Initializer && isa<VariableArrayType>(DestAT)) {
- SetFailed(FK_VariableLengthArrayHasInitializer);
- return;
- }
- if (Initializer) {
- switch (IsStringInit(Initializer, DestAT, Context)) {
- case SIF_None:
- TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
- return;
- case SIF_NarrowStringIntoWideChar:
- SetFailed(FK_NarrowStringIntoWideCharArray);
- return;
- case SIF_WideStringIntoChar:
- SetFailed(FK_WideStringIntoCharArray);
- return;
- case SIF_IncompatWideStringIntoWideChar:
- SetFailed(FK_IncompatWideStringIntoWideChar);
- return;
- case SIF_PlainStringIntoUTF8Char:
- SetFailed(FK_PlainStringIntoUTF8Char);
- return;
- case SIF_UTF8StringIntoPlainChar:
- SetFailed(FK_UTF8StringIntoPlainChar);
- return;
- case SIF_Other:
- break;
- }
- }
- // Some kinds of initialization permit an array to be initialized from
- // another array of the same type, and perform elementwise initialization.
- if (Initializer && isa<ConstantArrayType>(DestAT) &&
- S.Context.hasSameUnqualifiedType(Initializer->getType(),
- Entity.getType()) &&
- canPerformArrayCopy(Entity)) {
- // If source is a prvalue, use it directly.
- if (Initializer->isPRValue()) {
- AddArrayInitStep(DestType, /*IsGNUExtension*/false);
- return;
- }
- // Emit element-at-a-time copy loop.
- InitializedEntity Element =
- InitializedEntity::InitializeElement(S.Context, 0, Entity);
- QualType InitEltT =
- Context.getAsArrayType(Initializer->getType())->getElementType();
- OpaqueValueExpr OVE(Initializer->getExprLoc(), InitEltT,
- Initializer->getValueKind(),
- Initializer->getObjectKind());
- Expr *OVEAsExpr = &OVE;
- InitializeFrom(S, Element, Kind, OVEAsExpr, TopLevelOfInitList,
- TreatUnavailableAsInvalid);
- if (!Failed())
- AddArrayInitLoopStep(Entity.getType(), InitEltT);
- return;
- }
- // Note: as an GNU C extension, we allow initialization of an
- // array from a compound literal that creates an array of the same
- // type, so long as the initializer has no side effects.
- if (!S.getLangOpts().CPlusPlus && Initializer &&
- isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) &&
- Initializer->getType()->isArrayType()) {
- const ArrayType *SourceAT
- = Context.getAsArrayType(Initializer->getType());
- if (!hasCompatibleArrayTypes(S.Context, DestAT, SourceAT))
- SetFailed(FK_ArrayTypeMismatch);
- else if (Initializer->HasSideEffects(S.Context))
- SetFailed(FK_NonConstantArrayInit);
- else {
- AddArrayInitStep(DestType, /*IsGNUExtension*/true);
- }
- }
- // Note: as a GNU C++ extension, we allow list-initialization of a
- // class member of array type from a parenthesized initializer list.
- else if (S.getLangOpts().CPlusPlus &&
- Entity.getKind() == InitializedEntity::EK_Member &&
- Initializer && isa<InitListExpr>(Initializer)) {
- TryListInitialization(S, Entity, Kind, cast<InitListExpr>(Initializer),
- *this, TreatUnavailableAsInvalid);
- AddParenthesizedArrayInitStep(DestType);
- } else if (S.getLangOpts().CPlusPlus20 && !TopLevelOfInitList &&
- Kind.getKind() == InitializationKind::IK_Direct)
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/true);
- else if (DestAT->getElementType()->isCharType())
- SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
- else if (IsWideCharCompatible(DestAT->getElementType(), Context))
- SetFailed(FK_ArrayNeedsInitListOrWideStringLiteral);
- else
- SetFailed(FK_ArrayNeedsInitList);
- return;
- }
- // Determine whether we should consider writeback conversions for
- // Objective-C ARC.
- bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount &&
- Entity.isParameterKind();
- if (TryOCLSamplerInitialization(S, *this, DestType, Initializer))
- return;
- // We're at the end of the line for C: it's either a write-back conversion
- // or it's a C assignment. There's no need to check anything else.
- if (!S.getLangOpts().CPlusPlus) {
- // If allowed, check whether this is an Objective-C writeback conversion.
- if (allowObjCWritebackConversion &&
- tryObjCWritebackConversion(S, *this, Entity, Initializer)) {
- return;
- }
- if (TryOCLZeroOpaqueTypeInitialization(S, *this, DestType, Initializer))
- return;
- // Handle initialization in C
- AddCAssignmentStep(DestType);
- MaybeProduceObjCObject(S, *this, Entity);
- return;
- }
- assert(S.getLangOpts().CPlusPlus);
- // - If the destination type is a (possibly cv-qualified) class type:
- if (DestType->isRecordType()) {
- // - If the initialization is direct-initialization, or if it is
- // copy-initialization where the cv-unqualified version of the
- // source type is the same class as, or a derived class of, the
- // class of the destination, constructors are considered. [...]
- if (Kind.getKind() == InitializationKind::IK_Direct ||
- (Kind.getKind() == InitializationKind::IK_Copy &&
- (Context.hasSameUnqualifiedType(SourceType, DestType) ||
- S.IsDerivedFrom(Initializer->getBeginLoc(), SourceType, DestType)))) {
- TryConstructorInitialization(S, Entity, Kind, Args, DestType, DestType,
- *this);
- // We fall back to the "no matching constructor" path if the
- // failed candidate set has functions other than the three default
- // constructors. For example, conversion function.
- if (const auto *RD =
- dyn_cast<CXXRecordDecl>(DestType->getAs<RecordType>()->getDecl());
- // In general, we should call isCompleteType for RD to check its
- // completeness, we don't call it here as it was already called in the
- // above TryConstructorInitialization.
- S.getLangOpts().CPlusPlus20 && RD && RD->hasDefinition() &&
- RD->isAggregate() && Failed() &&
- getFailureKind() == FK_ConstructorOverloadFailed) {
- // Do not attempt paren list initialization if overload resolution
- // resolves to a deleted function .
- //
- // We may reach this condition if we have a union wrapping a class with
- // a non-trivial copy or move constructor and we call one of those two
- // constructors. The union is an aggregate, but the matched constructor
- // is implicitly deleted, so we need to prevent aggregate initialization
- // (otherwise, it'll attempt aggregate initialization by initializing
- // the first element with a reference to the union).
- OverloadCandidateSet::iterator Best;
- OverloadingResult OR = getFailedCandidateSet().BestViableFunction(
- S, Kind.getLocation(), Best);
- if (OR != OverloadingResult::OR_Deleted) {
- // C++20 [dcl.init] 17.6.2.2:
- // - Otherwise, if no constructor is viable, the destination type is
- // an
- // aggregate class, and the initializer is a parenthesized
- // expression-list.
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/true);
- }
- }
- } else {
- // - Otherwise (i.e., for the remaining copy-initialization cases),
- // user-defined conversion sequences that can convert from the
- // source type to the destination type or (when a conversion
- // function is used) to a derived class thereof are enumerated as
- // described in 13.3.1.4, and the best one is chosen through
- // overload resolution (13.3).
- TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
- TopLevelOfInitList);
- }
- return;
- }
- assert(Args.size() >= 1 && "Zero-argument case handled above");
- // For HLSL ext vector types we allow list initialization behavior for C++
- // constructor syntax. This is accomplished by converting initialization
- // arguments an InitListExpr late.
- if (S.getLangOpts().HLSL && DestType->isExtVectorType() &&
- (SourceType.isNull() ||
- !Context.hasSameUnqualifiedType(SourceType, DestType))) {
- llvm::SmallVector<Expr *> InitArgs;
- for (auto *Arg : Args) {
- if (Arg->getType()->isExtVectorType()) {
- const auto *VTy = Arg->getType()->castAs<ExtVectorType>();
- unsigned Elm = VTy->getNumElements();
- for (unsigned Idx = 0; Idx < Elm; ++Idx) {
- InitArgs.emplace_back(new (Context) ArraySubscriptExpr(
- Arg,
- IntegerLiteral::Create(
- Context, llvm::APInt(Context.getIntWidth(Context.IntTy), Idx),
- Context.IntTy, SourceLocation()),
- VTy->getElementType(), Arg->getValueKind(), Arg->getObjectKind(),
- SourceLocation()));
- }
- } else
- InitArgs.emplace_back(Arg);
- }
- InitListExpr *ILE = new (Context) InitListExpr(
- S.getASTContext(), SourceLocation(), InitArgs, SourceLocation());
- Args[0] = ILE;
- AddListInitializationStep(DestType);
- return;
- }
- // The remaining cases all need a source type.
- if (Args.size() > 1) {
- SetFailed(FK_TooManyInitsForScalar);
- return;
- } else if (isa<InitListExpr>(Args[0])) {
- SetFailed(FK_ParenthesizedListInitForScalar);
- return;
- }
- // - Otherwise, if the source type is a (possibly cv-qualified) class
- // type, conversion functions are considered.
- if (!SourceType.isNull() && SourceType->isRecordType()) {
- // For a conversion to _Atomic(T) from either T or a class type derived
- // from T, initialize the T object then convert to _Atomic type.
- bool NeedAtomicConversion = false;
- if (const AtomicType *Atomic = DestType->getAs<AtomicType>()) {
- if (Context.hasSameUnqualifiedType(SourceType, Atomic->getValueType()) ||
- S.IsDerivedFrom(Initializer->getBeginLoc(), SourceType,
- Atomic->getValueType())) {
- DestType = Atomic->getValueType();
- NeedAtomicConversion = true;
- }
- }
- TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
- TopLevelOfInitList);
- MaybeProduceObjCObject(S, *this, Entity);
- if (!Failed() && NeedAtomicConversion)
- AddAtomicConversionStep(Entity.getType());
- return;
- }
- // - Otherwise, if the initialization is direct-initialization, the source
- // type is std::nullptr_t, and the destination type is bool, the initial
- // value of the object being initialized is false.
- if (!SourceType.isNull() && SourceType->isNullPtrType() &&
- DestType->isBooleanType() &&
- Kind.getKind() == InitializationKind::IK_Direct) {
- AddConversionSequenceStep(
- ImplicitConversionSequence::getNullptrToBool(SourceType, DestType,
- Initializer->isGLValue()),
- DestType);
- return;
- }
- // - Otherwise, the initial value of the object being initialized is the
- // (possibly converted) value of the initializer expression. Standard
- // conversions (Clause 4) will be used, if necessary, to convert the
- // initializer expression to the cv-unqualified version of the
- // destination type; no user-defined conversions are considered.
- ImplicitConversionSequence ICS
- = S.TryImplicitConversion(Initializer, DestType,
- /*SuppressUserConversions*/true,
- Sema::AllowedExplicit::None,
- /*InOverloadResolution*/ false,
- /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
- allowObjCWritebackConversion);
- if (ICS.isStandard() &&
- ICS.Standard.Second == ICK_Writeback_Conversion) {
- // Objective-C ARC writeback conversion.
- // We should copy unless we're passing to an argument explicitly
- // marked 'out'.
- bool ShouldCopy = true;
- if (ParmVarDecl *Param = cast_or_null<ParmVarDecl>(Entity.getDecl()))
- ShouldCopy = (Param->getObjCDeclQualifier() != ParmVarDecl::OBJC_TQ_Out);
- // If there was an lvalue adjustment, add it as a separate conversion.
- if (ICS.Standard.First == ICK_Array_To_Pointer ||
- ICS.Standard.First == ICK_Lvalue_To_Rvalue) {
- ImplicitConversionSequence LvalueICS;
- LvalueICS.setStandard();
- LvalueICS.Standard.setAsIdentityConversion();
- LvalueICS.Standard.setAllToTypes(ICS.Standard.getToType(0));
- LvalueICS.Standard.First = ICS.Standard.First;
- AddConversionSequenceStep(LvalueICS, ICS.Standard.getToType(0));
- }
- AddPassByIndirectCopyRestoreStep(DestType, ShouldCopy);
- } else if (ICS.isBad()) {
- DeclAccessPair dap;
- if (isLibstdcxxPointerReturnFalseHack(S, Entity, Initializer)) {
- AddZeroInitializationStep(Entity.getType());
- } else if (Initializer->getType() == Context.OverloadTy &&
- !S.ResolveAddressOfOverloadedFunction(Initializer, DestType,
- false, dap))
- SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
- else if (Initializer->getType()->isFunctionType() &&
- isExprAnUnaddressableFunction(S, Initializer))
- SetFailed(InitializationSequence::FK_AddressOfUnaddressableFunction);
- else
- SetFailed(InitializationSequence::FK_ConversionFailed);
- } else {
- AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
- MaybeProduceObjCObject(S, *this, Entity);
- }
- }
- InitializationSequence::~InitializationSequence() {
- for (auto &S : Steps)
- S.Destroy();
- }
- //===----------------------------------------------------------------------===//
- // Perform initialization
- //===----------------------------------------------------------------------===//
- static Sema::AssignmentAction
- getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) {
- switch(Entity.getKind()) {
- case InitializedEntity::EK_Variable:
- case InitializedEntity::EK_New:
- case InitializedEntity::EK_Exception:
- case InitializedEntity::EK_Base:
- case InitializedEntity::EK_Delegating:
- return Sema::AA_Initializing;
- case InitializedEntity::EK_Parameter:
- if (Entity.getDecl() &&
- isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
- return Sema::AA_Sending;
- return Sema::AA_Passing;
- case InitializedEntity::EK_Parameter_CF_Audited:
- if (Entity.getDecl() &&
- isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
- return Sema::AA_Sending;
- return !Diagnose ? Sema::AA_Passing : Sema::AA_Passing_CFAudited;
- case InitializedEntity::EK_Result:
- case InitializedEntity::EK_StmtExprResult: // FIXME: Not quite right.
- return Sema::AA_Returning;
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_RelatedResult:
- // FIXME: Can we tell apart casting vs. converting?
- return Sema::AA_Casting;
- case InitializedEntity::EK_TemplateParameter:
- // This is really initialization, but refer to it as conversion for
- // consistency with CheckConvertedConstantExpression.
- return Sema::AA_Converting;
- case InitializedEntity::EK_Member:
- case InitializedEntity::EK_Binding:
- case InitializedEntity::EK_ArrayElement:
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_LambdaCapture:
- case InitializedEntity::EK_CompoundLiteralInit:
- return Sema::AA_Initializing;
- }
- llvm_unreachable("Invalid EntityKind!");
- }
- /// Whether we should bind a created object as a temporary when
- /// initializing the given entity.
- static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
- switch (Entity.getKind()) {
- case InitializedEntity::EK_ArrayElement:
- case InitializedEntity::EK_Member:
- case InitializedEntity::EK_Result:
- case InitializedEntity::EK_StmtExprResult:
- case InitializedEntity::EK_New:
- case InitializedEntity::EK_Variable:
- case InitializedEntity::EK_Base:
- case InitializedEntity::EK_Delegating:
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- case InitializedEntity::EK_Exception:
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_LambdaCapture:
- case InitializedEntity::EK_CompoundLiteralInit:
- case InitializedEntity::EK_TemplateParameter:
- return false;
- case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_RelatedResult:
- case InitializedEntity::EK_Binding:
- return true;
- }
- llvm_unreachable("missed an InitializedEntity kind?");
- }
- /// Whether the given entity, when initialized with an object
- /// created for that initialization, requires destruction.
- static bool shouldDestroyEntity(const InitializedEntity &Entity) {
- switch (Entity.getKind()) {
- case InitializedEntity::EK_Result:
- case InitializedEntity::EK_StmtExprResult:
- case InitializedEntity::EK_New:
- case InitializedEntity::EK_Base:
- case InitializedEntity::EK_Delegating:
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_LambdaCapture:
- return false;
- case InitializedEntity::EK_Member:
- case InitializedEntity::EK_Binding:
- case InitializedEntity::EK_Variable:
- case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
- case InitializedEntity::EK_TemplateParameter:
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_ArrayElement:
- case InitializedEntity::EK_Exception:
- case InitializedEntity::EK_CompoundLiteralInit:
- case InitializedEntity::EK_RelatedResult:
- return true;
- }
- llvm_unreachable("missed an InitializedEntity kind?");
- }
- /// Get the location at which initialization diagnostics should appear.
- static SourceLocation getInitializationLoc(const InitializedEntity &Entity,
- Expr *Initializer) {
- switch (Entity.getKind()) {
- case InitializedEntity::EK_Result:
- case InitializedEntity::EK_StmtExprResult:
- return Entity.getReturnLoc();
- case InitializedEntity::EK_Exception:
- return Entity.getThrowLoc();
- case InitializedEntity::EK_Variable:
- case InitializedEntity::EK_Binding:
- return Entity.getDecl()->getLocation();
- case InitializedEntity::EK_LambdaCapture:
- return Entity.getCaptureLoc();
- case InitializedEntity::EK_ArrayElement:
- case InitializedEntity::EK_Member:
- case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
- case InitializedEntity::EK_TemplateParameter:
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_New:
- case InitializedEntity::EK_Base:
- case InitializedEntity::EK_Delegating:
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_CompoundLiteralInit:
- case InitializedEntity::EK_RelatedResult:
- return Initializer->getBeginLoc();
- }
- llvm_unreachable("missed an InitializedEntity kind?");
- }
- /// Make a (potentially elidable) temporary copy of the object
- /// provided by the given initializer by calling the appropriate copy
- /// constructor.
- ///
- /// \param S The Sema object used for type-checking.
- ///
- /// \param T The type of the temporary object, which must either be
- /// the type of the initializer expression or a superclass thereof.
- ///
- /// \param Entity The entity being initialized.
- ///
- /// \param CurInit The initializer expression.
- ///
- /// \param IsExtraneousCopy Whether this is an "extraneous" copy that
- /// is permitted in C++03 (but not C++0x) when binding a reference to
- /// an rvalue.
- ///
- /// \returns An expression that copies the initializer expression into
- /// a temporary object, or an error expression if a copy could not be
- /// created.
- static ExprResult CopyObject(Sema &S,
- QualType T,
- const InitializedEntity &Entity,
- ExprResult CurInit,
- bool IsExtraneousCopy) {
- if (CurInit.isInvalid())
- return CurInit;
- // Determine which class type we're copying to.
- Expr *CurInitExpr = (Expr *)CurInit.get();
- CXXRecordDecl *Class = nullptr;
- if (const RecordType *Record = T->getAs<RecordType>())
- Class = cast<CXXRecordDecl>(Record->getDecl());
- if (!Class)
- return CurInit;
- SourceLocation Loc = getInitializationLoc(Entity, CurInit.get());
- // Make sure that the type we are copying is complete.
- if (S.RequireCompleteType(Loc, T, diag::err_temp_copy_incomplete))
- return CurInit;
- // Perform overload resolution using the class's constructors. Per
- // C++11 [dcl.init]p16, second bullet for class types, this initialization
- // is direct-initialization.
- OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
- DeclContext::lookup_result Ctors = S.LookupConstructors(Class);
- OverloadCandidateSet::iterator Best;
- switch (ResolveConstructorOverload(
- S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best,
- /*CopyInitializing=*/false, /*AllowExplicit=*/true,
- /*OnlyListConstructors=*/false, /*IsListInit=*/false,
- /*SecondStepOfCopyInit=*/true)) {
- case OR_Success:
- break;
- case OR_No_Viable_Function:
- CandidateSet.NoteCandidates(
- PartialDiagnosticAt(
- Loc, S.PDiag(IsExtraneousCopy && !S.isSFINAEContext()
- ? diag::ext_rvalue_to_reference_temp_copy_no_viable
- : diag::err_temp_copy_no_viable)
- << (int)Entity.getKind() << CurInitExpr->getType()
- << CurInitExpr->getSourceRange()),
- S, OCD_AllCandidates, CurInitExpr);
- if (!IsExtraneousCopy || S.isSFINAEContext())
- return ExprError();
- return CurInit;
- case OR_Ambiguous:
- CandidateSet.NoteCandidates(
- PartialDiagnosticAt(Loc, S.PDiag(diag::err_temp_copy_ambiguous)
- << (int)Entity.getKind()
- << CurInitExpr->getType()
- << CurInitExpr->getSourceRange()),
- S, OCD_AmbiguousCandidates, CurInitExpr);
- return ExprError();
- case OR_Deleted:
- S.Diag(Loc, diag::err_temp_copy_deleted)
- << (int)Entity.getKind() << CurInitExpr->getType()
- << CurInitExpr->getSourceRange();
- S.NoteDeletedFunction(Best->Function);
- return ExprError();
- }
- bool HadMultipleCandidates = CandidateSet.size() > 1;
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
- SmallVector<Expr*, 8> ConstructorArgs;
- CurInit.get(); // Ownership transferred into MultiExprArg, below.
- S.CheckConstructorAccess(Loc, Constructor, Best->FoundDecl, Entity,
- IsExtraneousCopy);
- if (IsExtraneousCopy) {
- // If this is a totally extraneous copy for C++03 reference
- // binding purposes, just return the original initialization
- // expression. We don't generate an (elided) copy operation here
- // because doing so would require us to pass down a flag to avoid
- // infinite recursion, where each step adds another extraneous,
- // elidable copy.
- // Instantiate the default arguments of any extra parameters in
- // the selected copy constructor, as if we were going to create a
- // proper call to the copy constructor.
- for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {
- ParmVarDecl *Parm = Constructor->getParamDecl(I);
- if (S.RequireCompleteType(Loc, Parm->getType(),
- diag::err_call_incomplete_argument))
- break;
- // Build the default argument expression; we don't actually care
- // if this succeeds or not, because this routine will complain
- // if there was a problem.
- S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
- }
- return CurInitExpr;
- }
- // Determine the arguments required to actually perform the
- // constructor call (we might have derived-to-base conversions, or
- // the copy constructor may have default arguments).
- if (S.CompleteConstructorCall(Constructor, T, CurInitExpr, Loc,
- ConstructorArgs))
- return ExprError();
- // C++0x [class.copy]p32:
- // When certain criteria are met, an implementation is allowed to
- // omit the copy/move construction of a class object, even if the
- // copy/move constructor and/or destructor for the object have
- // side effects. [...]
- // - when a temporary class object that has not been bound to a
- // reference (12.2) would be copied/moved to a class object
- // with the same cv-unqualified type, the copy/move operation
- // can be omitted by constructing the temporary object
- // directly into the target of the omitted copy/move
- //
- // Note that the other three bullets are handled elsewhere. Copy
- // elision for return statements and throw expressions are handled as part
- // of constructor initialization, while copy elision for exception handlers
- // is handled by the run-time.
- //
- // FIXME: If the function parameter is not the same type as the temporary, we
- // should still be able to elide the copy, but we don't have a way to
- // represent in the AST how much should be elided in this case.
- bool Elidable =
- CurInitExpr->isTemporaryObject(S.Context, Class) &&
- S.Context.hasSameUnqualifiedType(
- Best->Function->getParamDecl(0)->getType().getNonReferenceType(),
- CurInitExpr->getType());
- // Actually perform the constructor call.
- CurInit = S.BuildCXXConstructExpr(Loc, T, Best->FoundDecl, Constructor,
- Elidable,
- ConstructorArgs,
- HadMultipleCandidates,
- /*ListInit*/ false,
- /*StdInitListInit*/ false,
- /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
- // If we're supposed to bind temporaries, do so.
- if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
- return CurInit;
- }
- /// Check whether elidable copy construction for binding a reference to
- /// a temporary would have succeeded if we were building in C++98 mode, for
- /// -Wc++98-compat.
- static void CheckCXX98CompatAccessibleCopy(Sema &S,
- const InitializedEntity &Entity,
- Expr *CurInitExpr) {
- assert(S.getLangOpts().CPlusPlus11);
- const RecordType *Record = CurInitExpr->getType()->getAs<RecordType>();
- if (!Record)
- return;
- SourceLocation Loc = getInitializationLoc(Entity, CurInitExpr);
- if (S.Diags.isIgnored(diag::warn_cxx98_compat_temp_copy, Loc))
- return;
- // Find constructors which would have been considered.
- OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
- DeclContext::lookup_result Ctors =
- S.LookupConstructors(cast<CXXRecordDecl>(Record->getDecl()));
- // Perform overload resolution.
- OverloadCandidateSet::iterator Best;
- OverloadingResult OR = ResolveConstructorOverload(
- S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best,
- /*CopyInitializing=*/false, /*AllowExplicit=*/true,
- /*OnlyListConstructors=*/false, /*IsListInit=*/false,
- /*SecondStepOfCopyInit=*/true);
- PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy)
- << OR << (int)Entity.getKind() << CurInitExpr->getType()
- << CurInitExpr->getSourceRange();
- switch (OR) {
- case OR_Success:
- S.CheckConstructorAccess(Loc, cast<CXXConstructorDecl>(Best->Function),
- Best->FoundDecl, Entity, Diag);
- // FIXME: Check default arguments as far as that's possible.
- break;
- case OR_No_Viable_Function:
- CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
- OCD_AllCandidates, CurInitExpr);
- break;
- case OR_Ambiguous:
- CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
- OCD_AmbiguousCandidates, CurInitExpr);
- break;
- case OR_Deleted:
- S.Diag(Loc, Diag);
- S.NoteDeletedFunction(Best->Function);
- break;
- }
- }
- void InitializationSequence::PrintInitLocationNote(Sema &S,
- const InitializedEntity &Entity) {
- if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) {
- if (Entity.getDecl()->getLocation().isInvalid())
- return;
- if (Entity.getDecl()->getDeclName())
- S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_named_here)
- << Entity.getDecl()->getDeclName();
- else
- S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here);
- }
- else if (Entity.getKind() == InitializedEntity::EK_RelatedResult &&
- Entity.getMethodDecl())
- S.Diag(Entity.getMethodDecl()->getLocation(),
- diag::note_method_return_type_change)
- << Entity.getMethodDecl()->getDeclName();
- }
- /// Returns true if the parameters describe a constructor initialization of
- /// an explicit temporary object, e.g. "Point(x, y)".
- static bool isExplicitTemporary(const InitializedEntity &Entity,
- const InitializationKind &Kind,
- unsigned NumArgs) {
- switch (Entity.getKind()) {
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_CompoundLiteralInit:
- case InitializedEntity::EK_RelatedResult:
- break;
- default:
- return false;
- }
- switch (Kind.getKind()) {
- case InitializationKind::IK_DirectList:
- return true;
- // FIXME: Hack to work around cast weirdness.
- case InitializationKind::IK_Direct:
- case InitializationKind::IK_Value:
- return NumArgs != 1;
- default:
- return false;
- }
- }
- static ExprResult
- PerformConstructorInitialization(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- const InitializationSequence::Step& Step,
- bool &ConstructorInitRequiresZeroInit,
- bool IsListInitialization,
- bool IsStdInitListInitialization,
- SourceLocation LBraceLoc,
- SourceLocation RBraceLoc) {
- unsigned NumArgs = Args.size();
- CXXConstructorDecl *Constructor
- = cast<CXXConstructorDecl>(Step.Function.Function);
- bool HadMultipleCandidates = Step.Function.HadMultipleCandidates;
- // Build a call to the selected constructor.
- SmallVector<Expr*, 8> ConstructorArgs;
- SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid())
- ? Kind.getEqualLoc()
- : Kind.getLocation();
- if (Kind.getKind() == InitializationKind::IK_Default) {
- // Force even a trivial, implicit default constructor to be
- // semantically checked. We do this explicitly because we don't build
- // the definition for completely trivial constructors.
- assert(Constructor->getParent() && "No parent class for constructor.");
- if (Constructor->isDefaulted() && Constructor->isDefaultConstructor() &&
- Constructor->isTrivial() && !Constructor->isUsed(false)) {
- S.runWithSufficientStackSpace(Loc, [&] {
- S.DefineImplicitDefaultConstructor(Loc, Constructor);
- });
- }
- }
- ExprResult CurInit((Expr *)nullptr);
- // C++ [over.match.copy]p1:
- // - When initializing a temporary to be bound to the first parameter
- // of a constructor that takes a reference to possibly cv-qualified
- // T as its first argument, called with a single argument in the
- // context of direct-initialization, explicit conversion functions
- // are also considered.
- bool AllowExplicitConv =
- Kind.AllowExplicit() && !Kind.isCopyInit() && Args.size() == 1 &&
- hasCopyOrMoveCtorParam(S.Context,
- getConstructorInfo(Step.Function.FoundDecl));
- // Determine the arguments required to actually perform the constructor
- // call.
- if (S.CompleteConstructorCall(Constructor, Step.Type, Args, Loc,
- ConstructorArgs, AllowExplicitConv,
- IsListInitialization))
- return ExprError();
- if (isExplicitTemporary(Entity, Kind, NumArgs)) {
- // An explicitly-constructed temporary, e.g., X(1, 2).
- if (S.DiagnoseUseOfDecl(Constructor, Loc))
- return ExprError();
- TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
- if (!TSInfo)
- TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc);
- SourceRange ParenOrBraceRange =
- (Kind.getKind() == InitializationKind::IK_DirectList)
- ? SourceRange(LBraceLoc, RBraceLoc)
- : Kind.getParenOrBraceRange();
- CXXConstructorDecl *CalleeDecl = Constructor;
- if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(
- Step.Function.FoundDecl.getDecl())) {
- CalleeDecl = S.findInheritingConstructor(Loc, Constructor, Shadow);
- if (S.DiagnoseUseOfDecl(CalleeDecl, Loc))
- return ExprError();
- }
- S.MarkFunctionReferenced(Loc, CalleeDecl);
- CurInit = S.CheckForImmediateInvocation(
- CXXTemporaryObjectExpr::Create(
- S.Context, CalleeDecl,
- Entity.getType().getNonLValueExprType(S.Context), TSInfo,
- ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
- IsListInitialization, IsStdInitListInitialization,
- ConstructorInitRequiresZeroInit),
- CalleeDecl);
- } else {
- CXXConstructExpr::ConstructionKind ConstructKind =
- CXXConstructExpr::CK_Complete;
- if (Entity.getKind() == InitializedEntity::EK_Base) {
- ConstructKind = Entity.getBaseSpecifier()->isVirtual() ?
- CXXConstructExpr::CK_VirtualBase :
- CXXConstructExpr::CK_NonVirtualBase;
- } else if (Entity.getKind() == InitializedEntity::EK_Delegating) {
- ConstructKind = CXXConstructExpr::CK_Delegating;
- }
- // Only get the parenthesis or brace range if it is a list initialization or
- // direct construction.
- SourceRange ParenOrBraceRange;
- if (IsListInitialization)
- ParenOrBraceRange = SourceRange(LBraceLoc, RBraceLoc);
- else if (Kind.getKind() == InitializationKind::IK_Direct)
- ParenOrBraceRange = Kind.getParenOrBraceRange();
- // If the entity allows NRVO, mark the construction as elidable
- // unconditionally.
- if (Entity.allowsNRVO())
- CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
- Step.Function.FoundDecl,
- Constructor, /*Elidable=*/true,
- ConstructorArgs,
- HadMultipleCandidates,
- IsListInitialization,
- IsStdInitListInitialization,
- ConstructorInitRequiresZeroInit,
- ConstructKind,
- ParenOrBraceRange);
- else
- CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
- Step.Function.FoundDecl,
- Constructor,
- ConstructorArgs,
- HadMultipleCandidates,
- IsListInitialization,
- IsStdInitListInitialization,
- ConstructorInitRequiresZeroInit,
- ConstructKind,
- ParenOrBraceRange);
- }
- if (CurInit.isInvalid())
- return ExprError();
- // Only check access if all of that succeeded.
- S.CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
- if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
- return ExprError();
- if (const ArrayType *AT = S.Context.getAsArrayType(Entity.getType()))
- if (checkDestructorReference(S.Context.getBaseElementType(AT), Loc, S))
- return ExprError();
- if (shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.get());
- return CurInit;
- }
- namespace {
- enum LifetimeKind {
- /// The lifetime of a temporary bound to this entity ends at the end of the
- /// full-expression, and that's (probably) fine.
- LK_FullExpression,
- /// The lifetime of a temporary bound to this entity is extended to the
- /// lifeitme of the entity itself.
- LK_Extended,
- /// The lifetime of a temporary bound to this entity probably ends too soon,
- /// because the entity is allocated in a new-expression.
- LK_New,
- /// The lifetime of a temporary bound to this entity ends too soon, because
- /// the entity is a return object.
- LK_Return,
- /// The lifetime of a temporary bound to this entity ends too soon, because
- /// the entity is the result of a statement expression.
- LK_StmtExprResult,
- /// This is a mem-initializer: if it would extend a temporary (other than via
- /// a default member initializer), the program is ill-formed.
- LK_MemInitializer,
- };
- using LifetimeResult =
- llvm::PointerIntPair<const InitializedEntity *, 3, LifetimeKind>;
- }
- /// Determine the declaration which an initialized entity ultimately refers to,
- /// for the purpose of lifetime-extending a temporary bound to a reference in
- /// the initialization of \p Entity.
- static LifetimeResult getEntityLifetime(
- const InitializedEntity *Entity,
- const InitializedEntity *InitField = nullptr) {
- // C++11 [class.temporary]p5:
- switch (Entity->getKind()) {
- case InitializedEntity::EK_Variable:
- // The temporary [...] persists for the lifetime of the reference
- return {Entity, LK_Extended};
- case InitializedEntity::EK_Member:
- // For subobjects, we look at the complete object.
- if (Entity->getParent())
- return getEntityLifetime(Entity->getParent(), Entity);
- // except:
- // C++17 [class.base.init]p8:
- // A temporary expression bound to a reference member in a
- // mem-initializer is ill-formed.
- // C++17 [class.base.init]p11:
- // A temporary expression bound to a reference member from a
- // default member initializer is ill-formed.
- //
- // The context of p11 and its example suggest that it's only the use of a
- // default member initializer from a constructor that makes the program
- // ill-formed, not its mere existence, and that it can even be used by
- // aggregate initialization.
- return {Entity, Entity->isDefaultMemberInitializer() ? LK_Extended
- : LK_MemInitializer};
- case InitializedEntity::EK_Binding:
- // Per [dcl.decomp]p3, the binding is treated as a variable of reference
- // type.
- return {Entity, LK_Extended};
- case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
- // -- A temporary bound to a reference parameter in a function call
- // persists until the completion of the full-expression containing
- // the call.
- return {nullptr, LK_FullExpression};
- case InitializedEntity::EK_TemplateParameter:
- // FIXME: This will always be ill-formed; should we eagerly diagnose it here?
- return {nullptr, LK_FullExpression};
- case InitializedEntity::EK_Result:
- // -- The lifetime of a temporary bound to the returned value in a
- // function return statement is not extended; the temporary is
- // destroyed at the end of the full-expression in the return statement.
- return {nullptr, LK_Return};
- case InitializedEntity::EK_StmtExprResult:
- // FIXME: Should we lifetime-extend through the result of a statement
- // expression?
- return {nullptr, LK_StmtExprResult};
- case InitializedEntity::EK_New:
- // -- A temporary bound to a reference in a new-initializer persists
- // until the completion of the full-expression containing the
- // new-initializer.
- return {nullptr, LK_New};
- case InitializedEntity::EK_Temporary:
- case InitializedEntity::EK_CompoundLiteralInit:
- case InitializedEntity::EK_RelatedResult:
- // We don't yet know the storage duration of the surrounding temporary.
- // Assume it's got full-expression duration for now, it will patch up our
- // storage duration if that's not correct.
- return {nullptr, LK_FullExpression};
- case InitializedEntity::EK_ArrayElement:
- // For subobjects, we look at the complete object.
- return getEntityLifetime(Entity->getParent(), InitField);
- case InitializedEntity::EK_Base:
- // For subobjects, we look at the complete object.
- if (Entity->getParent())
- return getEntityLifetime(Entity->getParent(), InitField);
- return {InitField, LK_MemInitializer};
- case InitializedEntity::EK_Delegating:
- // We can reach this case for aggregate initialization in a constructor:
- // struct A { int &&r; };
- // struct B : A { B() : A{0} {} };
- // In this case, use the outermost field decl as the context.
- return {InitField, LK_MemInitializer};
- case InitializedEntity::EK_BlockElement:
- case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
- case InitializedEntity::EK_LambdaCapture:
- case InitializedEntity::EK_VectorElement:
- case InitializedEntity::EK_ComplexElement:
- return {nullptr, LK_FullExpression};
- case InitializedEntity::EK_Exception:
- // FIXME: Can we diagnose lifetime problems with exceptions?
- return {nullptr, LK_FullExpression};
- }
- llvm_unreachable("unknown entity kind");
- }
- namespace {
- enum ReferenceKind {
- /// Lifetime would be extended by a reference binding to a temporary.
- RK_ReferenceBinding,
- /// Lifetime would be extended by a std::initializer_list object binding to
- /// its backing array.
- RK_StdInitializerList,
- };
- /// A temporary or local variable. This will be one of:
- /// * A MaterializeTemporaryExpr.
- /// * A DeclRefExpr whose declaration is a local.
- /// * An AddrLabelExpr.
- /// * A BlockExpr for a block with captures.
- using Local = Expr*;
- /// Expressions we stepped over when looking for the local state. Any steps
- /// that would inhibit lifetime extension or take us out of subexpressions of
- /// the initializer are included.
- struct IndirectLocalPathEntry {
- enum EntryKind {
- DefaultInit,
- AddressOf,
- VarInit,
- LValToRVal,
- LifetimeBoundCall,
- TemporaryCopy,
- LambdaCaptureInit,
- GslReferenceInit,
- GslPointerInit
- } Kind;
- Expr *E;
- union {
- const Decl *D = nullptr;
- const LambdaCapture *Capture;
- };
- IndirectLocalPathEntry() {}
- IndirectLocalPathEntry(EntryKind K, Expr *E) : Kind(K), E(E) {}
- IndirectLocalPathEntry(EntryKind K, Expr *E, const Decl *D)
- : Kind(K), E(E), D(D) {}
- IndirectLocalPathEntry(EntryKind K, Expr *E, const LambdaCapture *Capture)
- : Kind(K), E(E), Capture(Capture) {}
- };
- using IndirectLocalPath = llvm::SmallVectorImpl<IndirectLocalPathEntry>;
- struct RevertToOldSizeRAII {
- IndirectLocalPath &Path;
- unsigned OldSize = Path.size();
- RevertToOldSizeRAII(IndirectLocalPath &Path) : Path(Path) {}
- ~RevertToOldSizeRAII() { Path.resize(OldSize); }
- };
- using LocalVisitor = llvm::function_ref<bool(IndirectLocalPath &Path, Local L,
- ReferenceKind RK)>;
- }
- static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD) {
- for (auto E : Path)
- if (E.Kind == IndirectLocalPathEntry::VarInit && E.D == VD)
- return true;
- return false;
- }
- static bool pathContainsInit(IndirectLocalPath &Path) {
- return llvm::any_of(Path, [=](IndirectLocalPathEntry E) {
- return E.Kind == IndirectLocalPathEntry::DefaultInit ||
- E.Kind == IndirectLocalPathEntry::VarInit;
- });
- }
- static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
- Expr *Init, LocalVisitor Visit,
- bool RevisitSubinits,
- bool EnableLifetimeWarnings);
- static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
- Expr *Init, ReferenceKind RK,
- LocalVisitor Visit,
- bool EnableLifetimeWarnings);
- template <typename T> static bool isRecordWithAttr(QualType Type) {
- if (auto *RD = Type->getAsCXXRecordDecl())
- return RD->hasAttr<T>();
- return false;
- }
- // Decl::isInStdNamespace will return false for iterators in some STL
- // implementations due to them being defined in a namespace outside of the std
- // namespace.
- static bool isInStlNamespace(const Decl *D) {
- const DeclContext *DC = D->getDeclContext();
- if (!DC)
- return false;
- if (const auto *ND = dyn_cast<NamespaceDecl>(DC))
- if (const IdentifierInfo *II = ND->getIdentifier()) {
- StringRef Name = II->getName();
- if (Name.size() >= 2 && Name.front() == '_' &&
- (Name[1] == '_' || isUppercase(Name[1])))
- return true;
- }
- return DC->isStdNamespace();
- }
- static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
- if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
- if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
- return true;
- if (!isInStlNamespace(Callee->getParent()))
- return false;
- if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) &&
- !isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType()))
- return false;
- if (Callee->getReturnType()->isPointerType() ||
- isRecordWithAttr<PointerAttr>(Callee->getReturnType())) {
- if (!Callee->getIdentifier())
- return false;
- return llvm::StringSwitch<bool>(Callee->getName())
- .Cases("begin", "rbegin", "cbegin", "crbegin", true)
- .Cases("end", "rend", "cend", "crend", true)
- .Cases("c_str", "data", "get", true)
- // Map and set types.
- .Cases("find", "equal_range", "lower_bound", "upper_bound", true)
- .Default(false);
- } else if (Callee->getReturnType()->isReferenceType()) {
- if (!Callee->getIdentifier()) {
- auto OO = Callee->getOverloadedOperator();
- return OO == OverloadedOperatorKind::OO_Subscript ||
- OO == OverloadedOperatorKind::OO_Star;
- }
- return llvm::StringSwitch<bool>(Callee->getName())
- .Cases("front", "back", "at", "top", "value", true)
- .Default(false);
- }
- return false;
- }
- static bool shouldTrackFirstArgument(const FunctionDecl *FD) {
- if (!FD->getIdentifier() || FD->getNumParams() != 1)
- return false;
- const auto *RD = FD->getParamDecl(0)->getType()->getPointeeCXXRecordDecl();
- if (!FD->isInStdNamespace() || !RD || !RD->isInStdNamespace())
- return false;
- if (!isRecordWithAttr<PointerAttr>(QualType(RD->getTypeForDecl(), 0)) &&
- !isRecordWithAttr<OwnerAttr>(QualType(RD->getTypeForDecl(), 0)))
- return false;
- if (FD->getReturnType()->isPointerType() ||
- isRecordWithAttr<PointerAttr>(FD->getReturnType())) {
- return llvm::StringSwitch<bool>(FD->getName())
- .Cases("begin", "rbegin", "cbegin", "crbegin", true)
- .Cases("end", "rend", "cend", "crend", true)
- .Case("data", true)
- .Default(false);
- } else if (FD->getReturnType()->isReferenceType()) {
- return llvm::StringSwitch<bool>(FD->getName())
- .Cases("get", "any_cast", true)
- .Default(false);
- }
- return false;
- }
- static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
- LocalVisitor Visit) {
- auto VisitPointerArg = [&](const Decl *D, Expr *Arg, bool Value) {
- // We are not interested in the temporary base objects of gsl Pointers:
- // Temp().ptr; // Here ptr might not dangle.
- if (isa<MemberExpr>(Arg->IgnoreImpCasts()))
- return;
- // Once we initialized a value with a reference, it can no longer dangle.
- if (!Value) {
- for (const IndirectLocalPathEntry &PE : llvm::reverse(Path)) {
- if (PE.Kind == IndirectLocalPathEntry::GslReferenceInit)
- continue;
- if (PE.Kind == IndirectLocalPathEntry::GslPointerInit)
- return;
- break;
- }
- }
- Path.push_back({Value ? IndirectLocalPathEntry::GslPointerInit
- : IndirectLocalPathEntry::GslReferenceInit,
- Arg, D});
- if (Arg->isGLValue())
- visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
- Visit,
- /*EnableLifetimeWarnings=*/true);
- else
- visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
- /*EnableLifetimeWarnings=*/true);
- Path.pop_back();
- };
- if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
- const auto *MD = cast_or_null<CXXMethodDecl>(MCE->getDirectCallee());
- if (MD && shouldTrackImplicitObjectArg(MD))
- VisitPointerArg(MD, MCE->getImplicitObjectArgument(),
- !MD->getReturnType()->isReferenceType());
- return;
- } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(Call)) {
- FunctionDecl *Callee = OCE->getDirectCallee();
- if (Callee && Callee->isCXXInstanceMember() &&
- shouldTrackImplicitObjectArg(cast<CXXMethodDecl>(Callee)))
- VisitPointerArg(Callee, OCE->getArg(0),
- !Callee->getReturnType()->isReferenceType());
- return;
- } else if (auto *CE = dyn_cast<CallExpr>(Call)) {
- FunctionDecl *Callee = CE->getDirectCallee();
- if (Callee && shouldTrackFirstArgument(Callee))
- VisitPointerArg(Callee, CE->getArg(0),
- !Callee->getReturnType()->isReferenceType());
- return;
- }
- if (auto *CCE = dyn_cast<CXXConstructExpr>(Call)) {
- const auto *Ctor = CCE->getConstructor();
- const CXXRecordDecl *RD = Ctor->getParent();
- if (CCE->getNumArgs() > 0 && RD->hasAttr<PointerAttr>())
- VisitPointerArg(Ctor->getParamDecl(0), CCE->getArgs()[0], true);
- }
- }
- static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
- const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
- if (!TSI)
- return false;
- // Don't declare this variable in the second operand of the for-statement;
- // GCC miscompiles that by ending its lifetime before evaluating the
- // third operand. See gcc.gnu.org/PR86769.
- AttributedTypeLoc ATL;
- for (TypeLoc TL = TSI->getTypeLoc();
- (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
- TL = ATL.getModifiedLoc()) {
- if (ATL.getAttrAs<LifetimeBoundAttr>())
- return true;
- }
- // Assume that all assignment operators with a "normal" return type return
- // *this, that is, an lvalue reference that is the same type as the implicit
- // object parameter (or the LHS for a non-member operator$=).
- OverloadedOperatorKind OO = FD->getDeclName().getCXXOverloadedOperator();
- if (OO == OO_Equal || isCompoundAssignmentOperator(OO)) {
- QualType RetT = FD->getReturnType();
- if (RetT->isLValueReferenceType()) {
- ASTContext &Ctx = FD->getASTContext();
- QualType LHST;
- auto *MD = dyn_cast<CXXMethodDecl>(FD);
- if (MD && MD->isCXXInstanceMember())
- LHST = Ctx.getLValueReferenceType(MD->getThisObjectType());
- else
- LHST = MD->getParamDecl(0)->getType();
- if (Ctx.hasSameType(RetT, LHST))
- return true;
- }
- }
- return false;
- }
- static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
- LocalVisitor Visit) {
- const FunctionDecl *Callee;
- ArrayRef<Expr*> Args;
- if (auto *CE = dyn_cast<CallExpr>(Call)) {
- Callee = CE->getDirectCallee();
- Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs());
- } else {
- auto *CCE = cast<CXXConstructExpr>(Call);
- Callee = CCE->getConstructor();
- Args = llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs());
- }
- if (!Callee)
- return;
- Expr *ObjectArg = nullptr;
- if (isa<CXXOperatorCallExpr>(Call) && Callee->isCXXInstanceMember()) {
- ObjectArg = Args[0];
- Args = Args.slice(1);
- } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
- ObjectArg = MCE->getImplicitObjectArgument();
- }
- auto VisitLifetimeBoundArg = [&](const Decl *D, Expr *Arg) {
- Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D});
- if (Arg->isGLValue())
- visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
- Visit,
- /*EnableLifetimeWarnings=*/false);
- else
- visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
- /*EnableLifetimeWarnings=*/false);
- Path.pop_back();
- };
- if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
- VisitLifetimeBoundArg(Callee, ObjectArg);
- for (unsigned I = 0,
- N = std::min<unsigned>(Callee->getNumParams(), Args.size());
- I != N; ++I) {
- if (Callee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
- VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
- }
- }
- /// Visit the locals that would be reachable through a reference bound to the
- /// glvalue expression \c Init.
- static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
- Expr *Init, ReferenceKind RK,
- LocalVisitor Visit,
- bool EnableLifetimeWarnings) {
- RevertToOldSizeRAII RAII(Path);
- // Walk past any constructs which we can lifetime-extend across.
- Expr *Old;
- do {
- Old = Init;
- if (auto *FE = dyn_cast<FullExpr>(Init))
- Init = FE->getSubExpr();
- if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
- // If this is just redundant braces around an initializer, step over it.
- if (ILE->isTransparent())
- Init = ILE->getInit(0);
- }
- // Step over any subobject adjustments; we may have a materialized
- // temporary inside them.
- Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
- // Per current approach for DR1376, look through casts to reference type
- // when performing lifetime extension.
- if (CastExpr *CE = dyn_cast<CastExpr>(Init))
- if (CE->getSubExpr()->isGLValue())
- Init = CE->getSubExpr();
- // Per the current approach for DR1299, look through array element access
- // on array glvalues when performing lifetime extension.
- if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Init)) {
- Init = ASE->getBase();
- auto *ICE = dyn_cast<ImplicitCastExpr>(Init);
- if (ICE && ICE->getCastKind() == CK_ArrayToPointerDecay)
- Init = ICE->getSubExpr();
- else
- // We can't lifetime extend through this but we might still find some
- // retained temporaries.
- return visitLocalsRetainedByInitializer(Path, Init, Visit, true,
- EnableLifetimeWarnings);
- }
- // Step into CXXDefaultInitExprs so we can diagnose cases where a
- // constructor inherits one as an implicit mem-initializer.
- if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
- Path.push_back(
- {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
- Init = DIE->getExpr();
- }
- } while (Init != Old);
- if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) {
- if (Visit(Path, Local(MTE), RK))
- visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit, true,
- EnableLifetimeWarnings);
- }
- if (isa<CallExpr>(Init)) {
- if (EnableLifetimeWarnings)
- handleGslAnnotatedTypes(Path, Init, Visit);
- return visitLifetimeBoundArguments(Path, Init, Visit);
- }
- switch (Init->getStmtClass()) {
- case Stmt::DeclRefExprClass: {
- // If we find the name of a local non-reference parameter, we could have a
- // lifetime problem.
- auto *DRE = cast<DeclRefExpr>(Init);
- auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
- if (VD && VD->hasLocalStorage() &&
- !DRE->refersToEnclosingVariableOrCapture()) {
- if (!VD->getType()->isReferenceType()) {
- Visit(Path, Local(DRE), RK);
- } else if (isa<ParmVarDecl>(DRE->getDecl())) {
- // The lifetime of a reference parameter is unknown; assume it's OK
- // for now.
- break;
- } else if (VD->getInit() && !isVarOnPath(Path, VD)) {
- Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
- visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
- RK_ReferenceBinding, Visit,
- EnableLifetimeWarnings);
- }
- }
- break;
- }
- case Stmt::UnaryOperatorClass: {
- // The only unary operator that make sense to handle here
- // is Deref. All others don't resolve to a "name." This includes
- // handling all sorts of rvalues passed to a unary operator.
- const UnaryOperator *U = cast<UnaryOperator>(Init);
- if (U->getOpcode() == UO_Deref)
- visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true,
- EnableLifetimeWarnings);
- break;
- }
- case Stmt::OMPArraySectionExprClass: {
- visitLocalsRetainedByInitializer(Path,
- cast<OMPArraySectionExpr>(Init)->getBase(),
- Visit, true, EnableLifetimeWarnings);
- break;
- }
- case Stmt::ConditionalOperatorClass:
- case Stmt::BinaryConditionalOperatorClass: {
- auto *C = cast<AbstractConditionalOperator>(Init);
- if (!C->getTrueExpr()->getType()->isVoidType())
- visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit,
- EnableLifetimeWarnings);
- if (!C->getFalseExpr()->getType()->isVoidType())
- visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit,
- EnableLifetimeWarnings);
- break;
- }
- // FIXME: Visit the left-hand side of an -> or ->*.
- default:
- break;
- }
- }
- /// Visit the locals that would be reachable through an object initialized by
- /// the prvalue expression \c Init.
- static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
- Expr *Init, LocalVisitor Visit,
- bool RevisitSubinits,
- bool EnableLifetimeWarnings) {
- RevertToOldSizeRAII RAII(Path);
- Expr *Old;
- do {
- Old = Init;
- // Step into CXXDefaultInitExprs so we can diagnose cases where a
- // constructor inherits one as an implicit mem-initializer.
- if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
- Path.push_back({IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
- Init = DIE->getExpr();
- }
- if (auto *FE = dyn_cast<FullExpr>(Init))
- Init = FE->getSubExpr();
- // Dig out the expression which constructs the extended temporary.
- Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
- if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
- Init = BTE->getSubExpr();
- Init = Init->IgnoreParens();
- // Step over value-preserving rvalue casts.
- if (auto *CE = dyn_cast<CastExpr>(Init)) {
- switch (CE->getCastKind()) {
- case CK_LValueToRValue:
- // If we can match the lvalue to a const object, we can look at its
- // initializer.
- Path.push_back({IndirectLocalPathEntry::LValToRVal, CE});
- return visitLocalsRetainedByReferenceBinding(
- Path, Init, RK_ReferenceBinding,
- [&](IndirectLocalPath &Path, Local L, ReferenceKind RK) -> bool {
- if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
- auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
- if (VD && VD->getType().isConstQualified() && VD->getInit() &&
- !isVarOnPath(Path, VD)) {
- Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
- visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, true,
- EnableLifetimeWarnings);
- }
- } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
- if (MTE->getType().isConstQualified())
- visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit,
- true, EnableLifetimeWarnings);
- }
- return false;
- }, EnableLifetimeWarnings);
- // We assume that objects can be retained by pointers cast to integers,
- // but not if the integer is cast to floating-point type or to _Complex.
- // We assume that casts to 'bool' do not preserve enough information to
- // retain a local object.
- case CK_NoOp:
- case CK_BitCast:
- case CK_BaseToDerived:
- case CK_DerivedToBase:
- case CK_UncheckedDerivedToBase:
- case CK_Dynamic:
- case CK_ToUnion:
- case CK_UserDefinedConversion:
- case CK_ConstructorConversion:
- case CK_IntegralToPointer:
- case CK_PointerToIntegral:
- case CK_VectorSplat:
- case CK_IntegralCast:
- case CK_CPointerToObjCPointerCast:
- case CK_BlockPointerToObjCPointerCast:
- case CK_AnyPointerToBlockPointerCast:
- case CK_AddressSpaceConversion:
- break;
- case CK_ArrayToPointerDecay:
- // Model array-to-pointer decay as taking the address of the array
- // lvalue.
- Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
- return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(),
- RK_ReferenceBinding, Visit,
- EnableLifetimeWarnings);
- default:
- return;
- }
- Init = CE->getSubExpr();
- }
- } while (Old != Init);
- // C++17 [dcl.init.list]p6:
- // initializing an initializer_list object from the array extends the
- // lifetime of the array exactly like binding a reference to a temporary.
- if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init))
- return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(),
- RK_StdInitializerList, Visit,
- EnableLifetimeWarnings);
- if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
- // We already visited the elements of this initializer list while
- // performing the initialization. Don't visit them again unless we've
- // changed the lifetime of the initialized entity.
- if (!RevisitSubinits)
- return;
- if (ILE->isTransparent())
- return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit,
- RevisitSubinits,
- EnableLifetimeWarnings);
- if (ILE->getType()->isArrayType()) {
- for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
- visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit,
- RevisitSubinits,
- EnableLifetimeWarnings);
- return;
- }
- if (CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl()) {
- assert(RD->isAggregate() && "aggregate init on non-aggregate");
- // If we lifetime-extend a braced initializer which is initializing an
- // aggregate, and that aggregate contains reference members which are
- // bound to temporaries, those temporaries are also lifetime-extended.
- if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
- ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
- visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0),
- RK_ReferenceBinding, Visit,
- EnableLifetimeWarnings);
- else {
- unsigned Index = 0;
- for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index)
- visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit,
- RevisitSubinits,
- EnableLifetimeWarnings);
- for (const auto *I : RD->fields()) {
- if (Index >= ILE->getNumInits())
- break;
- if (I->isUnnamedBitfield())
- continue;
- Expr *SubInit = ILE->getInit(Index);
- if (I->getType()->isReferenceType())
- visitLocalsRetainedByReferenceBinding(Path, SubInit,
- RK_ReferenceBinding, Visit,
- EnableLifetimeWarnings);
- else
- // This might be either aggregate-initialization of a member or
- // initialization of a std::initializer_list object. Regardless,
- // we should recursively lifetime-extend that initializer.
- visitLocalsRetainedByInitializer(Path, SubInit, Visit,
- RevisitSubinits,
- EnableLifetimeWarnings);
- ++Index;
- }
- }
- }
- return;
- }
- // The lifetime of an init-capture is that of the closure object constructed
- // by a lambda-expression.
- if (auto *LE = dyn_cast<LambdaExpr>(Init)) {
- LambdaExpr::capture_iterator CapI = LE->capture_begin();
- for (Expr *E : LE->capture_inits()) {
- assert(CapI != LE->capture_end());
- const LambdaCapture &Cap = *CapI++;
- if (!E)
- continue;
- if (Cap.capturesVariable())
- Path.push_back({IndirectLocalPathEntry::LambdaCaptureInit, E, &Cap});
- if (E->isGLValue())
- visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
- Visit, EnableLifetimeWarnings);
- else
- visitLocalsRetainedByInitializer(Path, E, Visit, true,
- EnableLifetimeWarnings);
- if (Cap.capturesVariable())
- Path.pop_back();
- }
- }
- // Assume that a copy or move from a temporary references the same objects
- // that the temporary does.
- if (auto *CCE = dyn_cast<CXXConstructExpr>(Init)) {
- if (CCE->getConstructor()->isCopyOrMoveConstructor()) {
- if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CCE->getArg(0))) {
- Expr *Arg = MTE->getSubExpr();
- Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg,
- CCE->getConstructor()});
- visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
- /*EnableLifetimeWarnings*/false);
- Path.pop_back();
- }
- }
- }
- if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) {
- if (EnableLifetimeWarnings)
- handleGslAnnotatedTypes(Path, Init, Visit);
- return visitLifetimeBoundArguments(Path, Init, Visit);
- }
- switch (Init->getStmtClass()) {
- case Stmt::UnaryOperatorClass: {
- auto *UO = cast<UnaryOperator>(Init);
- // If the initializer is the address of a local, we could have a lifetime
- // problem.
- if (UO->getOpcode() == UO_AddrOf) {
- // If this is &rvalue, then it's ill-formed and we have already diagnosed
- // it. Don't produce a redundant warning about the lifetime of the
- // temporary.
- if (isa<MaterializeTemporaryExpr>(UO->getSubExpr()))
- return;
- Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
- visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
- RK_ReferenceBinding, Visit,
- EnableLifetimeWarnings);
- }
- break;
- }
- case Stmt::BinaryOperatorClass: {
- // Handle pointer arithmetic.
- auto *BO = cast<BinaryOperator>(Init);
- BinaryOperatorKind BOK = BO->getOpcode();
- if (!BO->getType()->isPointerType() || (BOK != BO_Add && BOK != BO_Sub))
- break;
- if (BO->getLHS()->getType()->isPointerType())
- visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true,
- EnableLifetimeWarnings);
- else if (BO->getRHS()->getType()->isPointerType())
- visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true,
- EnableLifetimeWarnings);
- break;
- }
- case Stmt::ConditionalOperatorClass:
- case Stmt::BinaryConditionalOperatorClass: {
- auto *C = cast<AbstractConditionalOperator>(Init);
- // In C++, we can have a throw-expression operand, which has 'void' type
- // and isn't interesting from a lifetime perspective.
- if (!C->getTrueExpr()->getType()->isVoidType())
- visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true,
- EnableLifetimeWarnings);
- if (!C->getFalseExpr()->getType()->isVoidType())
- visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true,
- EnableLifetimeWarnings);
- break;
- }
- case Stmt::BlockExprClass:
- if (cast<BlockExpr>(Init)->getBlockDecl()->hasCaptures()) {
- // This is a local block, whose lifetime is that of the function.
- Visit(Path, Local(cast<BlockExpr>(Init)), RK_ReferenceBinding);
- }
- break;
- case Stmt::AddrLabelExprClass:
- // We want to warn if the address of a label would escape the function.
- Visit(Path, Local(cast<AddrLabelExpr>(Init)), RK_ReferenceBinding);
- break;
- default:
- break;
- }
- }
- /// Whether a path to an object supports lifetime extension.
- enum PathLifetimeKind {
- /// Lifetime-extend along this path.
- Extend,
- /// We should lifetime-extend, but we don't because (due to technical
- /// limitations) we can't. This happens for default member initializers,
- /// which we don't clone for every use, so we don't have a unique
- /// MaterializeTemporaryExpr to update.
- ShouldExtend,
- /// Do not lifetime extend along this path.
- NoExtend
- };
- /// Determine whether this is an indirect path to a temporary that we are
- /// supposed to lifetime-extend along.
- static PathLifetimeKind
- shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) {
- PathLifetimeKind Kind = PathLifetimeKind::Extend;
- for (auto Elem : Path) {
- if (Elem.Kind == IndirectLocalPathEntry::DefaultInit)
- Kind = PathLifetimeKind::ShouldExtend;
- else if (Elem.Kind != IndirectLocalPathEntry::LambdaCaptureInit)
- return PathLifetimeKind::NoExtend;
- }
- return Kind;
- }
- /// Find the range for the first interesting entry in the path at or after I.
- static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I,
- Expr *E) {
- for (unsigned N = Path.size(); I != N; ++I) {
- switch (Path[I].Kind) {
- case IndirectLocalPathEntry::AddressOf:
- case IndirectLocalPathEntry::LValToRVal:
- case IndirectLocalPathEntry::LifetimeBoundCall:
- case IndirectLocalPathEntry::TemporaryCopy:
- case IndirectLocalPathEntry::GslReferenceInit:
- case IndirectLocalPathEntry::GslPointerInit:
- // These exist primarily to mark the path as not permitting or
- // supporting lifetime extension.
- break;
- case IndirectLocalPathEntry::VarInit:
- if (cast<VarDecl>(Path[I].D)->isImplicit())
- return SourceRange();
- [[fallthrough]];
- case IndirectLocalPathEntry::DefaultInit:
- return Path[I].E->getSourceRange();
- case IndirectLocalPathEntry::LambdaCaptureInit:
- if (!Path[I].Capture->capturesVariable())
- continue;
- return Path[I].E->getSourceRange();
- }
- }
- return E->getSourceRange();
- }
- static bool pathOnlyInitializesGslPointer(IndirectLocalPath &Path) {
- for (const auto &It : llvm::reverse(Path)) {
- if (It.Kind == IndirectLocalPathEntry::VarInit)
- continue;
- if (It.Kind == IndirectLocalPathEntry::AddressOf)
- continue;
- if (It.Kind == IndirectLocalPathEntry::LifetimeBoundCall)
- continue;
- return It.Kind == IndirectLocalPathEntry::GslPointerInit ||
- It.Kind == IndirectLocalPathEntry::GslReferenceInit;
- }
- return false;
- }
- void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
- Expr *Init) {
- LifetimeResult LR = getEntityLifetime(&Entity);
- LifetimeKind LK = LR.getInt();
- const InitializedEntity *ExtendingEntity = LR.getPointer();
- // If this entity doesn't have an interesting lifetime, don't bother looking
- // for temporaries within its initializer.
- if (LK == LK_FullExpression)
- return;
- auto TemporaryVisitor = [&](IndirectLocalPath &Path, Local L,
- ReferenceKind RK) -> bool {
- SourceRange DiagRange = nextPathEntryRange(Path, 0, L);
- SourceLocation DiagLoc = DiagRange.getBegin();
- auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
- bool IsGslPtrInitWithGslTempOwner = false;
- bool IsLocalGslOwner = false;
- if (pathOnlyInitializesGslPointer(Path)) {
- if (isa<DeclRefExpr>(L)) {
- // We do not want to follow the references when returning a pointer originating
- // from a local owner to avoid the following false positive:
- // int &p = *localUniquePtr;
- // someContainer.add(std::move(localUniquePtr));
- // return p;
- IsLocalGslOwner = isRecordWithAttr<OwnerAttr>(L->getType());
- if (pathContainsInit(Path) || !IsLocalGslOwner)
- return false;
- } else {
- IsGslPtrInitWithGslTempOwner = MTE && !MTE->getExtendingDecl() &&
- isRecordWithAttr<OwnerAttr>(MTE->getType());
- // Skipping a chain of initializing gsl::Pointer annotated objects.
- // We are looking only for the final source to find out if it was
- // a local or temporary owner or the address of a local variable/param.
- if (!IsGslPtrInitWithGslTempOwner)
- return true;
- }
- }
- switch (LK) {
- case LK_FullExpression:
- llvm_unreachable("already handled this");
- case LK_Extended: {
- if (!MTE) {
- // The initialized entity has lifetime beyond the full-expression,
- // and the local entity does too, so don't warn.
- //
- // FIXME: We should consider warning if a static / thread storage
- // duration variable retains an automatic storage duration local.
- return false;
- }
- if (IsGslPtrInitWithGslTempOwner && DiagLoc.isValid()) {
- Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange;
- return false;
- }
- switch (shouldLifetimeExtendThroughPath(Path)) {
- case PathLifetimeKind::Extend:
- // Update the storage duration of the materialized temporary.
- // FIXME: Rebuild the expression instead of mutating it.
- MTE->setExtendingDecl(ExtendingEntity->getDecl(),
- ExtendingEntity->allocateManglingNumber());
- // Also visit the temporaries lifetime-extended by this initializer.
- return true;
- case PathLifetimeKind::ShouldExtend:
- // We're supposed to lifetime-extend the temporary along this path (per
- // the resolution of DR1815), but we don't support that yet.
- //
- // FIXME: Properly handle this situation. Perhaps the easiest approach
- // would be to clone the initializer expression on each use that would
- // lifetime extend its temporaries.
- Diag(DiagLoc, diag::warn_unsupported_lifetime_extension)
- << RK << DiagRange;
- break;
- case PathLifetimeKind::NoExtend:
- // If the path goes through the initialization of a variable or field,
- // it can't possibly reach a temporary created in this full-expression.
- // We will have already diagnosed any problems with the initializer.
- if (pathContainsInit(Path))
- return false;
- Diag(DiagLoc, diag::warn_dangling_variable)
- << RK << !Entity.getParent()
- << ExtendingEntity->getDecl()->isImplicit()
- << ExtendingEntity->getDecl() << Init->isGLValue() << DiagRange;
- break;
- }
- break;
- }
- case LK_MemInitializer: {
- if (isa<MaterializeTemporaryExpr>(L)) {
- // Under C++ DR1696, if a mem-initializer (or a default member
- // initializer used by the absence of one) would lifetime-extend a
- // temporary, the program is ill-formed.
- if (auto *ExtendingDecl =
- ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
- if (IsGslPtrInitWithGslTempOwner) {
- Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member)
- << ExtendingDecl << DiagRange;
- Diag(ExtendingDecl->getLocation(),
- diag::note_ref_or_ptr_member_declared_here)
- << true;
- return false;
- }
- bool IsSubobjectMember = ExtendingEntity != &Entity;
- Diag(DiagLoc, shouldLifetimeExtendThroughPath(Path) !=
- PathLifetimeKind::NoExtend
- ? diag::err_dangling_member
- : diag::warn_dangling_member)
- << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
- // Don't bother adding a note pointing to the field if we're inside
- // its default member initializer; our primary diagnostic points to
- // the same place in that case.
- if (Path.empty() ||
- Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
- Diag(ExtendingDecl->getLocation(),
- diag::note_lifetime_extending_member_declared_here)
- << RK << IsSubobjectMember;
- }
- } else {
- // We have a mem-initializer but no particular field within it; this
- // is either a base class or a delegating initializer directly
- // initializing the base-class from something that doesn't live long
- // enough.
- //
- // FIXME: Warn on this.
- return false;
- }
- } else {
- // Paths via a default initializer can only occur during error recovery
- // (there's no other way that a default initializer can refer to a
- // local). Don't produce a bogus warning on those cases.
- if (pathContainsInit(Path))
- return false;
- // Suppress false positives for code like the one below:
- // Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {}
- if (IsLocalGslOwner && pathOnlyInitializesGslPointer(Path))
- return false;
- auto *DRE = dyn_cast<DeclRefExpr>(L);
- auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
- if (!VD) {
- // A member was initialized to a local block.
- // FIXME: Warn on this.
- return false;
- }
- if (auto *Member =
- ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
- bool IsPointer = !Member->getType()->isReferenceType();
- Diag(DiagLoc, IsPointer ? diag::warn_init_ptr_member_to_parameter_addr
- : diag::warn_bind_ref_member_to_parameter)
- << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
- Diag(Member->getLocation(),
- diag::note_ref_or_ptr_member_declared_here)
- << (unsigned)IsPointer;
- }
- }
- break;
- }
- case LK_New:
- if (isa<MaterializeTemporaryExpr>(L)) {
- if (IsGslPtrInitWithGslTempOwner)
- Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange;
- else
- Diag(DiagLoc, RK == RK_ReferenceBinding
- ? diag::warn_new_dangling_reference
- : diag::warn_new_dangling_initializer_list)
- << !Entity.getParent() << DiagRange;
- } else {
- // We can't determine if the allocation outlives the local declaration.
- return false;
- }
- break;
- case LK_Return:
- case LK_StmtExprResult:
- if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
- // We can't determine if the local variable outlives the statement
- // expression.
- if (LK == LK_StmtExprResult)
- return false;
- Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
- << Entity.getType()->isReferenceType() << DRE->getDecl()
- << isa<ParmVarDecl>(DRE->getDecl()) << DiagRange;
- } else if (isa<BlockExpr>(L)) {
- Diag(DiagLoc, diag::err_ret_local_block) << DiagRange;
- } else if (isa<AddrLabelExpr>(L)) {
- // Don't warn when returning a label from a statement expression.
- // Leaving the scope doesn't end its lifetime.
- if (LK == LK_StmtExprResult)
- return false;
- Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
- } else {
- Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
- << Entity.getType()->isReferenceType() << DiagRange;
- }
- break;
- }
- for (unsigned I = 0; I != Path.size(); ++I) {
- auto Elem = Path[I];
- switch (Elem.Kind) {
- case IndirectLocalPathEntry::AddressOf:
- case IndirectLocalPathEntry::LValToRVal:
- // These exist primarily to mark the path as not permitting or
- // supporting lifetime extension.
- break;
- case IndirectLocalPathEntry::LifetimeBoundCall:
- case IndirectLocalPathEntry::TemporaryCopy:
- case IndirectLocalPathEntry::GslPointerInit:
- case IndirectLocalPathEntry::GslReferenceInit:
- // FIXME: Consider adding a note for these.
- break;
- case IndirectLocalPathEntry::DefaultInit: {
- auto *FD = cast<FieldDecl>(Elem.D);
- Diag(FD->getLocation(), diag::note_init_with_default_member_initalizer)
- << FD << nextPathEntryRange(Path, I + 1, L);
- break;
- }
- case IndirectLocalPathEntry::VarInit: {
- const VarDecl *VD = cast<VarDecl>(Elem.D);
- Diag(VD->getLocation(), diag::note_local_var_initializer)
- << VD->getType()->isReferenceType()
- << VD->isImplicit() << VD->getDeclName()
- << nextPathEntryRange(Path, I + 1, L);
- break;
- }
- case IndirectLocalPathEntry::LambdaCaptureInit:
- if (!Elem.Capture->capturesVariable())
- break;
- // FIXME: We can't easily tell apart an init-capture from a nested
- // capture of an init-capture.
- const ValueDecl *VD = Elem.Capture->getCapturedVar();
- Diag(Elem.Capture->getLocation(), diag::note_lambda_capture_initializer)
- << VD << VD->isInitCapture() << Elem.Capture->isExplicit()
- << (Elem.Capture->getCaptureKind() == LCK_ByRef) << VD
- << nextPathEntryRange(Path, I + 1, L);
- break;
- }
- }
- // We didn't lifetime-extend, so don't go any further; we don't need more
- // warnings or errors on inner temporaries within this one's initializer.
- return false;
- };
- bool EnableLifetimeWarnings = !getDiagnostics().isIgnored(
- diag::warn_dangling_lifetime_pointer, SourceLocation());
- llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
- if (Init->isGLValue())
- visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
- TemporaryVisitor,
- EnableLifetimeWarnings);
- else
- visitLocalsRetainedByInitializer(Path, Init, TemporaryVisitor, false,
- EnableLifetimeWarnings);
- }
- static void DiagnoseNarrowingInInitList(Sema &S,
- const ImplicitConversionSequence &ICS,
- QualType PreNarrowingType,
- QualType EntityType,
- const Expr *PostInit);
- /// Provide warnings when std::move is used on construction.
- static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr,
- bool IsReturnStmt) {
- if (!InitExpr)
- return;
- if (S.inTemplateInstantiation())
- return;
- QualType DestType = InitExpr->getType();
- if (!DestType->isRecordType())
- return;
- unsigned DiagID = 0;
- if (IsReturnStmt) {
- const CXXConstructExpr *CCE =
- dyn_cast<CXXConstructExpr>(InitExpr->IgnoreParens());
- if (!CCE || CCE->getNumArgs() != 1)
- return;
- if (!CCE->getConstructor()->isCopyOrMoveConstructor())
- return;
- InitExpr = CCE->getArg(0)->IgnoreImpCasts();
- }
- // Find the std::move call and get the argument.
- const CallExpr *CE = dyn_cast<CallExpr>(InitExpr->IgnoreParens());
- if (!CE || !CE->isCallToStdMove())
- return;
- const Expr *Arg = CE->getArg(0)->IgnoreImplicit();
- if (IsReturnStmt) {
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg->IgnoreParenImpCasts());
- if (!DRE || DRE->refersToEnclosingVariableOrCapture())
- return;
- const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
- if (!VD || !VD->hasLocalStorage())
- return;
- // __block variables are not moved implicitly.
- if (VD->hasAttr<BlocksAttr>())
- return;
- QualType SourceType = VD->getType();
- if (!SourceType->isRecordType())
- return;
- if (!S.Context.hasSameUnqualifiedType(DestType, SourceType)) {
- return;
- }
- // If we're returning a function parameter, copy elision
- // is not possible.
- if (isa<ParmVarDecl>(VD))
- DiagID = diag::warn_redundant_move_on_return;
- else
- DiagID = diag::warn_pessimizing_move_on_return;
- } else {
- DiagID = diag::warn_pessimizing_move_on_initialization;
- const Expr *ArgStripped = Arg->IgnoreImplicit()->IgnoreParens();
- if (!ArgStripped->isPRValue() || !ArgStripped->getType()->isRecordType())
- return;
- }
- S.Diag(CE->getBeginLoc(), DiagID);
- // Get all the locations for a fix-it. Don't emit the fix-it if any location
- // is within a macro.
- SourceLocation CallBegin = CE->getCallee()->getBeginLoc();
- if (CallBegin.isMacroID())
- return;
- SourceLocation RParen = CE->getRParenLoc();
- if (RParen.isMacroID())
- return;
- SourceLocation LParen;
- SourceLocation ArgLoc = Arg->getBeginLoc();
- // Special testing for the argument location. Since the fix-it needs the
- // location right before the argument, the argument location can be in a
- // macro only if it is at the beginning of the macro.
- while (ArgLoc.isMacroID() &&
- S.getSourceManager().isAtStartOfImmediateMacroExpansion(ArgLoc)) {
- ArgLoc = S.getSourceManager().getImmediateExpansionRange(ArgLoc).getBegin();
- }
- if (LParen.isMacroID())
- return;
- LParen = ArgLoc.getLocWithOffset(-1);
- S.Diag(CE->getBeginLoc(), diag::note_remove_move)
- << FixItHint::CreateRemoval(SourceRange(CallBegin, LParen))
- << FixItHint::CreateRemoval(SourceRange(RParen, RParen));
- }
- static void CheckForNullPointerDereference(Sema &S, const Expr *E) {
- // Check to see if we are dereferencing a null pointer. If so, this is
- // undefined behavior, so warn about it. This only handles the pattern
- // "*null", which is a very syntactic check.
- if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts()))
- if (UO->getOpcode() == UO_Deref &&
- UO->getSubExpr()->IgnoreParenCasts()->
- isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)) {
- S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
- S.PDiag(diag::warn_binding_null_to_reference)
- << UO->getSubExpr()->getSourceRange());
- }
- }
- MaterializeTemporaryExpr *
- Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference) {
- auto MTE = new (Context)
- MaterializeTemporaryExpr(T, Temporary, BoundToLvalueReference);
- // Order an ExprWithCleanups for lifetime marks.
- //
- // TODO: It'll be good to have a single place to check the access of the
- // destructor and generate ExprWithCleanups for various uses. Currently these
- // are done in both CreateMaterializeTemporaryExpr and MaybeBindToTemporary,
- // but there may be a chance to merge them.
- Cleanup.setExprNeedsCleanups(false);
- return MTE;
- }
- ExprResult Sema::TemporaryMaterializationConversion(Expr *E) {
- // In C++98, we don't want to implicitly create an xvalue.
- // FIXME: This means that AST consumers need to deal with "prvalues" that
- // denote materialized temporaries. Maybe we should add another ValueKind
- // for "xvalue pretending to be a prvalue" for C++98 support.
- if (!E->isPRValue() || !getLangOpts().CPlusPlus11)
- return E;
- // C++1z [conv.rval]/1: T shall be a complete type.
- // FIXME: Does this ever matter (can we form a prvalue of incomplete type)?
- // If so, we should check for a non-abstract class type here too.
- QualType T = E->getType();
- if (RequireCompleteType(E->getExprLoc(), T, diag::err_incomplete_type))
- return ExprError();
- return CreateMaterializeTemporaryExpr(E->getType(), E, false);
- }
- ExprResult Sema::PerformQualificationConversion(Expr *E, QualType Ty,
- ExprValueKind VK,
- CheckedConversionKind CCK) {
- CastKind CK = CK_NoOp;
- if (VK == VK_PRValue) {
- auto PointeeTy = Ty->getPointeeType();
- auto ExprPointeeTy = E->getType()->getPointeeType();
- if (!PointeeTy.isNull() &&
- PointeeTy.getAddressSpace() != ExprPointeeTy.getAddressSpace())
- CK = CK_AddressSpaceConversion;
- } else if (Ty.getAddressSpace() != E->getType().getAddressSpace()) {
- CK = CK_AddressSpaceConversion;
- }
- return ImpCastExprToType(E, Ty, CK, VK, /*BasePath=*/nullptr, CCK);
- }
- ExprResult InitializationSequence::Perform(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- QualType *ResultType) {
- if (Failed()) {
- Diagnose(S, Entity, Kind, Args);
- return ExprError();
- }
- if (!ZeroInitializationFixit.empty()) {
- const Decl *D = Entity.getDecl();
- const auto *VD = dyn_cast_or_null<VarDecl>(D);
- QualType DestType = Entity.getType();
- // The initialization would have succeeded with this fixit. Since the fixit
- // is on the error, we need to build a valid AST in this case, so this isn't
- // handled in the Failed() branch above.
- if (!DestType->isRecordType() && VD && VD->isConstexpr()) {
- // Use a more useful diagnostic for constexpr variables.
- S.Diag(Kind.getLocation(), diag::err_constexpr_var_requires_const_init)
- << VD
- << FixItHint::CreateInsertion(ZeroInitializationFixitLoc,
- ZeroInitializationFixit);
- } else {
- unsigned DiagID = diag::err_default_init_const;
- if (S.getLangOpts().MSVCCompat && D && D->hasAttr<SelectAnyAttr>())
- DiagID = diag::ext_default_init_const;
- S.Diag(Kind.getLocation(), DiagID)
- << DestType << (bool)DestType->getAs<RecordType>()
- << FixItHint::CreateInsertion(ZeroInitializationFixitLoc,
- ZeroInitializationFixit);
- }
- }
- if (getKind() == DependentSequence) {
- // If the declaration is a non-dependent, incomplete array type
- // that has an initializer, then its type will be completed once
- // the initializer is instantiated.
- if (ResultType && !Entity.getType()->isDependentType() &&
- Args.size() == 1) {
- QualType DeclType = Entity.getType();
- if (const IncompleteArrayType *ArrayT
- = S.Context.getAsIncompleteArrayType(DeclType)) {
- // FIXME: We don't currently have the ability to accurately
- // compute the length of an initializer list without
- // performing full type-checking of the initializer list
- // (since we have to determine where braces are implicitly
- // introduced and such). So, we fall back to making the array
- // type a dependently-sized array type with no specified
- // bound.
- if (isa<InitListExpr>((Expr *)Args[0])) {
- SourceRange Brackets;
- // Scavange the location of the brackets from the entity, if we can.
- if (auto *DD = dyn_cast_or_null<DeclaratorDecl>(Entity.getDecl())) {
- if (TypeSourceInfo *TInfo = DD->getTypeSourceInfo()) {
- TypeLoc TL = TInfo->getTypeLoc();
- if (IncompleteArrayTypeLoc ArrayLoc =
- TL.getAs<IncompleteArrayTypeLoc>())
- Brackets = ArrayLoc.getBracketsRange();
- }
- }
- *ResultType
- = S.Context.getDependentSizedArrayType(ArrayT->getElementType(),
- /*NumElts=*/nullptr,
- ArrayT->getSizeModifier(),
- ArrayT->getIndexTypeCVRQualifiers(),
- Brackets);
- }
- }
- }
- if (Kind.getKind() == InitializationKind::IK_Direct &&
- !Kind.isExplicitCast()) {
- // Rebuild the ParenListExpr.
- SourceRange ParenRange = Kind.getParenOrBraceRange();
- return S.ActOnParenListExpr(ParenRange.getBegin(), ParenRange.getEnd(),
- Args);
- }
- assert(Kind.getKind() == InitializationKind::IK_Copy ||
- Kind.isExplicitCast() ||
- Kind.getKind() == InitializationKind::IK_DirectList);
- return ExprResult(Args[0]);
- }
- // No steps means no initialization.
- if (Steps.empty())
- return ExprResult((Expr *)nullptr);
- if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() &&
- Args.size() == 1 && isa<InitListExpr>(Args[0]) &&
- !Entity.isParamOrTemplateParamKind()) {
- // Produce a C++98 compatibility warning if we are initializing a reference
- // from an initializer list. For parameters, we produce a better warning
- // elsewhere.
- Expr *Init = Args[0];
- S.Diag(Init->getBeginLoc(), diag::warn_cxx98_compat_reference_list_init)
- << Init->getSourceRange();
- }
- // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope
- QualType ETy = Entity.getType();
- bool HasGlobalAS = ETy.hasAddressSpace() &&
- ETy.getAddressSpace() == LangAS::opencl_global;
- if (S.getLangOpts().OpenCLVersion >= 200 &&
- ETy->isAtomicType() && !HasGlobalAS &&
- Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) {
- S.Diag(Args[0]->getBeginLoc(), diag::err_opencl_atomic_init)
- << 1
- << SourceRange(Entity.getDecl()->getBeginLoc(), Args[0]->getEndLoc());
- return ExprError();
- }
- QualType DestType = Entity.getType().getNonReferenceType();
- // FIXME: Ugly hack around the fact that Entity.getType() is not
- // the same as Entity.getDecl()->getType() in cases involving type merging,
- // and we want latter when it makes sense.
- if (ResultType)
- *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
- Entity.getType();
- ExprResult CurInit((Expr *)nullptr);
- SmallVector<Expr*, 4> ArrayLoopCommonExprs;
- // HLSL allows vector initialization to function like list initialization, but
- // use the syntax of a C++-like constructor.
- bool IsHLSLVectorInit = S.getLangOpts().HLSL && DestType->isExtVectorType() &&
- isa<InitListExpr>(Args[0]);
- (void)IsHLSLVectorInit;
- // For initialization steps that start with a single initializer,
- // grab the only argument out the Args and place it into the "current"
- // initializer.
- switch (Steps.front().Kind) {
- case SK_ResolveAddressOfOverloadedFunction:
- case SK_CastDerivedToBasePRValue:
- case SK_CastDerivedToBaseXValue:
- case SK_CastDerivedToBaseLValue:
- case SK_BindReference:
- case SK_BindReferenceToTemporary:
- case SK_FinalCopy:
- case SK_ExtraneousCopyToTemporary:
- case SK_UserConversion:
- case SK_QualificationConversionLValue:
- case SK_QualificationConversionXValue:
- case SK_QualificationConversionPRValue:
- case SK_FunctionReferenceConversion:
- case SK_AtomicConversion:
- case SK_ConversionSequence:
- case SK_ConversionSequenceNoNarrowing:
- case SK_ListInitialization:
- case SK_UnwrapInitList:
- case SK_RewrapInitList:
- case SK_CAssignment:
- case SK_StringInit:
- case SK_ObjCObjectConversion:
- case SK_ArrayLoopIndex:
- case SK_ArrayLoopInit:
- case SK_ArrayInit:
- case SK_GNUArrayInit:
- case SK_ParenthesizedArrayInit:
- case SK_PassByIndirectCopyRestore:
- case SK_PassByIndirectRestore:
- case SK_ProduceObjCObject:
- case SK_StdInitializerList:
- case SK_OCLSamplerInit:
- case SK_OCLZeroOpaqueType: {
- assert(Args.size() == 1 || IsHLSLVectorInit);
- CurInit = Args[0];
- if (!CurInit.get()) return ExprError();
- break;
- }
- case SK_ConstructorInitialization:
- case SK_ConstructorInitializationFromList:
- case SK_StdInitializerListConstructorCall:
- case SK_ZeroInitialization:
- case SK_ParenthesizedListInit:
- break;
- }
- // Promote from an unevaluated context to an unevaluated list context in
- // C++11 list-initialization; we need to instantiate entities usable in
- // constant expressions here in order to perform narrowing checks =(
- EnterExpressionEvaluationContext Evaluated(
- S, EnterExpressionEvaluationContext::InitList,
- CurInit.get() && isa<InitListExpr>(CurInit.get()));
- // C++ [class.abstract]p2:
- // no objects of an abstract class can be created except as subobjects
- // of a class derived from it
- auto checkAbstractType = [&](QualType T) -> bool {
- if (Entity.getKind() == InitializedEntity::EK_Base ||
- Entity.getKind() == InitializedEntity::EK_Delegating)
- return false;
- return S.RequireNonAbstractType(Kind.getLocation(), T,
- diag::err_allocation_of_abstract_type);
- };
- // Walk through the computed steps for the initialization sequence,
- // performing the specified conversions along the way.
- bool ConstructorInitRequiresZeroInit = false;
- for (step_iterator Step = step_begin(), StepEnd = step_end();
- Step != StepEnd; ++Step) {
- if (CurInit.isInvalid())
- return ExprError();
- QualType SourceType = CurInit.get() ? CurInit.get()->getType() : QualType();
- switch (Step->Kind) {
- case SK_ResolveAddressOfOverloadedFunction:
- // Overload resolution determined which function invoke; update the
- // initializer to reflect that choice.
- S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
- if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
- return ExprError();
- CurInit = S.FixOverloadedFunctionReference(CurInit,
- Step->Function.FoundDecl,
- Step->Function.Function);
- // We might get back another placeholder expression if we resolved to a
- // builtin.
- if (!CurInit.isInvalid())
- CurInit = S.CheckPlaceholderExpr(CurInit.get());
- break;
- case SK_CastDerivedToBasePRValue:
- case SK_CastDerivedToBaseXValue:
- case SK_CastDerivedToBaseLValue: {
- // We have a derived-to-base cast that produces either an rvalue or an
- // lvalue. Perform that cast.
- CXXCastPath BasePath;
- // Casts to inaccessible base classes are allowed with C-style casts.
- bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
- if (S.CheckDerivedToBaseConversion(
- SourceType, Step->Type, CurInit.get()->getBeginLoc(),
- CurInit.get()->getSourceRange(), &BasePath, IgnoreBaseAccess))
- return ExprError();
- ExprValueKind VK =
- Step->Kind == SK_CastDerivedToBaseLValue
- ? VK_LValue
- : (Step->Kind == SK_CastDerivedToBaseXValue ? VK_XValue
- : VK_PRValue);
- CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
- CK_DerivedToBase, CurInit.get(),
- &BasePath, VK, FPOptionsOverride());
- break;
- }
- case SK_BindReference:
- // Reference binding does not have any corresponding ASTs.
- // Check exception specifications
- if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
- return ExprError();
- // We don't check for e.g. function pointers here, since address
- // availability checks should only occur when the function first decays
- // into a pointer or reference.
- if (CurInit.get()->getType()->isFunctionProtoType()) {
- if (auto *DRE = dyn_cast<DeclRefExpr>(CurInit.get()->IgnoreParens())) {
- if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (!S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
- DRE->getBeginLoc()))
- return ExprError();
- }
- }
- }
- CheckForNullPointerDereference(S, CurInit.get());
- break;
- case SK_BindReferenceToTemporary: {
- // Make sure the "temporary" is actually an rvalue.
- assert(CurInit.get()->isPRValue() && "not a temporary");
- // Check exception specifications
- if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
- return ExprError();
- QualType MTETy = Step->Type;
- // When this is an incomplete array type (such as when this is
- // initializing an array of unknown bounds from an init list), use THAT
- // type instead so that we propagate the array bounds.
- if (MTETy->isIncompleteArrayType() &&
- !CurInit.get()->getType()->isIncompleteArrayType() &&
- S.Context.hasSameType(
- MTETy->getPointeeOrArrayElementType(),
- CurInit.get()->getType()->getPointeeOrArrayElementType()))
- MTETy = CurInit.get()->getType();
- // Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
- MTETy, CurInit.get(), Entity.getType()->isLValueReferenceType());
- CurInit = MTE;
- // If we're extending this temporary to automatic storage duration -- we
- // need to register its cleanup during the full-expression's cleanups.
- if (MTE->getStorageDuration() == SD_Automatic &&
- MTE->getType().isDestructedType())
- S.Cleanup.setExprNeedsCleanups(true);
- break;
- }
- case SK_FinalCopy:
- if (checkAbstractType(Step->Type))
- return ExprError();
- // If the overall initialization is initializing a temporary, we already
- // bound our argument if it was necessary to do so. If not (if we're
- // ultimately initializing a non-temporary), our argument needs to be
- // bound since it's initializing a function parameter.
- // FIXME: This is a mess. Rationalize temporary destruction.
- if (!shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.get());
- CurInit = CopyObject(S, Step->Type, Entity, CurInit,
- /*IsExtraneousCopy=*/false);
- break;
- case SK_ExtraneousCopyToTemporary:
- CurInit = CopyObject(S, Step->Type, Entity, CurInit,
- /*IsExtraneousCopy=*/true);
- break;
- case SK_UserConversion: {
- // We have a user-defined conversion that invokes either a constructor
- // or a conversion function.
- CastKind CastKind;
- FunctionDecl *Fn = Step->Function.Function;
- DeclAccessPair FoundFn = Step->Function.FoundDecl;
- bool HadMultipleCandidates = Step->Function.HadMultipleCandidates;
- bool CreatedObject = false;
- if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
- // Build a call to the selected constructor.
- SmallVector<Expr*, 8> ConstructorArgs;
- SourceLocation Loc = CurInit.get()->getBeginLoc();
- // Determine the arguments required to actually perform the constructor
- // call.
- Expr *Arg = CurInit.get();
- if (S.CompleteConstructorCall(Constructor, Step->Type,
- MultiExprArg(&Arg, 1), Loc,
- ConstructorArgs))
- return ExprError();
- // Build an expression that constructs a temporary.
- CurInit = S.BuildCXXConstructExpr(Loc, Step->Type,
- FoundFn, Constructor,
- ConstructorArgs,
- HadMultipleCandidates,
- /*ListInit*/ false,
- /*StdInitListInit*/ false,
- /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
- if (CurInit.isInvalid())
- return ExprError();
- S.CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
- Entity);
- if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
- return ExprError();
- CastKind = CK_ConstructorConversion;
- CreatedObject = true;
- } else {
- // Build a call to the conversion function.
- CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
- S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
- FoundFn);
- if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
- return ExprError();
- CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
- HadMultipleCandidates);
- if (CurInit.isInvalid())
- return ExprError();
- CastKind = CK_UserDefinedConversion;
- CreatedObject = Conversion->getReturnType()->isRecordType();
- }
- if (CreatedObject && checkAbstractType(CurInit.get()->getType()))
- return ExprError();
- CurInit = ImplicitCastExpr::Create(
- S.Context, CurInit.get()->getType(), CastKind, CurInit.get(), nullptr,
- CurInit.get()->getValueKind(), S.CurFPFeatureOverrides());
- if (shouldBindAsTemporary(Entity))
- // The overall entity is temporary, so this expression should be
- // destroyed at the end of its full-expression.
- CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
- else if (CreatedObject && shouldDestroyEntity(Entity)) {
- // The object outlasts the full-expression, but we need to prepare for
- // a destructor being run on it.
- // FIXME: It makes no sense to do this here. This should happen
- // regardless of how we initialized the entity.
- QualType T = CurInit.get()->getType();
- if (const RecordType *Record = T->getAs<RecordType>()) {
- CXXDestructorDecl *Destructor
- = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
- S.CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor,
- S.PDiag(diag::err_access_dtor_temp) << T);
- S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor);
- if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getBeginLoc()))
- return ExprError();
- }
- }
- break;
- }
- case SK_QualificationConversionLValue:
- case SK_QualificationConversionXValue:
- case SK_QualificationConversionPRValue: {
- // Perform a qualification conversion; these can never go wrong.
- ExprValueKind VK =
- Step->Kind == SK_QualificationConversionLValue
- ? VK_LValue
- : (Step->Kind == SK_QualificationConversionXValue ? VK_XValue
- : VK_PRValue);
- CurInit = S.PerformQualificationConversion(CurInit.get(), Step->Type, VK);
- break;
- }
- case SK_FunctionReferenceConversion:
- assert(CurInit.get()->isLValue() &&
- "function reference should be lvalue");
- CurInit =
- S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK_LValue);
- break;
- case SK_AtomicConversion: {
- assert(CurInit.get()->isPRValue() && "cannot convert glvalue to atomic");
- CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
- CK_NonAtomicToAtomic, VK_PRValue);
- break;
- }
- case SK_ConversionSequence:
- case SK_ConversionSequenceNoNarrowing: {
- if (const auto *FromPtrType =
- CurInit.get()->getType()->getAs<PointerType>()) {
- if (const auto *ToPtrType = Step->Type->getAs<PointerType>()) {
- if (FromPtrType->getPointeeType()->hasAttr(attr::NoDeref) &&
- !ToPtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
- // Do not check static casts here because they are checked earlier
- // in Sema::ActOnCXXNamedCast()
- if (!Kind.isStaticCast()) {
- S.Diag(CurInit.get()->getExprLoc(),
- diag::warn_noderef_to_dereferenceable_pointer)
- << CurInit.get()->getSourceRange();
- }
- }
- }
- }
- Sema::CheckedConversionKind CCK
- = Kind.isCStyleCast()? Sema::CCK_CStyleCast
- : Kind.isFunctionalCast()? Sema::CCK_FunctionalCast
- : Kind.isExplicitCast()? Sema::CCK_OtherCast
- : Sema::CCK_ImplicitConversion;
- ExprResult CurInitExprRes =
- S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS,
- getAssignmentAction(Entity), CCK);
- if (CurInitExprRes.isInvalid())
- return ExprError();
- S.DiscardMisalignedMemberAddress(Step->Type.getTypePtr(), CurInit.get());
- CurInit = CurInitExprRes;
- if (Step->Kind == SK_ConversionSequenceNoNarrowing &&
- S.getLangOpts().CPlusPlus)
- DiagnoseNarrowingInInitList(S, *Step->ICS, SourceType, Entity.getType(),
- CurInit.get());
- break;
- }
- case SK_ListInitialization: {
- if (checkAbstractType(Step->Type))
- return ExprError();
- InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
- // If we're not initializing the top-level entity, we need to create an
- // InitializeTemporary entity for our target type.
- QualType Ty = Step->Type;
- bool IsTemporary = !S.Context.hasSameType(Entity.getType(), Ty);
- InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty);
- InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;
- InitListChecker PerformInitList(S, InitEntity,
- InitList, Ty, /*VerifyOnly=*/false,
- /*TreatUnavailableAsInvalid=*/false);
- if (PerformInitList.HadError())
- return ExprError();
- // Hack: We must update *ResultType if available in order to set the
- // bounds of arrays, e.g. in 'int ar[] = {1, 2, 3};'.
- // Worst case: 'const int (&arref)[] = {1, 2, 3};'.
- if (ResultType &&
- ResultType->getNonReferenceType()->isIncompleteArrayType()) {
- if ((*ResultType)->isRValueReferenceType())
- Ty = S.Context.getRValueReferenceType(Ty);
- else if ((*ResultType)->isLValueReferenceType())
- Ty = S.Context.getLValueReferenceType(Ty,
- (*ResultType)->castAs<LValueReferenceType>()->isSpelledAsLValue());
- *ResultType = Ty;
- }
- InitListExpr *StructuredInitList =
- PerformInitList.getFullyStructuredList();
- CurInit.get();
- CurInit = shouldBindAsTemporary(InitEntity)
- ? S.MaybeBindToTemporary(StructuredInitList)
- : StructuredInitList;
- break;
- }
- case SK_ConstructorInitializationFromList: {
- if (checkAbstractType(Step->Type))
- return ExprError();
- // When an initializer list is passed for a parameter of type "reference
- // to object", we don't get an EK_Temporary entity, but instead an
- // EK_Parameter entity with reference type.
- // FIXME: This is a hack. What we really should do is create a user
- // conversion step for this case, but this makes it considerably more
- // complicated. For now, this will do.
- InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
- Entity.getType().getNonReferenceType());
- bool UseTemporary = Entity.getType()->isReferenceType();
- assert(Args.size() == 1 && "expected a single argument for list init");
- InitListExpr *InitList = cast<InitListExpr>(Args[0]);
- S.Diag(InitList->getExprLoc(), diag::warn_cxx98_compat_ctor_list_init)
- << InitList->getSourceRange();
- MultiExprArg Arg(InitList->getInits(), InitList->getNumInits());
- CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity :
- Entity,
- Kind, Arg, *Step,
- ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/true,
- /*IsStdInitListInit*/false,
- InitList->getLBraceLoc(),
- InitList->getRBraceLoc());
- break;
- }
- case SK_UnwrapInitList:
- CurInit = cast<InitListExpr>(CurInit.get())->getInit(0);
- break;
- case SK_RewrapInitList: {
- Expr *E = CurInit.get();
- InitListExpr *Syntactic = Step->WrappingSyntacticList;
- InitListExpr *ILE = new (S.Context) InitListExpr(S.Context,
- Syntactic->getLBraceLoc(), E, Syntactic->getRBraceLoc());
- ILE->setSyntacticForm(Syntactic);
- ILE->setType(E->getType());
- ILE->setValueKind(E->getValueKind());
- CurInit = ILE;
- break;
- }
- case SK_ConstructorInitialization:
- case SK_StdInitializerListConstructorCall: {
- if (checkAbstractType(Step->Type))
- return ExprError();
- // When an initializer list is passed for a parameter of type "reference
- // to object", we don't get an EK_Temporary entity, but instead an
- // EK_Parameter entity with reference type.
- // FIXME: This is a hack. What we really should do is create a user
- // conversion step for this case, but this makes it considerably more
- // complicated. For now, this will do.
- InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
- Entity.getType().getNonReferenceType());
- bool UseTemporary = Entity.getType()->isReferenceType();
- bool IsStdInitListInit =
- Step->Kind == SK_StdInitializerListConstructorCall;
- Expr *Source = CurInit.get();
- SourceRange Range = Kind.hasParenOrBraceRange()
- ? Kind.getParenOrBraceRange()
- : SourceRange();
- CurInit = PerformConstructorInitialization(
- S, UseTemporary ? TempEntity : Entity, Kind,
- Source ? MultiExprArg(Source) : Args, *Step,
- ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/ IsStdInitListInit,
- /*IsStdInitListInitialization*/ IsStdInitListInit,
- /*LBraceLoc*/ Range.getBegin(),
- /*RBraceLoc*/ Range.getEnd());
- break;
- }
- case SK_ZeroInitialization: {
- step_iterator NextStep = Step;
- ++NextStep;
- if (NextStep != StepEnd &&
- (NextStep->Kind == SK_ConstructorInitialization ||
- NextStep->Kind == SK_ConstructorInitializationFromList)) {
- // The need for zero-initialization is recorded directly into
- // the call to the object's constructor within the next step.
- ConstructorInitRequiresZeroInit = true;
- } else if (Kind.getKind() == InitializationKind::IK_Value &&
- S.getLangOpts().CPlusPlus &&
- !Kind.isImplicitValueInit()) {
- TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
- if (!TSInfo)
- TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
- Kind.getRange().getBegin());
- CurInit = new (S.Context) CXXScalarValueInitExpr(
- Entity.getType().getNonLValueExprType(S.Context), TSInfo,
- Kind.getRange().getEnd());
- } else {
- CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type);
- }
- break;
- }
- case SK_CAssignment: {
- QualType SourceType = CurInit.get()->getType();
- // Save off the initial CurInit in case we need to emit a diagnostic
- ExprResult InitialCurInit = CurInit;
- ExprResult Result = CurInit;
- Sema::AssignConvertType ConvTy =
- S.CheckSingleAssignmentConstraints(Step->Type, Result, true,
- Entity.getKind() == InitializedEntity::EK_Parameter_CF_Audited);
- if (Result.isInvalid())
- return ExprError();
- CurInit = Result;
- // If this is a call, allow conversion to a transparent union.
- ExprResult CurInitExprRes = CurInit;
- if (ConvTy != Sema::Compatible &&
- Entity.isParameterKind() &&
- S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExprRes)
- == Sema::Compatible)
- ConvTy = Sema::Compatible;
- if (CurInitExprRes.isInvalid())
- return ExprError();
- CurInit = CurInitExprRes;
- bool Complained;
- if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
- Step->Type, SourceType,
- InitialCurInit.get(),
- getAssignmentAction(Entity, true),
- &Complained)) {
- PrintInitLocationNote(S, Entity);
- return ExprError();
- } else if (Complained)
- PrintInitLocationNote(S, Entity);
- break;
- }
- case SK_StringInit: {
- QualType Ty = Step->Type;
- bool UpdateType = ResultType && Entity.getType()->isIncompleteArrayType();
- CheckStringInit(CurInit.get(), UpdateType ? *ResultType : Ty,
- S.Context.getAsArrayType(Ty), S);
- break;
- }
- case SK_ObjCObjectConversion:
- CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
- CK_ObjCObjectLValueCast,
- CurInit.get()->getValueKind());
- break;
- case SK_ArrayLoopIndex: {
- Expr *Cur = CurInit.get();
- Expr *BaseExpr = new (S.Context)
- OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(),
- Cur->getValueKind(), Cur->getObjectKind(), Cur);
- Expr *IndexExpr =
- new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType());
- CurInit = S.CreateBuiltinArraySubscriptExpr(
- BaseExpr, Kind.getLocation(), IndexExpr, Kind.getLocation());
- ArrayLoopCommonExprs.push_back(BaseExpr);
- break;
- }
- case SK_ArrayLoopInit: {
- assert(!ArrayLoopCommonExprs.empty() &&
- "mismatched SK_ArrayLoopIndex and SK_ArrayLoopInit");
- Expr *Common = ArrayLoopCommonExprs.pop_back_val();
- CurInit = new (S.Context) ArrayInitLoopExpr(Step->Type, Common,
- CurInit.get());
- break;
- }
- case SK_GNUArrayInit:
- // Okay: we checked everything before creating this step. Note that
- // this is a GNU extension.
- S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
- << Step->Type << CurInit.get()->getType()
- << CurInit.get()->getSourceRange();
- updateGNUCompoundLiteralRValue(CurInit.get());
- [[fallthrough]];
- case SK_ArrayInit:
- // If the destination type is an incomplete array type, update the
- // type accordingly.
- if (ResultType) {
- if (const IncompleteArrayType *IncompleteDest
- = S.Context.getAsIncompleteArrayType(Step->Type)) {
- if (const ConstantArrayType *ConstantSource
- = S.Context.getAsConstantArrayType(CurInit.get()->getType())) {
- *ResultType = S.Context.getConstantArrayType(
- IncompleteDest->getElementType(),
- ConstantSource->getSize(),
- ConstantSource->getSizeExpr(),
- ArrayType::Normal, 0);
- }
- }
- }
- break;
- case SK_ParenthesizedArrayInit:
- // Okay: we checked everything before creating this step. Note that
- // this is a GNU extension.
- S.Diag(Kind.getLocation(), diag::ext_array_init_parens)
- << CurInit.get()->getSourceRange();
- break;
- case SK_PassByIndirectCopyRestore:
- case SK_PassByIndirectRestore:
- checkIndirectCopyRestoreSource(S, CurInit.get());
- CurInit = new (S.Context) ObjCIndirectCopyRestoreExpr(
- CurInit.get(), Step->Type,
- Step->Kind == SK_PassByIndirectCopyRestore);
- break;
- case SK_ProduceObjCObject:
- CurInit = ImplicitCastExpr::Create(
- S.Context, Step->Type, CK_ARCProduceObject, CurInit.get(), nullptr,
- VK_PRValue, FPOptionsOverride());
- break;
- case SK_StdInitializerList: {
- S.Diag(CurInit.get()->getExprLoc(),
- diag::warn_cxx98_compat_initializer_list_init)
- << CurInit.get()->getSourceRange();
- // Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
- CurInit.get()->getType(), CurInit.get(),
- /*BoundToLvalueReference=*/false);
- // Wrap it in a construction of a std::initializer_list<T>.
- CurInit = new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE);
- // Bind the result, in case the library has given initializer_list a
- // non-trivial destructor.
- if (shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.get());
- break;
- }
- case SK_OCLSamplerInit: {
- // Sampler initialization have 5 cases:
- // 1. function argument passing
- // 1a. argument is a file-scope variable
- // 1b. argument is a function-scope variable
- // 1c. argument is one of caller function's parameters
- // 2. variable initialization
- // 2a. initializing a file-scope variable
- // 2b. initializing a function-scope variable
- //
- // For file-scope variables, since they cannot be initialized by function
- // call of __translate_sampler_initializer in LLVM IR, their references
- // need to be replaced by a cast from their literal initializers to
- // sampler type. Since sampler variables can only be used in function
- // calls as arguments, we only need to replace them when handling the
- // argument passing.
- assert(Step->Type->isSamplerT() &&
- "Sampler initialization on non-sampler type.");
- Expr *Init = CurInit.get()->IgnoreParens();
- QualType SourceType = Init->getType();
- // Case 1
- if (Entity.isParameterKind()) {
- if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) {
- S.Diag(Kind.getLocation(), diag::err_sampler_argument_required)
- << SourceType;
- break;
- } else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Init)) {
- auto Var = cast<VarDecl>(DRE->getDecl());
- // Case 1b and 1c
- // No cast from integer to sampler is needed.
- if (!Var->hasGlobalStorage()) {
- CurInit = ImplicitCastExpr::Create(
- S.Context, Step->Type, CK_LValueToRValue, Init,
- /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride());
- break;
- }
- // Case 1a
- // For function call with a file-scope sampler variable as argument,
- // get the integer literal.
- // Do not diagnose if the file-scope variable does not have initializer
- // since this has already been diagnosed when parsing the variable
- // declaration.
- if (!Var->getInit() || !isa<ImplicitCastExpr>(Var->getInit()))
- break;
- Init = cast<ImplicitCastExpr>(const_cast<Expr*>(
- Var->getInit()))->getSubExpr();
- SourceType = Init->getType();
- }
- } else {
- // Case 2
- // Check initializer is 32 bit integer constant.
- // If the initializer is taken from global variable, do not diagnose since
- // this has already been done when parsing the variable declaration.
- if (!Init->isConstantInitializer(S.Context, false))
- break;
- if (!SourceType->isIntegerType() ||
- 32 != S.Context.getIntWidth(SourceType)) {
- S.Diag(Kind.getLocation(), diag::err_sampler_initializer_not_integer)
- << SourceType;
- break;
- }
- Expr::EvalResult EVResult;
- Init->EvaluateAsInt(EVResult, S.Context);
- llvm::APSInt Result = EVResult.Val.getInt();
- const uint64_t SamplerValue = Result.getLimitedValue();
- // 32-bit value of sampler's initializer is interpreted as
- // bit-field with the following structure:
- // |unspecified|Filter|Addressing Mode| Normalized Coords|
- // |31 6|5 4|3 1| 0|
- // This structure corresponds to enum values of sampler properties
- // defined in SPIR spec v1.2 and also opencl-c.h
- unsigned AddressingMode = (0x0E & SamplerValue) >> 1;
- unsigned FilterMode = (0x30 & SamplerValue) >> 4;
- if (FilterMode != 1 && FilterMode != 2 &&
- !S.getOpenCLOptions().isAvailableOption(
- "cl_intel_device_side_avc_motion_estimation", S.getLangOpts()))
- S.Diag(Kind.getLocation(),
- diag::warn_sampler_initializer_invalid_bits)
- << "Filter Mode";
- if (AddressingMode > 4)
- S.Diag(Kind.getLocation(),
- diag::warn_sampler_initializer_invalid_bits)
- << "Addressing Mode";
- }
- // Cases 1a, 2a and 2b
- // Insert cast from integer to sampler.
- CurInit = S.ImpCastExprToType(Init, S.Context.OCLSamplerTy,
- CK_IntToOCLSampler);
- break;
- }
- case SK_OCLZeroOpaqueType: {
- assert((Step->Type->isEventT() || Step->Type->isQueueT() ||
- Step->Type->isOCLIntelSubgroupAVCType()) &&
- "Wrong type for initialization of OpenCL opaque type.");
- CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
- CK_ZeroToOCLOpaqueType,
- CurInit.get()->getValueKind());
- break;
- }
- case SK_ParenthesizedListInit: {
- CurInit = nullptr;
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/false, &CurInit);
- if (CurInit.get() && ResultType)
- *ResultType = CurInit.get()->getType();
- break;
- }
- }
- }
- // Check whether the initializer has a shorter lifetime than the initialized
- // entity, and if not, either lifetime-extend or warn as appropriate.
- if (auto *Init = CurInit.get())
- S.checkInitializerLifetime(Entity, Init);
- // Diagnose non-fatal problems with the completed initialization.
- if (Entity.getKind() == InitializedEntity::EK_Member &&
- cast<FieldDecl>(Entity.getDecl())->isBitField())
- S.CheckBitFieldInitialization(Kind.getLocation(),
- cast<FieldDecl>(Entity.getDecl()),
- CurInit.get());
- // Check for std::move on construction.
- if (const Expr *E = CurInit.get()) {
- CheckMoveOnConstruction(S, E,
- Entity.getKind() == InitializedEntity::EK_Result);
- }
- return CurInit;
- }
- /// Somewhere within T there is an uninitialized reference subobject.
- /// Dig it out and diagnose it.
- static bool DiagnoseUninitializedReference(Sema &S, SourceLocation Loc,
- QualType T) {
- if (T->isReferenceType()) {
- S.Diag(Loc, diag::err_reference_without_init)
- << T.getNonReferenceType();
- return true;
- }
- CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
- if (!RD || !RD->hasUninitializedReferenceMember())
- return false;
- for (const auto *FI : RD->fields()) {
- if (FI->isUnnamedBitfield())
- continue;
- if (DiagnoseUninitializedReference(S, FI->getLocation(), FI->getType())) {
- S.Diag(Loc, diag::note_value_initialization_here) << RD;
- return true;
- }
- }
- for (const auto &BI : RD->bases()) {
- if (DiagnoseUninitializedReference(S, BI.getBeginLoc(), BI.getType())) {
- S.Diag(Loc, diag::note_value_initialization_here) << RD;
- return true;
- }
- }
- return false;
- }
- //===----------------------------------------------------------------------===//
- // Diagnose initialization failures
- //===----------------------------------------------------------------------===//
- /// Emit notes associated with an initialization that failed due to a
- /// "simple" conversion failure.
- static void emitBadConversionNotes(Sema &S, const InitializedEntity &entity,
- Expr *op) {
- QualType destType = entity.getType();
- if (destType.getNonReferenceType()->isObjCObjectPointerType() &&
- op->getType()->isObjCObjectPointerType()) {
- // Emit a possible note about the conversion failing because the
- // operand is a message send with a related result type.
- S.EmitRelatedResultTypeNote(op);
- // Emit a possible note about a return failing because we're
- // expecting a related result type.
- if (entity.getKind() == InitializedEntity::EK_Result)
- S.EmitRelatedResultTypeNoteForReturn(destType);
- }
- QualType fromType = op->getType();
- QualType fromPointeeType = fromType.getCanonicalType()->getPointeeType();
- QualType destPointeeType = destType.getCanonicalType()->getPointeeType();
- auto *fromDecl = fromType->getPointeeCXXRecordDecl();
- auto *destDecl = destType->getPointeeCXXRecordDecl();
- if (fromDecl && destDecl && fromDecl->getDeclKind() == Decl::CXXRecord &&
- destDecl->getDeclKind() == Decl::CXXRecord &&
- !fromDecl->isInvalidDecl() && !destDecl->isInvalidDecl() &&
- !fromDecl->hasDefinition() &&
- destPointeeType.getQualifiers().compatiblyIncludes(
- fromPointeeType.getQualifiers()))
- S.Diag(fromDecl->getLocation(), diag::note_forward_class_conversion)
- << S.getASTContext().getTagDeclType(fromDecl)
- << S.getASTContext().getTagDeclType(destDecl);
- }
- static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
- InitListExpr *InitList) {
- QualType DestType = Entity.getType();
- QualType E;
- if (S.getLangOpts().CPlusPlus11 && S.isStdInitializerList(DestType, &E)) {
- QualType ArrayType = S.Context.getConstantArrayType(
- E.withConst(),
- llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
- InitList->getNumInits()),
- nullptr, clang::ArrayType::Normal, 0);
- InitializedEntity HiddenArray =
- InitializedEntity::InitializeTemporary(ArrayType);
- return diagnoseListInit(S, HiddenArray, InitList);
- }
- if (DestType->isReferenceType()) {
- // A list-initialization failure for a reference means that we tried to
- // create a temporary of the inner type (per [dcl.init.list]p3.6) and the
- // inner initialization failed.
- QualType T = DestType->castAs<ReferenceType>()->getPointeeType();
- diagnoseListInit(S, InitializedEntity::InitializeTemporary(T), InitList);
- SourceLocation Loc = InitList->getBeginLoc();
- if (auto *D = Entity.getDecl())
- Loc = D->getLocation();
- S.Diag(Loc, diag::note_in_reference_temporary_list_initializer) << T;
- return;
- }
- InitListChecker DiagnoseInitList(S, Entity, InitList, DestType,
- /*VerifyOnly=*/false,
- /*TreatUnavailableAsInvalid=*/false);
- assert(DiagnoseInitList.HadError() &&
- "Inconsistent init list check result.");
- }
- bool InitializationSequence::Diagnose(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- ArrayRef<Expr *> Args) {
- if (!Failed())
- return false;
- // When we want to diagnose only one element of a braced-init-list,
- // we need to factor it out.
- Expr *OnlyArg;
- if (Args.size() == 1) {
- auto *List = dyn_cast<InitListExpr>(Args[0]);
- if (List && List->getNumInits() == 1)
- OnlyArg = List->getInit(0);
- else
- OnlyArg = Args[0];
- }
- else
- OnlyArg = nullptr;
- QualType DestType = Entity.getType();
- switch (Failure) {
- case FK_TooManyInitsForReference:
- // FIXME: Customize for the initialized entity?
- if (Args.empty()) {
- // Dig out the reference subobject which is uninitialized and diagnose it.
- // If this is value-initialization, this could be nested some way within
- // the target type.
- assert(Kind.getKind() == InitializationKind::IK_Value ||
- DestType->isReferenceType());
- bool Diagnosed =
- DiagnoseUninitializedReference(S, Kind.getLocation(), DestType);
- assert(Diagnosed && "couldn't find uninitialized reference to diagnose");
- (void)Diagnosed;
- } else // FIXME: diagnostic below could be better!
- S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits)
- << SourceRange(Args.front()->getBeginLoc(), Args.back()->getEndLoc());
- break;
- case FK_ParenthesizedListInitForReference:
- S.Diag(Kind.getLocation(), diag::err_list_init_in_parens)
- << 1 << Entity.getType() << Args[0]->getSourceRange();
- break;
- case FK_ArrayNeedsInitList:
- S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 0;
- break;
- case FK_ArrayNeedsInitListOrStringLiteral:
- S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 1;
- break;
- case FK_ArrayNeedsInitListOrWideStringLiteral:
- S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 2;
- break;
- case FK_NarrowStringIntoWideCharArray:
- S.Diag(Kind.getLocation(), diag::err_array_init_narrow_string_into_wchar);
- break;
- case FK_WideStringIntoCharArray:
- S.Diag(Kind.getLocation(), diag::err_array_init_wide_string_into_char);
- break;
- case FK_IncompatWideStringIntoWideChar:
- S.Diag(Kind.getLocation(),
- diag::err_array_init_incompat_wide_string_into_wchar);
- break;
- case FK_PlainStringIntoUTF8Char:
- S.Diag(Kind.getLocation(),
- diag::err_array_init_plain_string_into_char8_t);
- S.Diag(Args.front()->getBeginLoc(),
- diag::note_array_init_plain_string_into_char8_t)
- << FixItHint::CreateInsertion(Args.front()->getBeginLoc(), "u8");
- break;
- case FK_UTF8StringIntoPlainChar:
- S.Diag(Kind.getLocation(), diag::err_array_init_utf8_string_into_char)
- << DestType->isSignedIntegerType() << S.getLangOpts().CPlusPlus20;
- break;
- case FK_ArrayTypeMismatch:
- case FK_NonConstantArrayInit:
- S.Diag(Kind.getLocation(),
- (Failure == FK_ArrayTypeMismatch
- ? diag::err_array_init_different_type
- : diag::err_array_init_non_constant_array))
- << DestType.getNonReferenceType()
- << OnlyArg->getType()
- << Args[0]->getSourceRange();
- break;
- case FK_VariableLengthArrayHasInitializer:
- S.Diag(Kind.getLocation(), diag::err_variable_object_no_init)
- << Args[0]->getSourceRange();
- break;
- case FK_AddressOfOverloadFailed: {
- DeclAccessPair Found;
- S.ResolveAddressOfOverloadedFunction(OnlyArg,
- DestType.getNonReferenceType(),
- true,
- Found);
- break;
- }
- case FK_AddressOfUnaddressableFunction: {
- auto *FD = cast<FunctionDecl>(cast<DeclRefExpr>(OnlyArg)->getDecl());
- S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
- OnlyArg->getBeginLoc());
- break;
- }
- case FK_ReferenceInitOverloadFailed:
- case FK_UserConversionOverloadFailed:
- switch (FailedOverloadResult) {
- case OR_Ambiguous:
- FailedCandidateSet.NoteCandidates(
- PartialDiagnosticAt(
- Kind.getLocation(),
- Failure == FK_UserConversionOverloadFailed
- ? (S.PDiag(diag::err_typecheck_ambiguous_condition)
- << OnlyArg->getType() << DestType
- << Args[0]->getSourceRange())
- : (S.PDiag(diag::err_ref_init_ambiguous)
- << DestType << OnlyArg->getType()
- << Args[0]->getSourceRange())),
- S, OCD_AmbiguousCandidates, Args);
- break;
- case OR_No_Viable_Function: {
- auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args);
- if (!S.RequireCompleteType(Kind.getLocation(),
- DestType.getNonReferenceType(),
- diag::err_typecheck_nonviable_condition_incomplete,
- OnlyArg->getType(), Args[0]->getSourceRange()))
- S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
- << (Entity.getKind() == InitializedEntity::EK_Result)
- << OnlyArg->getType() << Args[0]->getSourceRange()
- << DestType.getNonReferenceType();
- FailedCandidateSet.NoteCandidates(S, Args, Cands);
- break;
- }
- case OR_Deleted: {
- S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
- << OnlyArg->getType() << DestType.getNonReferenceType()
- << Args[0]->getSourceRange();
- OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl
- = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
- if (Ovl == OR_Deleted) {
- S.NoteDeletedFunction(Best->Function);
- } else {
- llvm_unreachable("Inconsistent overload resolution?");
- }
- break;
- }
- case OR_Success:
- llvm_unreachable("Conversion did not fail!");
- }
- break;
- case FK_NonConstLValueReferenceBindingToTemporary:
- if (isa<InitListExpr>(Args[0])) {
- S.Diag(Kind.getLocation(),
- diag::err_lvalue_reference_bind_to_initlist)
- << DestType.getNonReferenceType().isVolatileQualified()
- << DestType.getNonReferenceType()
- << Args[0]->getSourceRange();
- break;
- }
- [[fallthrough]];
- case FK_NonConstLValueReferenceBindingToUnrelated:
- S.Diag(Kind.getLocation(),
- Failure == FK_NonConstLValueReferenceBindingToTemporary
- ? diag::err_lvalue_reference_bind_to_temporary
- : diag::err_lvalue_reference_bind_to_unrelated)
- << DestType.getNonReferenceType().isVolatileQualified()
- << DestType.getNonReferenceType()
- << OnlyArg->getType()
- << Args[0]->getSourceRange();
- break;
- case FK_NonConstLValueReferenceBindingToBitfield: {
- // We don't necessarily have an unambiguous source bit-field.
- FieldDecl *BitField = Args[0]->getSourceBitField();
- S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
- << DestType.isVolatileQualified()
- << (BitField ? BitField->getDeclName() : DeclarationName())
- << (BitField != nullptr)
- << Args[0]->getSourceRange();
- if (BitField)
- S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
- break;
- }
- case FK_NonConstLValueReferenceBindingToVectorElement:
- S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
- << DestType.isVolatileQualified()
- << Args[0]->getSourceRange();
- break;
- case FK_NonConstLValueReferenceBindingToMatrixElement:
- S.Diag(Kind.getLocation(), diag::err_reference_bind_to_matrix_element)
- << DestType.isVolatileQualified() << Args[0]->getSourceRange();
- break;
- case FK_RValueReferenceBindingToLValue:
- S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
- << DestType.getNonReferenceType() << OnlyArg->getType()
- << Args[0]->getSourceRange();
- break;
- case FK_ReferenceAddrspaceMismatchTemporary:
- S.Diag(Kind.getLocation(), diag::err_reference_bind_temporary_addrspace)
- << DestType << Args[0]->getSourceRange();
- break;
- case FK_ReferenceInitDropsQualifiers: {
- QualType SourceType = OnlyArg->getType();
- QualType NonRefType = DestType.getNonReferenceType();
- Qualifiers DroppedQualifiers =
- SourceType.getQualifiers() - NonRefType.getQualifiers();
- if (!NonRefType.getQualifiers().isAddressSpaceSupersetOf(
- SourceType.getQualifiers()))
- S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
- << NonRefType << SourceType << 1 /*addr space*/
- << Args[0]->getSourceRange();
- else if (DroppedQualifiers.hasQualifiers())
- S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
- << NonRefType << SourceType << 0 /*cv quals*/
- << Qualifiers::fromCVRMask(DroppedQualifiers.getCVRQualifiers())
- << DroppedQualifiers.getCVRQualifiers() << Args[0]->getSourceRange();
- else
- // FIXME: Consider decomposing the type and explaining which qualifiers
- // were dropped where, or on which level a 'const' is missing, etc.
- S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
- << NonRefType << SourceType << 2 /*incompatible quals*/
- << Args[0]->getSourceRange();
- break;
- }
- case FK_ReferenceInitFailed:
- S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
- << DestType.getNonReferenceType()
- << DestType.getNonReferenceType()->isIncompleteType()
- << OnlyArg->isLValue()
- << OnlyArg->getType()
- << Args[0]->getSourceRange();
- emitBadConversionNotes(S, Entity, Args[0]);
- break;
- case FK_ConversionFailed: {
- QualType FromType = OnlyArg->getType();
- PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
- << (int)Entity.getKind()
- << DestType
- << OnlyArg->isLValue()
- << FromType
- << Args[0]->getSourceRange();
- S.HandleFunctionTypeMismatch(PDiag, FromType, DestType);
- S.Diag(Kind.getLocation(), PDiag);
- emitBadConversionNotes(S, Entity, Args[0]);
- break;
- }
- case FK_ConversionFromPropertyFailed:
- // No-op. This error has already been reported.
- break;
- case FK_TooManyInitsForScalar: {
- SourceRange R;
- auto *InitList = dyn_cast<InitListExpr>(Args[0]);
- if (InitList && InitList->getNumInits() >= 1) {
- R = SourceRange(InitList->getInit(0)->getEndLoc(), InitList->getEndLoc());
- } else {
- assert(Args.size() > 1 && "Expected multiple initializers!");
- R = SourceRange(Args.front()->getEndLoc(), Args.back()->getEndLoc());
- }
- R.setBegin(S.getLocForEndOfToken(R.getBegin()));
- if (Kind.isCStyleOrFunctionalCast())
- S.Diag(Kind.getLocation(), diag::err_builtin_func_cast_more_than_one_arg)
- << R;
- else
- S.Diag(Kind.getLocation(), diag::err_excess_initializers)
- << /*scalar=*/2 << R;
- break;
- }
- case FK_ParenthesizedListInitForScalar:
- S.Diag(Kind.getLocation(), diag::err_list_init_in_parens)
- << 0 << Entity.getType() << Args[0]->getSourceRange();
- break;
- case FK_ReferenceBindingToInitList:
- S.Diag(Kind.getLocation(), diag::err_reference_bind_init_list)
- << DestType.getNonReferenceType() << Args[0]->getSourceRange();
- break;
- case FK_InitListBadDestinationType:
- S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type)
- << (DestType->isRecordType()) << DestType << Args[0]->getSourceRange();
- break;
- case FK_ListConstructorOverloadFailed:
- case FK_ConstructorOverloadFailed: {
- SourceRange ArgsRange;
- if (Args.size())
- ArgsRange =
- SourceRange(Args.front()->getBeginLoc(), Args.back()->getEndLoc());
- if (Failure == FK_ListConstructorOverloadFailed) {
- assert(Args.size() == 1 &&
- "List construction from other than 1 argument.");
- InitListExpr *InitList = cast<InitListExpr>(Args[0]);
- Args = MultiExprArg(InitList->getInits(), InitList->getNumInits());
- }
- // FIXME: Using "DestType" for the entity we're printing is probably
- // bad.
- switch (FailedOverloadResult) {
- case OR_Ambiguous:
- FailedCandidateSet.NoteCandidates(
- PartialDiagnosticAt(Kind.getLocation(),
- S.PDiag(diag::err_ovl_ambiguous_init)
- << DestType << ArgsRange),
- S, OCD_AmbiguousCandidates, Args);
- break;
- case OR_No_Viable_Function:
- if (Kind.getKind() == InitializationKind::IK_Default &&
- (Entity.getKind() == InitializedEntity::EK_Base ||
- Entity.getKind() == InitializedEntity::EK_Member) &&
- isa<CXXConstructorDecl>(S.CurContext)) {
- // This is implicit default initialization of a member or
- // base within a constructor. If no viable function was
- // found, notify the user that they need to explicitly
- // initialize this base/member.
- CXXConstructorDecl *Constructor
- = cast<CXXConstructorDecl>(S.CurContext);
- const CXXRecordDecl *InheritedFrom = nullptr;
- if (auto Inherited = Constructor->getInheritedConstructor())
- InheritedFrom = Inherited.getShadowDecl()->getNominatedBaseClass();
- if (Entity.getKind() == InitializedEntity::EK_Base) {
- S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
- << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*base=*/0
- << Entity.getType()
- << InheritedFrom;
- RecordDecl *BaseDecl
- = Entity.getBaseSpecifier()->getType()->castAs<RecordType>()
- ->getDecl();
- S.Diag(BaseDecl->getLocation(), diag::note_previous_decl)
- << S.Context.getTagDeclType(BaseDecl);
- } else {
- S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
- << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*member=*/1
- << Entity.getName()
- << InheritedFrom;
- S.Diag(Entity.getDecl()->getLocation(),
- diag::note_member_declared_at);
- if (const RecordType *Record
- = Entity.getType()->getAs<RecordType>())
- S.Diag(Record->getDecl()->getLocation(),
- diag::note_previous_decl)
- << S.Context.getTagDeclType(Record->getDecl());
- }
- break;
- }
- FailedCandidateSet.NoteCandidates(
- PartialDiagnosticAt(
- Kind.getLocation(),
- S.PDiag(diag::err_ovl_no_viable_function_in_init)
- << DestType << ArgsRange),
- S, OCD_AllCandidates, Args);
- break;
- case OR_Deleted: {
- OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl
- = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
- if (Ovl != OR_Deleted) {
- S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
- << DestType << ArgsRange;
- llvm_unreachable("Inconsistent overload resolution?");
- break;
- }
- // If this is a defaulted or implicitly-declared function, then
- // it was implicitly deleted. Make it clear that the deletion was
- // implicit.
- if (S.isImplicitlyDeleted(Best->Function))
- S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
- << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))
- << DestType << ArgsRange;
- else
- S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
- << DestType << ArgsRange;
- S.NoteDeletedFunction(Best->Function);
- break;
- }
- case OR_Success:
- llvm_unreachable("Conversion did not fail!");
- }
- }
- break;
- case FK_DefaultInitOfConst:
- if (Entity.getKind() == InitializedEntity::EK_Member &&
- isa<CXXConstructorDecl>(S.CurContext)) {
- // This is implicit default-initialization of a const member in
- // a constructor. Complain that it needs to be explicitly
- // initialized.
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(S.CurContext);
- S.Diag(Kind.getLocation(), diag::err_uninitialized_member_in_ctor)
- << (Constructor->getInheritedConstructor() ? 2 :
- Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*const=*/1
- << Entity.getName();
- S.Diag(Entity.getDecl()->getLocation(), diag::note_previous_decl)
- << Entity.getName();
- } else if (const auto *VD = dyn_cast_if_present<VarDecl>(Entity.getDecl());
- VD && VD->isConstexpr()) {
- S.Diag(Kind.getLocation(), diag::err_constexpr_var_requires_const_init)
- << VD;
- } else {
- S.Diag(Kind.getLocation(), diag::err_default_init_const)
- << DestType << (bool)DestType->getAs<RecordType>();
- }
- break;
- case FK_Incomplete:
- S.RequireCompleteType(Kind.getLocation(), FailedIncompleteType,
- diag::err_init_incomplete_type);
- break;
- case FK_ListInitializationFailed: {
- // Run the init list checker again to emit diagnostics.
- InitListExpr *InitList = cast<InitListExpr>(Args[0]);
- diagnoseListInit(S, Entity, InitList);
- break;
- }
- case FK_PlaceholderType: {
- // FIXME: Already diagnosed!
- break;
- }
- case FK_ExplicitConstructor: {
- S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor)
- << Args[0]->getSourceRange();
- OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl
- = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
- (void)Ovl;
- assert(Ovl == OR_Success && "Inconsistent overload resolution");
- CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
- S.Diag(CtorDecl->getLocation(),
- diag::note_explicit_ctor_deduction_guide_here) << false;
- break;
- }
- case FK_ParenthesizedListInitFailed:
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/false);
- break;
- }
- PrintInitLocationNote(S, Entity);
- return true;
- }
- void InitializationSequence::dump(raw_ostream &OS) const {
- switch (SequenceKind) {
- case FailedSequence: {
- OS << "Failed sequence: ";
- switch (Failure) {
- case FK_TooManyInitsForReference:
- OS << "too many initializers for reference";
- break;
- case FK_ParenthesizedListInitForReference:
- OS << "parenthesized list init for reference";
- break;
- case FK_ArrayNeedsInitList:
- OS << "array requires initializer list";
- break;
- case FK_AddressOfUnaddressableFunction:
- OS << "address of unaddressable function was taken";
- break;
- case FK_ArrayNeedsInitListOrStringLiteral:
- OS << "array requires initializer list or string literal";
- break;
- case FK_ArrayNeedsInitListOrWideStringLiteral:
- OS << "array requires initializer list or wide string literal";
- break;
- case FK_NarrowStringIntoWideCharArray:
- OS << "narrow string into wide char array";
- break;
- case FK_WideStringIntoCharArray:
- OS << "wide string into char array";
- break;
- case FK_IncompatWideStringIntoWideChar:
- OS << "incompatible wide string into wide char array";
- break;
- case FK_PlainStringIntoUTF8Char:
- OS << "plain string literal into char8_t array";
- break;
- case FK_UTF8StringIntoPlainChar:
- OS << "u8 string literal into char array";
- break;
- case FK_ArrayTypeMismatch:
- OS << "array type mismatch";
- break;
- case FK_NonConstantArrayInit:
- OS << "non-constant array initializer";
- break;
- case FK_AddressOfOverloadFailed:
- OS << "address of overloaded function failed";
- break;
- case FK_ReferenceInitOverloadFailed:
- OS << "overload resolution for reference initialization failed";
- break;
- case FK_NonConstLValueReferenceBindingToTemporary:
- OS << "non-const lvalue reference bound to temporary";
- break;
- case FK_NonConstLValueReferenceBindingToBitfield:
- OS << "non-const lvalue reference bound to bit-field";
- break;
- case FK_NonConstLValueReferenceBindingToVectorElement:
- OS << "non-const lvalue reference bound to vector element";
- break;
- case FK_NonConstLValueReferenceBindingToMatrixElement:
- OS << "non-const lvalue reference bound to matrix element";
- break;
- case FK_NonConstLValueReferenceBindingToUnrelated:
- OS << "non-const lvalue reference bound to unrelated type";
- break;
- case FK_RValueReferenceBindingToLValue:
- OS << "rvalue reference bound to an lvalue";
- break;
- case FK_ReferenceInitDropsQualifiers:
- OS << "reference initialization drops qualifiers";
- break;
- case FK_ReferenceAddrspaceMismatchTemporary:
- OS << "reference with mismatching address space bound to temporary";
- break;
- case FK_ReferenceInitFailed:
- OS << "reference initialization failed";
- break;
- case FK_ConversionFailed:
- OS << "conversion failed";
- break;
- case FK_ConversionFromPropertyFailed:
- OS << "conversion from property failed";
- break;
- case FK_TooManyInitsForScalar:
- OS << "too many initializers for scalar";
- break;
- case FK_ParenthesizedListInitForScalar:
- OS << "parenthesized list init for reference";
- break;
- case FK_ReferenceBindingToInitList:
- OS << "referencing binding to initializer list";
- break;
- case FK_InitListBadDestinationType:
- OS << "initializer list for non-aggregate, non-scalar type";
- break;
- case FK_UserConversionOverloadFailed:
- OS << "overloading failed for user-defined conversion";
- break;
- case FK_ConstructorOverloadFailed:
- OS << "constructor overloading failed";
- break;
- case FK_DefaultInitOfConst:
- OS << "default initialization of a const variable";
- break;
- case FK_Incomplete:
- OS << "initialization of incomplete type";
- break;
- case FK_ListInitializationFailed:
- OS << "list initialization checker failure";
- break;
- case FK_VariableLengthArrayHasInitializer:
- OS << "variable length array has an initializer";
- break;
- case FK_PlaceholderType:
- OS << "initializer expression isn't contextually valid";
- break;
- case FK_ListConstructorOverloadFailed:
- OS << "list constructor overloading failed";
- break;
- case FK_ExplicitConstructor:
- OS << "list copy initialization chose explicit constructor";
- break;
- case FK_ParenthesizedListInitFailed:
- OS << "parenthesized list initialization failed";
- break;
- }
- OS << '\n';
- return;
- }
- case DependentSequence:
- OS << "Dependent sequence\n";
- return;
- case NormalSequence:
- OS << "Normal sequence: ";
- break;
- }
- for (step_iterator S = step_begin(), SEnd = step_end(); S != SEnd; ++S) {
- if (S != step_begin()) {
- OS << " -> ";
- }
- switch (S->Kind) {
- case SK_ResolveAddressOfOverloadedFunction:
- OS << "resolve address of overloaded function";
- break;
- case SK_CastDerivedToBasePRValue:
- OS << "derived-to-base (prvalue)";
- break;
- case SK_CastDerivedToBaseXValue:
- OS << "derived-to-base (xvalue)";
- break;
- case SK_CastDerivedToBaseLValue:
- OS << "derived-to-base (lvalue)";
- break;
- case SK_BindReference:
- OS << "bind reference to lvalue";
- break;
- case SK_BindReferenceToTemporary:
- OS << "bind reference to a temporary";
- break;
- case SK_FinalCopy:
- OS << "final copy in class direct-initialization";
- break;
- case SK_ExtraneousCopyToTemporary:
- OS << "extraneous C++03 copy to temporary";
- break;
- case SK_UserConversion:
- OS << "user-defined conversion via " << *S->Function.Function;
- break;
- case SK_QualificationConversionPRValue:
- OS << "qualification conversion (prvalue)";
- break;
- case SK_QualificationConversionXValue:
- OS << "qualification conversion (xvalue)";
- break;
- case SK_QualificationConversionLValue:
- OS << "qualification conversion (lvalue)";
- break;
- case SK_FunctionReferenceConversion:
- OS << "function reference conversion";
- break;
- case SK_AtomicConversion:
- OS << "non-atomic-to-atomic conversion";
- break;
- case SK_ConversionSequence:
- OS << "implicit conversion sequence (";
- S->ICS->dump(); // FIXME: use OS
- OS << ")";
- break;
- case SK_ConversionSequenceNoNarrowing:
- OS << "implicit conversion sequence with narrowing prohibited (";
- S->ICS->dump(); // FIXME: use OS
- OS << ")";
- break;
- case SK_ListInitialization:
- OS << "list aggregate initialization";
- break;
- case SK_UnwrapInitList:
- OS << "unwrap reference initializer list";
- break;
- case SK_RewrapInitList:
- OS << "rewrap reference initializer list";
- break;
- case SK_ConstructorInitialization:
- OS << "constructor initialization";
- break;
- case SK_ConstructorInitializationFromList:
- OS << "list initialization via constructor";
- break;
- case SK_ZeroInitialization:
- OS << "zero initialization";
- break;
- case SK_CAssignment:
- OS << "C assignment";
- break;
- case SK_StringInit:
- OS << "string initialization";
- break;
- case SK_ObjCObjectConversion:
- OS << "Objective-C object conversion";
- break;
- case SK_ArrayLoopIndex:
- OS << "indexing for array initialization loop";
- break;
- case SK_ArrayLoopInit:
- OS << "array initialization loop";
- break;
- case SK_ArrayInit:
- OS << "array initialization";
- break;
- case SK_GNUArrayInit:
- OS << "array initialization (GNU extension)";
- break;
- case SK_ParenthesizedArrayInit:
- OS << "parenthesized array initialization";
- break;
- case SK_PassByIndirectCopyRestore:
- OS << "pass by indirect copy and restore";
- break;
- case SK_PassByIndirectRestore:
- OS << "pass by indirect restore";
- break;
- case SK_ProduceObjCObject:
- OS << "Objective-C object retension";
- break;
- case SK_StdInitializerList:
- OS << "std::initializer_list from initializer list";
- break;
- case SK_StdInitializerListConstructorCall:
- OS << "list initialization from std::initializer_list";
- break;
- case SK_OCLSamplerInit:
- OS << "OpenCL sampler_t from integer constant";
- break;
- case SK_OCLZeroOpaqueType:
- OS << "OpenCL opaque type from zero";
- break;
- case SK_ParenthesizedListInit:
- OS << "initialization from a parenthesized list of values";
- break;
- }
- OS << " [" << S->Type << ']';
- }
- OS << '\n';
- }
- void InitializationSequence::dump() const {
- dump(llvm::errs());
- }
- static bool NarrowingErrs(const LangOptions &L) {
- return L.CPlusPlus11 &&
- (!L.MicrosoftExt || L.isCompatibleWithMSVC(LangOptions::MSVC2015));
- }
- static void DiagnoseNarrowingInInitList(Sema &S,
- const ImplicitConversionSequence &ICS,
- QualType PreNarrowingType,
- QualType EntityType,
- const Expr *PostInit) {
- const StandardConversionSequence *SCS = nullptr;
- switch (ICS.getKind()) {
- case ImplicitConversionSequence::StandardConversion:
- SCS = &ICS.Standard;
- break;
- case ImplicitConversionSequence::UserDefinedConversion:
- SCS = &ICS.UserDefined.After;
- break;
- case ImplicitConversionSequence::AmbiguousConversion:
- case ImplicitConversionSequence::StaticObjectArgumentConversion:
- case ImplicitConversionSequence::EllipsisConversion:
- case ImplicitConversionSequence::BadConversion:
- return;
- }
- // C++11 [dcl.init.list]p7: Check whether this is a narrowing conversion.
- APValue ConstantValue;
- QualType ConstantType;
- switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue,
- ConstantType)) {
- case NK_Not_Narrowing:
- case NK_Dependent_Narrowing:
- // No narrowing occurred.
- return;
- case NK_Type_Narrowing:
- // This was a floating-to-integer conversion, which is always considered a
- // narrowing conversion even if the value is a constant and can be
- // represented exactly as an integer.
- S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_type_narrowing
- : diag::warn_init_list_type_narrowing)
- << PostInit->getSourceRange()
- << PreNarrowingType.getLocalUnqualifiedType()
- << EntityType.getLocalUnqualifiedType();
- break;
- case NK_Constant_Narrowing:
- // A constant value was narrowed.
- S.Diag(PostInit->getBeginLoc(),
- NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_constant_narrowing
- : diag::warn_init_list_constant_narrowing)
- << PostInit->getSourceRange()
- << ConstantValue.getAsString(S.getASTContext(), ConstantType)
- << EntityType.getLocalUnqualifiedType();
- break;
- case NK_Variable_Narrowing:
- // A variable's value may have been narrowed.
- S.Diag(PostInit->getBeginLoc(),
- NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_variable_narrowing
- : diag::warn_init_list_variable_narrowing)
- << PostInit->getSourceRange()
- << PreNarrowingType.getLocalUnqualifiedType()
- << EntityType.getLocalUnqualifiedType();
- break;
- }
- SmallString<128> StaticCast;
- llvm::raw_svector_ostream OS(StaticCast);
- OS << "static_cast<";
- if (const TypedefType *TT = EntityType->getAs<TypedefType>()) {
- // It's important to use the typedef's name if there is one so that the
- // fixit doesn't break code using types like int64_t.
- //
- // FIXME: This will break if the typedef requires qualification. But
- // getQualifiedNameAsString() includes non-machine-parsable components.
- OS << *TT->getDecl();
- } else if (const BuiltinType *BT = EntityType->getAs<BuiltinType>())
- OS << BT->getName(S.getLangOpts());
- else {
- // Oops, we didn't find the actual type of the variable. Don't emit a fixit
- // with a broken cast.
- return;
- }
- OS << ">(";
- S.Diag(PostInit->getBeginLoc(), diag::note_init_list_narrowing_silence)
- << PostInit->getSourceRange()
- << FixItHint::CreateInsertion(PostInit->getBeginLoc(), OS.str())
- << FixItHint::CreateInsertion(
- S.getLocForEndOfToken(PostInit->getEndLoc()), ")");
- }
- //===----------------------------------------------------------------------===//
- // Initialization helper functions
- //===----------------------------------------------------------------------===//
- bool
- Sema::CanPerformCopyInitialization(const InitializedEntity &Entity,
- ExprResult Init) {
- if (Init.isInvalid())
- return false;
- Expr *InitE = Init.get();
- assert(InitE && "No initialization expression");
- InitializationKind Kind =
- InitializationKind::CreateCopy(InitE->getBeginLoc(), SourceLocation());
- InitializationSequence Seq(*this, Entity, Kind, InitE);
- return !Seq.Failed();
- }
- ExprResult
- Sema::PerformCopyInitialization(const InitializedEntity &Entity,
- SourceLocation EqualLoc,
- ExprResult Init,
- bool TopLevelOfInitList,
- bool AllowExplicit) {
- if (Init.isInvalid())
- return ExprError();
- Expr *InitE = Init.get();
- assert(InitE && "No initialization expression?");
- if (EqualLoc.isInvalid())
- EqualLoc = InitE->getBeginLoc();
- InitializationKind Kind = InitializationKind::CreateCopy(
- InitE->getBeginLoc(), EqualLoc, AllowExplicit);
- InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
- // Prevent infinite recursion when performing parameter copy-initialization.
- const bool ShouldTrackCopy =
- Entity.isParameterKind() && Seq.isConstructorInitialization();
- if (ShouldTrackCopy) {
- if (llvm::is_contained(CurrentParameterCopyTypes, Entity.getType())) {
- Seq.SetOverloadFailure(
- InitializationSequence::FK_ConstructorOverloadFailed,
- OR_No_Viable_Function);
- // Try to give a meaningful diagnostic note for the problematic
- // constructor.
- const auto LastStep = Seq.step_end() - 1;
- assert(LastStep->Kind ==
- InitializationSequence::SK_ConstructorInitialization);
- const FunctionDecl *Function = LastStep->Function.Function;
- auto Candidate =
- llvm::find_if(Seq.getFailedCandidateSet(),
- [Function](const OverloadCandidate &Candidate) -> bool {
- return Candidate.Viable &&
- Candidate.Function == Function &&
- Candidate.Conversions.size() > 0;
- });
- if (Candidate != Seq.getFailedCandidateSet().end() &&
- Function->getNumParams() > 0) {
- Candidate->Viable = false;
- Candidate->FailureKind = ovl_fail_bad_conversion;
- Candidate->Conversions[0].setBad(BadConversionSequence::no_conversion,
- InitE,
- Function->getParamDecl(0)->getType());
- }
- }
- CurrentParameterCopyTypes.push_back(Entity.getType());
- }
- ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
- if (ShouldTrackCopy)
- CurrentParameterCopyTypes.pop_back();
- return Result;
- }
- /// Determine whether RD is, or is derived from, a specialization of CTD.
- static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD,
- ClassTemplateDecl *CTD) {
- auto NotSpecialization = [&] (const CXXRecordDecl *Candidate) {
- auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Candidate);
- return !CTSD || !declaresSameEntity(CTSD->getSpecializedTemplate(), CTD);
- };
- return !(NotSpecialization(RD) && RD->forallBases(NotSpecialization));
- }
- QualType Sema::DeduceTemplateSpecializationFromInitializer(
- TypeSourceInfo *TSInfo, const InitializedEntity &Entity,
- const InitializationKind &Kind, MultiExprArg Inits) {
- auto *DeducedTST = dyn_cast<DeducedTemplateSpecializationType>(
- TSInfo->getType()->getContainedDeducedType());
- assert(DeducedTST && "not a deduced template specialization type");
- auto TemplateName = DeducedTST->getTemplateName();
- if (TemplateName.isDependent())
- return SubstAutoTypeDependent(TSInfo->getType());
- // We can only perform deduction for class templates.
- auto *Template =
- dyn_cast_or_null<ClassTemplateDecl>(TemplateName.getAsTemplateDecl());
- if (!Template) {
- Diag(Kind.getLocation(),
- diag::err_deduced_non_class_template_specialization_type)
- << (int)getTemplateNameKindForDiagnostics(TemplateName) << TemplateName;
- if (auto *TD = TemplateName.getAsTemplateDecl())
- Diag(TD->getLocation(), diag::note_template_decl_here);
- return QualType();
- }
- // Can't deduce from dependent arguments.
- if (Expr::hasAnyTypeDependentArguments(Inits)) {
- Diag(TSInfo->getTypeLoc().getBeginLoc(),
- diag::warn_cxx14_compat_class_template_argument_deduction)
- << TSInfo->getTypeLoc().getSourceRange() << 0;
- return SubstAutoTypeDependent(TSInfo->getType());
- }
- // FIXME: Perform "exact type" matching first, per CWG discussion?
- // Or implement this via an implied 'T(T) -> T' deduction guide?
- // FIXME: Do we need/want a std::initializer_list<T> special case?
- // Look up deduction guides, including those synthesized from constructors.
- //
- // C++1z [over.match.class.deduct]p1:
- // A set of functions and function templates is formed comprising:
- // - For each constructor of the class template designated by the
- // template-name, a function template [...]
- // - For each deduction-guide, a function or function template [...]
- DeclarationNameInfo NameInfo(
- Context.DeclarationNames.getCXXDeductionGuideName(Template),
- TSInfo->getTypeLoc().getEndLoc());
- LookupResult Guides(*this, NameInfo, LookupOrdinaryName);
- LookupQualifiedName(Guides, Template->getDeclContext());
- // FIXME: Do not diagnose inaccessible deduction guides. The standard isn't
- // clear on this, but they're not found by name so access does not apply.
- Guides.suppressDiagnostics();
- // Figure out if this is list-initialization.
- InitListExpr *ListInit =
- (Inits.size() == 1 && Kind.getKind() != InitializationKind::IK_Direct)
- ? dyn_cast<InitListExpr>(Inits[0])
- : nullptr;
- // C++1z [over.match.class.deduct]p1:
- // Initialization and overload resolution are performed as described in
- // [dcl.init] and [over.match.ctor], [over.match.copy], or [over.match.list]
- // (as appropriate for the type of initialization performed) for an object
- // of a hypothetical class type, where the selected functions and function
- // templates are considered to be the constructors of that class type
- //
- // Since we know we're initializing a class type of a type unrelated to that
- // of the initializer, this reduces to something fairly reasonable.
- OverloadCandidateSet Candidates(Kind.getLocation(),
- OverloadCandidateSet::CSK_Normal);
- OverloadCandidateSet::iterator Best;
- bool HasAnyDeductionGuide = false;
- bool AllowExplicit = !Kind.isCopyInit() || ListInit;
- auto tryToResolveOverload =
- [&](bool OnlyListConstructors) -> OverloadingResult {
- Candidates.clear(OverloadCandidateSet::CSK_Normal);
- HasAnyDeductionGuide = false;
- for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) {
- NamedDecl *D = (*I)->getUnderlyingDecl();
- if (D->isInvalidDecl())
- continue;
- auto *TD = dyn_cast<FunctionTemplateDecl>(D);
- auto *GD = dyn_cast_or_null<CXXDeductionGuideDecl>(
- TD ? TD->getTemplatedDecl() : dyn_cast<FunctionDecl>(D));
- if (!GD)
- continue;
- if (!GD->isImplicit())
- HasAnyDeductionGuide = true;
- // C++ [over.match.ctor]p1: (non-list copy-initialization from non-class)
- // For copy-initialization, the candidate functions are all the
- // converting constructors (12.3.1) of that class.
- // C++ [over.match.copy]p1: (non-list copy-initialization from class)
- // The converting constructors of T are candidate functions.
- if (!AllowExplicit) {
- // Overload resolution checks whether the deduction guide is declared
- // explicit for us.
- // When looking for a converting constructor, deduction guides that
- // could never be called with one argument are not interesting to
- // check or note.
- if (GD->getMinRequiredArguments() > 1 ||
- (GD->getNumParams() == 0 && !GD->isVariadic()))
- continue;
- }
- // C++ [over.match.list]p1.1: (first phase list initialization)
- // Initially, the candidate functions are the initializer-list
- // constructors of the class T
- if (OnlyListConstructors && !isInitListConstructor(GD))
- continue;
- // C++ [over.match.list]p1.2: (second phase list initialization)
- // the candidate functions are all the constructors of the class T
- // C++ [over.match.ctor]p1: (all other cases)
- // the candidate functions are all the constructors of the class of
- // the object being initialized
- // C++ [over.best.ics]p4:
- // When [...] the constructor [...] is a candidate by
- // - [over.match.copy] (in all cases)
- // FIXME: The "second phase of [over.match.list] case can also
- // theoretically happen here, but it's not clear whether we can
- // ever have a parameter of the right type.
- bool SuppressUserConversions = Kind.isCopyInit();
- if (TD)
- AddTemplateOverloadCandidate(TD, I.getPair(), /*ExplicitArgs*/ nullptr,
- Inits, Candidates, SuppressUserConversions,
- /*PartialOverloading*/ false,
- AllowExplicit);
- else
- AddOverloadCandidate(GD, I.getPair(), Inits, Candidates,
- SuppressUserConversions,
- /*PartialOverloading*/ false, AllowExplicit);
- }
- return Candidates.BestViableFunction(*this, Kind.getLocation(), Best);
- };
- OverloadingResult Result = OR_No_Viable_Function;
- // C++11 [over.match.list]p1, per DR1467: for list-initialization, first
- // try initializer-list constructors.
- if (ListInit) {
- bool TryListConstructors = true;
- // Try list constructors unless the list is empty and the class has one or
- // more default constructors, in which case those constructors win.
- if (!ListInit->getNumInits()) {
- for (NamedDecl *D : Guides) {
- auto *FD = dyn_cast<FunctionDecl>(D->getUnderlyingDecl());
- if (FD && FD->getMinRequiredArguments() == 0) {
- TryListConstructors = false;
- break;
- }
- }
- } else if (ListInit->getNumInits() == 1) {
- // C++ [over.match.class.deduct]:
- // As an exception, the first phase in [over.match.list] (considering
- // initializer-list constructors) is omitted if the initializer list
- // consists of a single expression of type cv U, where U is a
- // specialization of C or a class derived from a specialization of C.
- Expr *E = ListInit->getInit(0);
- auto *RD = E->getType()->getAsCXXRecordDecl();
- if (!isa<InitListExpr>(E) && RD &&
- isCompleteType(Kind.getLocation(), E->getType()) &&
- isOrIsDerivedFromSpecializationOf(RD, Template))
- TryListConstructors = false;
- }
- if (TryListConstructors)
- Result = tryToResolveOverload(/*OnlyListConstructor*/true);
- // Then unwrap the initializer list and try again considering all
- // constructors.
- Inits = MultiExprArg(ListInit->getInits(), ListInit->getNumInits());
- }
- // If list-initialization fails, or if we're doing any other kind of
- // initialization, we (eventually) consider constructors.
- if (Result == OR_No_Viable_Function)
- Result = tryToResolveOverload(/*OnlyListConstructor*/false);
- switch (Result) {
- case OR_Ambiguous:
- // FIXME: For list-initialization candidates, it'd usually be better to
- // list why they were not viable when given the initializer list itself as
- // an argument.
- Candidates.NoteCandidates(
- PartialDiagnosticAt(
- Kind.getLocation(),
- PDiag(diag::err_deduced_class_template_ctor_ambiguous)
- << TemplateName),
- *this, OCD_AmbiguousCandidates, Inits);
- return QualType();
- case OR_No_Viable_Function: {
- CXXRecordDecl *Primary =
- cast<ClassTemplateDecl>(Template)->getTemplatedDecl();
- bool Complete =
- isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary));
- Candidates.NoteCandidates(
- PartialDiagnosticAt(
- Kind.getLocation(),
- PDiag(Complete ? diag::err_deduced_class_template_ctor_no_viable
- : diag::err_deduced_class_template_incomplete)
- << TemplateName << !Guides.empty()),
- *this, OCD_AllCandidates, Inits);
- return QualType();
- }
- case OR_Deleted: {
- Diag(Kind.getLocation(), diag::err_deduced_class_template_deleted)
- << TemplateName;
- NoteDeletedFunction(Best->Function);
- return QualType();
- }
- case OR_Success:
- // C++ [over.match.list]p1:
- // In copy-list-initialization, if an explicit constructor is chosen, the
- // initialization is ill-formed.
- if (Kind.isCopyInit() && ListInit &&
- cast<CXXDeductionGuideDecl>(Best->Function)->isExplicit()) {
- bool IsDeductionGuide = !Best->Function->isImplicit();
- Diag(Kind.getLocation(), diag::err_deduced_class_template_explicit)
- << TemplateName << IsDeductionGuide;
- Diag(Best->Function->getLocation(),
- diag::note_explicit_ctor_deduction_guide_here)
- << IsDeductionGuide;
- return QualType();
- }
- // Make sure we didn't select an unusable deduction guide, and mark it
- // as referenced.
- DiagnoseUseOfDecl(Best->Function, Kind.getLocation());
- MarkFunctionReferenced(Kind.getLocation(), Best->Function);
- break;
- }
- // C++ [dcl.type.class.deduct]p1:
- // The placeholder is replaced by the return type of the function selected
- // by overload resolution for class template deduction.
- QualType DeducedType =
- SubstAutoType(TSInfo->getType(), Best->Function->getReturnType());
- Diag(TSInfo->getTypeLoc().getBeginLoc(),
- diag::warn_cxx14_compat_class_template_argument_deduction)
- << TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType;
- // Warn if CTAD was used on a type that does not have any user-defined
- // deduction guides.
- if (!HasAnyDeductionGuide) {
- Diag(TSInfo->getTypeLoc().getBeginLoc(),
- diag::warn_ctad_maybe_unsupported)
- << TemplateName;
- Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported);
- }
- return DeducedType;
- }
|