1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229 |
- //===--- 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();
- switch (SL->getKind()) {
- case StringLiteral::UTF8:
- // char8_t array can be initialized with a UTF-8 string.
- if (ElemTy->isChar8Type())
- return SIF_None;
- LLVM_FALLTHROUGH;
- case StringLiteral::Ascii:
- // 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)
- << 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, None, 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, None, 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->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 two initializers, this extension kicks in:
- // it exepcts 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) {
- // 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 initializers allows 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 requires 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 (SemaRef.getLangOpts().CPlusPlus) {
- // Disallow flexible array init in C++; it is not required for gcc
- // compatibility, and it needs work to IRGen correctly in general.
- FlexArrayDiag = diag::err_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();
- 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;
- }
- 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 (CharTy->isPromotableIntegerType())
- 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(), None,
- 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().getAsString() << "'\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:
- 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:
- 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::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()->isIntegralOrEnumerationType() ||
- 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, 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, None, 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;
- }
- }
- /// 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 (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);
- // - 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).
- else
- TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
- TopLevelOfInitList);
- return;
- }
- assert(Args.size() >= 1 && "Zero-argument case handled above");
- // 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::makeArrayRef(CE->getArgs(), CE->getNumArgs());
- } else {
- auto *CCE = cast<CXXConstructExpr>(Call);
- Callee = CCE->getConstructor();
- Args = llvm::makeArrayRef(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();
- LLVM_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 (auto It = Path.rbegin(), End = Path.rend(); It != End; ++It) {
- 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 VarDecl *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()) {
- unsigned DiagID = diag::err_default_init_const;
- if (Decl *D = Entity.getDecl())
- if (S.getLangOpts().MSVCCompat && D->hasAttr<SelectAnyAttr>())
- DiagID = diag::ext_default_init_const;
- // 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.
- QualType DestType = Entity.getType();
- 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;
- // 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);
- CurInit = Args[0];
- if (!CurInit.get()) return ExprError();
- break;
- }
- case SK_ConstructorInitialization:
- case SK_ConstructorInitializationFromList:
- case SK_StdInitializerListConstructorCall:
- case SK_ZeroInitialization:
- 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);
- 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());
- LLVM_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;
- }
- }
- }
- // 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)
- << 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;
- }
- LLVM_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 {
- 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;
- }
- }
- 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;
- }
- 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;
- }
- OS << " [" << S->Type.getAsString() << ']';
- }
- 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::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;
- }
|