lint.go 146 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215
  1. package staticcheck
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/constant"
  6. "go/token"
  7. "go/types"
  8. htmltemplate "html/template"
  9. "net/http"
  10. "os"
  11. "reflect"
  12. "regexp"
  13. "regexp/syntax"
  14. "sort"
  15. "strconv"
  16. "strings"
  17. texttemplate "text/template"
  18. "unicode"
  19. "honnef.co/go/tools/analysis/code"
  20. "honnef.co/go/tools/analysis/edit"
  21. "honnef.co/go/tools/analysis/facts"
  22. "honnef.co/go/tools/analysis/facts/nilness"
  23. "honnef.co/go/tools/analysis/facts/typedness"
  24. "honnef.co/go/tools/analysis/lint"
  25. "honnef.co/go/tools/analysis/report"
  26. "honnef.co/go/tools/go/ast/astutil"
  27. "honnef.co/go/tools/go/ir"
  28. "honnef.co/go/tools/go/ir/irutil"
  29. "honnef.co/go/tools/go/types/typeutil"
  30. "honnef.co/go/tools/internal/passes/buildir"
  31. "honnef.co/go/tools/internal/sharedcheck"
  32. "honnef.co/go/tools/knowledge"
  33. "honnef.co/go/tools/pattern"
  34. "honnef.co/go/tools/printf"
  35. "honnef.co/go/tools/staticcheck/fakejson"
  36. "honnef.co/go/tools/staticcheck/fakereflect"
  37. "honnef.co/go/tools/staticcheck/fakexml"
  38. "golang.org/x/exp/typeparams"
  39. "golang.org/x/tools/go/analysis"
  40. "golang.org/x/tools/go/analysis/passes/inspect"
  41. "golang.org/x/tools/go/ast/inspector"
  42. )
  43. func checkSortSlice(call *Call) {
  44. c := call.Instr.Common().StaticCallee()
  45. arg := call.Args[0]
  46. T := arg.Value.Value.Type().Underlying()
  47. switch T.(type) {
  48. case *types.Interface:
  49. // we don't know.
  50. // TODO(dh): if the value is a phi node we can look at its edges
  51. if k, ok := arg.Value.Value.(*ir.Const); ok && k.Value == nil {
  52. // literal nil, e.g. sort.Sort(nil, ...)
  53. arg.Invalid(fmt.Sprintf("cannot call %s on nil literal", c))
  54. }
  55. case *types.Slice:
  56. // this is fine
  57. default:
  58. // this is not fine
  59. arg.Invalid(fmt.Sprintf("%s must only be called on slices, was called on %s", c, T))
  60. }
  61. }
  62. func validRegexp(call *Call) {
  63. arg := call.Args[0]
  64. err := ValidateRegexp(arg.Value)
  65. if err != nil {
  66. arg.Invalid(err.Error())
  67. }
  68. }
  69. type runeSlice []rune
  70. func (rs runeSlice) Len() int { return len(rs) }
  71. func (rs runeSlice) Less(i int, j int) bool { return rs[i] < rs[j] }
  72. func (rs runeSlice) Swap(i int, j int) { rs[i], rs[j] = rs[j], rs[i] }
  73. func utf8Cutset(call *Call) {
  74. arg := call.Args[1]
  75. if InvalidUTF8(arg.Value) {
  76. arg.Invalid(MsgInvalidUTF8)
  77. }
  78. }
  79. func uniqueCutset(call *Call) {
  80. arg := call.Args[1]
  81. if !UniqueStringCutset(arg.Value) {
  82. arg.Invalid(MsgNonUniqueCutset)
  83. }
  84. }
  85. func unmarshalPointer(name string, arg int) CallCheck {
  86. return func(call *Call) {
  87. if !Pointer(call.Args[arg].Value) {
  88. call.Args[arg].Invalid(fmt.Sprintf("%s expects to unmarshal into a pointer, but the provided value is not a pointer", name))
  89. }
  90. }
  91. }
  92. func pointlessIntMath(call *Call) {
  93. if ConvertedFromInt(call.Args[0].Value) {
  94. call.Invalid(fmt.Sprintf("calling %s on a converted integer is pointless", irutil.CallName(call.Instr.Common())))
  95. }
  96. }
  97. func checkValidHostPort(arg int) CallCheck {
  98. return func(call *Call) {
  99. if !ValidHostPort(call.Args[arg].Value) {
  100. call.Args[arg].Invalid(MsgInvalidHostPort)
  101. }
  102. }
  103. }
  104. var (
  105. checkRegexpRules = map[string]CallCheck{
  106. "regexp.MustCompile": validRegexp,
  107. "regexp.Compile": validRegexp,
  108. "regexp.Match": validRegexp,
  109. "regexp.MatchReader": validRegexp,
  110. "regexp.MatchString": validRegexp,
  111. }
  112. checkTimeParseRules = map[string]CallCheck{
  113. "time.Parse": func(call *Call) {
  114. arg := call.Args[knowledge.Arg("time.Parse.layout")]
  115. err := ValidateTimeLayout(arg.Value)
  116. if err != nil {
  117. arg.Invalid(err.Error())
  118. }
  119. },
  120. }
  121. checkEncodingBinaryRules = map[string]CallCheck{
  122. "encoding/binary.Write": func(call *Call) {
  123. arg := call.Args[knowledge.Arg("encoding/binary.Write.data")]
  124. if !CanBinaryMarshal(call.Pass, arg.Value) {
  125. arg.Invalid(fmt.Sprintf("value of type %s cannot be used with binary.Write", arg.Value.Value.Type()))
  126. }
  127. },
  128. }
  129. checkURLsRules = map[string]CallCheck{
  130. "net/url.Parse": func(call *Call) {
  131. arg := call.Args[knowledge.Arg("net/url.Parse.rawurl")]
  132. err := ValidateURL(arg.Value)
  133. if err != nil {
  134. arg.Invalid(err.Error())
  135. }
  136. },
  137. }
  138. checkSyncPoolValueRules = map[string]CallCheck{
  139. "(*sync.Pool).Put": func(call *Call) {
  140. arg := call.Args[knowledge.Arg("(*sync.Pool).Put.x")]
  141. typ := arg.Value.Value.Type()
  142. _, isSlice := typ.Underlying().(*types.Slice)
  143. if !typeutil.IsPointerLike(typ) || isSlice {
  144. arg.Invalid("argument should be pointer-like to avoid allocations")
  145. }
  146. },
  147. }
  148. checkRegexpFindAllRules = map[string]CallCheck{
  149. "(*regexp.Regexp).FindAll": RepeatZeroTimes("a FindAll method", 1),
  150. "(*regexp.Regexp).FindAllIndex": RepeatZeroTimes("a FindAll method", 1),
  151. "(*regexp.Regexp).FindAllString": RepeatZeroTimes("a FindAll method", 1),
  152. "(*regexp.Regexp).FindAllStringIndex": RepeatZeroTimes("a FindAll method", 1),
  153. "(*regexp.Regexp).FindAllStringSubmatch": RepeatZeroTimes("a FindAll method", 1),
  154. "(*regexp.Regexp).FindAllStringSubmatchIndex": RepeatZeroTimes("a FindAll method", 1),
  155. "(*regexp.Regexp).FindAllSubmatch": RepeatZeroTimes("a FindAll method", 1),
  156. "(*regexp.Regexp).FindAllSubmatchIndex": RepeatZeroTimes("a FindAll method", 1),
  157. }
  158. checkUTF8CutsetRules = map[string]CallCheck{
  159. "strings.IndexAny": utf8Cutset,
  160. "strings.LastIndexAny": utf8Cutset,
  161. "strings.ContainsAny": utf8Cutset,
  162. "strings.Trim": utf8Cutset,
  163. "strings.TrimLeft": utf8Cutset,
  164. "strings.TrimRight": utf8Cutset,
  165. }
  166. checkUniqueCutsetRules = map[string]CallCheck{
  167. "strings.Trim": uniqueCutset,
  168. "strings.TrimLeft": uniqueCutset,
  169. "strings.TrimRight": uniqueCutset,
  170. }
  171. checkUnmarshalPointerRules = map[string]CallCheck{
  172. "encoding/xml.Unmarshal": unmarshalPointer("xml.Unmarshal", 1),
  173. "(*encoding/xml.Decoder).Decode": unmarshalPointer("Decode", 0),
  174. "(*encoding/xml.Decoder).DecodeElement": unmarshalPointer("DecodeElement", 0),
  175. "encoding/json.Unmarshal": unmarshalPointer("json.Unmarshal", 1),
  176. "(*encoding/json.Decoder).Decode": unmarshalPointer("Decode", 0),
  177. }
  178. checkUnbufferedSignalChanRules = map[string]CallCheck{
  179. "os/signal.Notify": func(call *Call) {
  180. arg := call.Args[knowledge.Arg("os/signal.Notify.c")]
  181. if UnbufferedChannel(arg.Value) {
  182. arg.Invalid("the channel used with signal.Notify should be buffered")
  183. }
  184. },
  185. }
  186. checkMathIntRules = map[string]CallCheck{
  187. "math.Ceil": pointlessIntMath,
  188. "math.Floor": pointlessIntMath,
  189. "math.IsNaN": pointlessIntMath,
  190. "math.Trunc": pointlessIntMath,
  191. "math.IsInf": pointlessIntMath,
  192. }
  193. checkStringsReplaceZeroRules = map[string]CallCheck{
  194. "strings.Replace": RepeatZeroTimes("strings.Replace", 3),
  195. "bytes.Replace": RepeatZeroTimes("bytes.Replace", 3),
  196. }
  197. checkListenAddressRules = map[string]CallCheck{
  198. "net/http.ListenAndServe": checkValidHostPort(0),
  199. "net/http.ListenAndServeTLS": checkValidHostPort(0),
  200. }
  201. checkBytesEqualIPRules = map[string]CallCheck{
  202. "bytes.Equal": func(call *Call) {
  203. if ConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.a")].Value, "net.IP") &&
  204. ConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.b")].Value, "net.IP") {
  205. call.Invalid("use net.IP.Equal to compare net.IPs, not bytes.Equal")
  206. }
  207. },
  208. }
  209. checkRegexpMatchLoopRules = map[string]CallCheck{
  210. "regexp.Match": loopedRegexp("regexp.Match"),
  211. "regexp.MatchReader": loopedRegexp("regexp.MatchReader"),
  212. "regexp.MatchString": loopedRegexp("regexp.MatchString"),
  213. }
  214. checkNoopMarshal = map[string]CallCheck{
  215. // TODO(dh): should we really flag XML? Even an empty struct
  216. // produces a non-zero amount of data, namely its type name.
  217. // Let's see if we encounter any false positives.
  218. //
  219. // Also, should we flag gob?
  220. "encoding/json.Marshal": checkNoopMarshalImpl(knowledge.Arg("json.Marshal.v"), "MarshalJSON", "MarshalText"),
  221. "encoding/xml.Marshal": checkNoopMarshalImpl(knowledge.Arg("xml.Marshal.v"), "MarshalXML", "MarshalText"),
  222. "(*encoding/json.Encoder).Encode": checkNoopMarshalImpl(knowledge.Arg("(*encoding/json.Encoder).Encode.v"), "MarshalJSON", "MarshalText"),
  223. "(*encoding/xml.Encoder).Encode": checkNoopMarshalImpl(knowledge.Arg("(*encoding/xml.Encoder).Encode.v"), "MarshalXML", "MarshalText"),
  224. "encoding/json.Unmarshal": checkNoopMarshalImpl(knowledge.Arg("json.Unmarshal.v"), "UnmarshalJSON", "UnmarshalText"),
  225. "encoding/xml.Unmarshal": checkNoopMarshalImpl(knowledge.Arg("xml.Unmarshal.v"), "UnmarshalXML", "UnmarshalText"),
  226. "(*encoding/json.Decoder).Decode": checkNoopMarshalImpl(knowledge.Arg("(*encoding/json.Decoder).Decode.v"), "UnmarshalJSON", "UnmarshalText"),
  227. "(*encoding/xml.Decoder).Decode": checkNoopMarshalImpl(knowledge.Arg("(*encoding/xml.Decoder).Decode.v"), "UnmarshalXML", "UnmarshalText"),
  228. }
  229. checkUnsupportedMarshal = map[string]CallCheck{
  230. "encoding/json.Marshal": checkUnsupportedMarshalJSON,
  231. "encoding/xml.Marshal": checkUnsupportedMarshalXML,
  232. "(*encoding/json.Encoder).Encode": checkUnsupportedMarshalJSON,
  233. "(*encoding/xml.Encoder).Encode": checkUnsupportedMarshalXML,
  234. }
  235. checkAtomicAlignment = map[string]CallCheck{
  236. "sync/atomic.AddInt64": checkAtomicAlignmentImpl,
  237. "sync/atomic.AddUint64": checkAtomicAlignmentImpl,
  238. "sync/atomic.CompareAndSwapInt64": checkAtomicAlignmentImpl,
  239. "sync/atomic.CompareAndSwapUint64": checkAtomicAlignmentImpl,
  240. "sync/atomic.LoadInt64": checkAtomicAlignmentImpl,
  241. "sync/atomic.LoadUint64": checkAtomicAlignmentImpl,
  242. "sync/atomic.StoreInt64": checkAtomicAlignmentImpl,
  243. "sync/atomic.StoreUint64": checkAtomicAlignmentImpl,
  244. "sync/atomic.SwapInt64": checkAtomicAlignmentImpl,
  245. "sync/atomic.SwapUint64": checkAtomicAlignmentImpl,
  246. }
  247. // TODO(dh): detect printf wrappers
  248. checkPrintfRules = map[string]CallCheck{
  249. "fmt.Errorf": func(call *Call) { checkPrintfCall(call, 0, 1) },
  250. "fmt.Printf": func(call *Call) { checkPrintfCall(call, 0, 1) },
  251. "fmt.Sprintf": func(call *Call) { checkPrintfCall(call, 0, 1) },
  252. "fmt.Fprintf": func(call *Call) { checkPrintfCall(call, 1, 2) },
  253. "golang.org/x/xerrors.Errorf": func(call *Call) { checkPrintfCall(call, 0, 1) },
  254. }
  255. checkSortSliceRules = map[string]CallCheck{
  256. "sort.Slice": checkSortSlice,
  257. "sort.SliceIsSorted": checkSortSlice,
  258. "sort.SliceStable": checkSortSlice,
  259. }
  260. checkWithValueKeyRules = map[string]CallCheck{
  261. "context.WithValue": checkWithValueKey,
  262. }
  263. checkStrconvRules = map[string]CallCheck{
  264. "strconv.ParseComplex": func(call *Call) {
  265. validateComplexBitSize(call.Args[knowledge.Arg("strconv.ParseComplex.bitSize")])
  266. },
  267. "strconv.ParseFloat": func(call *Call) {
  268. validateFloatBitSize(call.Args[knowledge.Arg("strconv.ParseFloat.bitSize")])
  269. },
  270. "strconv.ParseInt": func(call *Call) {
  271. validateContinuousBitSize(call.Args[knowledge.Arg("strconv.ParseInt.bitSize")], 0, 64)
  272. validateIntBaseAllowZero(call.Args[knowledge.Arg("strconv.ParseInt.base")])
  273. },
  274. "strconv.ParseUint": func(call *Call) {
  275. validateContinuousBitSize(call.Args[knowledge.Arg("strconv.ParseUint.bitSize")], 0, 64)
  276. validateIntBaseAllowZero(call.Args[knowledge.Arg("strconv.ParseUint.base")])
  277. },
  278. "strconv.FormatComplex": func(call *Call) {
  279. validateComplexFormat(call.Args[knowledge.Arg("strconv.FormatComplex.fmt")])
  280. validateComplexBitSize(call.Args[knowledge.Arg("strconv.FormatComplex.bitSize")])
  281. },
  282. "strconv.FormatFloat": func(call *Call) {
  283. validateFloatFormat(call.Args[knowledge.Arg("strconv.FormatFloat.fmt")])
  284. validateFloatBitSize(call.Args[knowledge.Arg("strconv.FormatFloat.bitSize")])
  285. },
  286. "strconv.FormatInt": func(call *Call) {
  287. validateIntBase(call.Args[knowledge.Arg("strconv.FormatInt.base")])
  288. },
  289. "strconv.FormatUint": func(call *Call) {
  290. validateIntBase(call.Args[knowledge.Arg("strconv.FormatUint.base")])
  291. },
  292. "strconv.AppendFloat": func(call *Call) {
  293. validateFloatFormat(call.Args[knowledge.Arg("strconv.AppendFloat.fmt")])
  294. validateFloatBitSize(call.Args[knowledge.Arg("strconv.AppendFloat.bitSize")])
  295. },
  296. "strconv.AppendInt": func(call *Call) {
  297. validateIntBase(call.Args[knowledge.Arg("strconv.AppendInt.base")])
  298. },
  299. "strconv.AppendUint": func(call *Call) {
  300. validateIntBase(call.Args[knowledge.Arg("strconv.AppendUint.base")])
  301. },
  302. }
  303. )
  304. func validateIntBase(arg *Argument) {
  305. if c := extractConstExpectKind(arg.Value.Value, constant.Int); c != nil {
  306. val, _ := constant.Int64Val(c.Value)
  307. if val < 2 {
  308. arg.Invalid("'base' must not be smaller than 2")
  309. }
  310. if val > 36 {
  311. arg.Invalid("'base' must not be larger than 36")
  312. }
  313. }
  314. }
  315. func validateIntBaseAllowZero(arg *Argument) {
  316. if c := extractConstExpectKind(arg.Value.Value, constant.Int); c != nil {
  317. val, _ := constant.Int64Val(c.Value)
  318. if val < 2 && val != 0 {
  319. arg.Invalid("'base' must not be smaller than 2, unless it is 0")
  320. }
  321. if val > 36 {
  322. arg.Invalid("'base' must not be larger than 36")
  323. }
  324. }
  325. }
  326. func validateComplexFormat(arg *Argument) {
  327. validateFloatFormat(arg)
  328. }
  329. func validateFloatFormat(arg *Argument) {
  330. if c := extractConstExpectKind(arg.Value.Value, constant.Int); c != nil {
  331. val, _ := constant.Int64Val(c.Value)
  332. switch val {
  333. case 'b', 'e', 'E', 'f', 'g', 'G', 'x', 'X':
  334. default:
  335. arg.Invalid(fmt.Sprintf("'fmt' argument is invalid: unknown format %q", val))
  336. }
  337. }
  338. }
  339. func validateComplexBitSize(arg *Argument) { validateDiscreetBitSize(arg, 64, 128) }
  340. func validateFloatBitSize(arg *Argument) { validateDiscreetBitSize(arg, 32, 64) }
  341. func validateDiscreetBitSize(arg *Argument, size1 int, size2 int) {
  342. if c := extractConstExpectKind(arg.Value.Value, constant.Int); c != nil {
  343. val, _ := constant.Int64Val(c.Value)
  344. if val != int64(size1) && val != int64(size2) {
  345. arg.Invalid(fmt.Sprintf("'bitSize' argument is invalid, must be either %d or %d", size1, size2))
  346. }
  347. }
  348. }
  349. func validateContinuousBitSize(arg *Argument, min int, max int) {
  350. if c := extractConstExpectKind(arg.Value.Value, constant.Int); c != nil {
  351. val, _ := constant.Int64Val(c.Value)
  352. if val < int64(min) || val > int64(max) {
  353. arg.Invalid(fmt.Sprintf("'bitSize' argument is invalid, must be within %d and %d", min, max))
  354. }
  355. }
  356. }
  357. func checkPrintfCall(call *Call, fIdx, vIdx int) {
  358. f := call.Args[fIdx]
  359. var args []ir.Value
  360. switch v := call.Args[vIdx].Value.Value.(type) {
  361. case *ir.Slice:
  362. var ok bool
  363. args, ok = irutil.Vararg(v)
  364. if !ok {
  365. // We don't know what the actual arguments to the function are
  366. return
  367. }
  368. case *ir.Const:
  369. // nil, i.e. no arguments
  370. default:
  371. // We don't know what the actual arguments to the function are
  372. return
  373. }
  374. checkPrintfCallImpl(f, f.Value.Value, args)
  375. }
  376. type verbFlag int
  377. const (
  378. isInt verbFlag = 1 << iota
  379. isBool
  380. isFP
  381. isString
  382. isPointer
  383. // Verbs that accept "pseudo pointers" will sometimes dereference
  384. // non-nil pointers. For example, %x on a non-nil *struct will print the
  385. // individual fields, but on a nil pointer it will print the address.
  386. isPseudoPointer
  387. isSlice
  388. isAny
  389. noRecurse
  390. )
  391. var verbs = [...]verbFlag{
  392. 'b': isPseudoPointer | isInt | isFP,
  393. 'c': isInt,
  394. 'd': isPseudoPointer | isInt,
  395. 'e': isFP,
  396. 'E': isFP,
  397. 'f': isFP,
  398. 'F': isFP,
  399. 'g': isFP,
  400. 'G': isFP,
  401. 'o': isPseudoPointer | isInt,
  402. 'O': isPseudoPointer | isInt,
  403. 'p': isSlice | isPointer | noRecurse,
  404. 'q': isInt | isString,
  405. 's': isString,
  406. 't': isBool,
  407. 'T': isAny,
  408. 'U': isInt,
  409. 'v': isAny,
  410. 'X': isPseudoPointer | isInt | isFP | isString,
  411. 'x': isPseudoPointer | isInt | isFP | isString,
  412. }
  413. func checkPrintfCallImpl(carg *Argument, f ir.Value, args []ir.Value) {
  414. var msCache *typeutil.MethodSetCache
  415. if f.Parent() != nil {
  416. msCache = &f.Parent().Prog.MethodSets
  417. }
  418. elem := func(T types.Type, verb rune) ([]types.Type, bool) {
  419. if verbs[verb]&noRecurse != 0 {
  420. return []types.Type{T}, false
  421. }
  422. switch T := T.(type) {
  423. case *types.Slice:
  424. if verbs[verb]&isSlice != 0 {
  425. return []types.Type{T}, false
  426. }
  427. if verbs[verb]&isString != 0 && typeutil.IsType(T.Elem().Underlying(), "byte") {
  428. return []types.Type{T}, false
  429. }
  430. return []types.Type{T.Elem()}, true
  431. case *types.Map:
  432. key := T.Key()
  433. val := T.Elem()
  434. return []types.Type{key, val}, true
  435. case *types.Struct:
  436. out := make([]types.Type, 0, T.NumFields())
  437. for i := 0; i < T.NumFields(); i++ {
  438. out = append(out, T.Field(i).Type())
  439. }
  440. return out, true
  441. case *types.Array:
  442. return []types.Type{T.Elem()}, true
  443. default:
  444. return []types.Type{T}, false
  445. }
  446. }
  447. isInfo := func(T types.Type, info types.BasicInfo) bool {
  448. basic, ok := T.Underlying().(*types.Basic)
  449. return ok && basic.Info()&info != 0
  450. }
  451. isStringer := func(T types.Type, ms *types.MethodSet) bool {
  452. sel := ms.Lookup(nil, "String")
  453. if sel == nil {
  454. return false
  455. }
  456. fn, ok := sel.Obj().(*types.Func)
  457. if !ok {
  458. // should be unreachable
  459. return false
  460. }
  461. sig := fn.Type().(*types.Signature)
  462. if sig.Params().Len() != 0 {
  463. return false
  464. }
  465. if sig.Results().Len() != 1 {
  466. return false
  467. }
  468. if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
  469. return false
  470. }
  471. return true
  472. }
  473. isError := func(T types.Type, ms *types.MethodSet) bool {
  474. sel := ms.Lookup(nil, "Error")
  475. if sel == nil {
  476. return false
  477. }
  478. fn, ok := sel.Obj().(*types.Func)
  479. if !ok {
  480. // should be unreachable
  481. return false
  482. }
  483. sig := fn.Type().(*types.Signature)
  484. if sig.Params().Len() != 0 {
  485. return false
  486. }
  487. if sig.Results().Len() != 1 {
  488. return false
  489. }
  490. if !typeutil.IsType(sig.Results().At(0).Type(), "string") {
  491. return false
  492. }
  493. return true
  494. }
  495. isFormatter := func(T types.Type, ms *types.MethodSet) bool {
  496. sel := ms.Lookup(nil, "Format")
  497. if sel == nil {
  498. return false
  499. }
  500. fn, ok := sel.Obj().(*types.Func)
  501. if !ok {
  502. // should be unreachable
  503. return false
  504. }
  505. sig := fn.Type().(*types.Signature)
  506. if sig.Params().Len() != 2 {
  507. return false
  508. }
  509. // TODO(dh): check the types of the arguments for more
  510. // precision
  511. if sig.Results().Len() != 0 {
  512. return false
  513. }
  514. return true
  515. }
  516. seen := map[types.Type]bool{}
  517. var checkType func(verb rune, T types.Type, top bool) bool
  518. checkType = func(verb rune, T types.Type, top bool) bool {
  519. if top {
  520. for k := range seen {
  521. delete(seen, k)
  522. }
  523. }
  524. if seen[T] {
  525. return true
  526. }
  527. seen[T] = true
  528. if int(verb) >= len(verbs) {
  529. // Unknown verb
  530. return true
  531. }
  532. flags := verbs[verb]
  533. if flags == 0 {
  534. // Unknown verb
  535. return true
  536. }
  537. ms := msCache.MethodSet(T)
  538. if isFormatter(T, ms) {
  539. // the value is responsible for formatting itself
  540. return true
  541. }
  542. if flags&isString != 0 && (isStringer(T, ms) || isError(T, ms)) {
  543. // Check for stringer early because we're about to dereference
  544. return true
  545. }
  546. T = T.Underlying()
  547. if flags&(isPointer|isPseudoPointer) == 0 && top {
  548. T = typeutil.Dereference(T)
  549. }
  550. if flags&isPseudoPointer != 0 && top {
  551. t := typeutil.Dereference(T)
  552. if _, ok := t.Underlying().(*types.Struct); ok {
  553. T = t
  554. }
  555. }
  556. if _, ok := T.(*types.Interface); ok {
  557. // We don't know what's in the interface
  558. return true
  559. }
  560. var info types.BasicInfo
  561. if flags&isInt != 0 {
  562. info |= types.IsInteger
  563. }
  564. if flags&isBool != 0 {
  565. info |= types.IsBoolean
  566. }
  567. if flags&isFP != 0 {
  568. info |= types.IsFloat | types.IsComplex
  569. }
  570. if flags&isString != 0 {
  571. info |= types.IsString
  572. }
  573. if info != 0 && isInfo(T, info) {
  574. return true
  575. }
  576. if flags&isString != 0 {
  577. isStringyElem := func(typ types.Type) bool {
  578. if typ, ok := typ.Underlying().(*types.Basic); ok {
  579. return typ.Kind() == types.Byte
  580. }
  581. return false
  582. }
  583. switch T := T.(type) {
  584. case *types.Slice:
  585. if isStringyElem(T.Elem()) {
  586. return true
  587. }
  588. case *types.Array:
  589. if isStringyElem(T.Elem()) {
  590. return true
  591. }
  592. }
  593. if isStringer(T, ms) || isError(T, ms) {
  594. return true
  595. }
  596. }
  597. if flags&isPointer != 0 && typeutil.IsPointerLike(T) {
  598. return true
  599. }
  600. if flags&isPseudoPointer != 0 {
  601. switch U := T.Underlying().(type) {
  602. case *types.Pointer:
  603. if !top {
  604. return true
  605. }
  606. if _, ok := U.Elem().Underlying().(*types.Struct); !ok {
  607. // TODO(dh): can this condition ever be false? For
  608. // *T, if T is a struct, we'll already have
  609. // dereferenced it, meaning the *types.Pointer
  610. // branch couldn't have been taken. For T that
  611. // aren't structs, this condition will always
  612. // evaluate to true.
  613. return true
  614. }
  615. case *types.Chan, *types.Signature:
  616. // Channels and functions are always treated as
  617. // pointers and never recursed into.
  618. return true
  619. case *types.Basic:
  620. if U.Kind() == types.UnsafePointer {
  621. return true
  622. }
  623. case *types.Interface:
  624. // we will already have bailed if the type is an
  625. // interface.
  626. panic("unreachable")
  627. default:
  628. // other pointer-like types, such as maps or slices,
  629. // will be printed element-wise.
  630. }
  631. }
  632. if flags&isSlice != 0 {
  633. if _, ok := T.(*types.Slice); ok {
  634. return true
  635. }
  636. }
  637. if flags&isAny != 0 {
  638. return true
  639. }
  640. elems, ok := elem(T.Underlying(), verb)
  641. if !ok {
  642. return false
  643. }
  644. for _, elem := range elems {
  645. if !checkType(verb, elem, false) {
  646. return false
  647. }
  648. }
  649. return true
  650. }
  651. k, ok := irutil.Flatten(f).(*ir.Const)
  652. if !ok {
  653. return
  654. }
  655. actions, err := printf.Parse(constant.StringVal(k.Value))
  656. if err != nil {
  657. carg.Invalid("couldn't parse format string")
  658. return
  659. }
  660. ptr := 1
  661. hasExplicit := false
  662. checkStar := func(verb printf.Verb, star printf.Argument) bool {
  663. if star, ok := star.(printf.Star); ok {
  664. idx := 0
  665. if star.Index == -1 {
  666. idx = ptr
  667. ptr++
  668. } else {
  669. hasExplicit = true
  670. idx = star.Index
  671. ptr = star.Index + 1
  672. }
  673. if idx == 0 {
  674. carg.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
  675. return false
  676. }
  677. if idx > len(args) {
  678. carg.Invalid(
  679. fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
  680. verb.Raw, idx, len(args)))
  681. return false
  682. }
  683. if arg, ok := args[idx-1].(*ir.MakeInterface); ok {
  684. if !isInfo(arg.X.Type(), types.IsInteger) {
  685. carg.Invalid(fmt.Sprintf("Printf format %s reads non-int arg #%d as argument of *", verb.Raw, idx))
  686. }
  687. }
  688. }
  689. return true
  690. }
  691. // We only report one problem per format string. Making a
  692. // mistake with an index tends to invalidate all future
  693. // implicit indices.
  694. for _, action := range actions {
  695. verb, ok := action.(printf.Verb)
  696. if !ok {
  697. continue
  698. }
  699. if !checkStar(verb, verb.Width) || !checkStar(verb, verb.Precision) {
  700. return
  701. }
  702. off := ptr
  703. if verb.Value != -1 {
  704. hasExplicit = true
  705. off = verb.Value
  706. }
  707. if off > len(args) {
  708. carg.Invalid(
  709. fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
  710. verb.Raw, off, len(args)))
  711. return
  712. } else if verb.Value == 0 && verb.Letter != '%' {
  713. carg.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
  714. return
  715. } else if off != 0 {
  716. arg, ok := args[off-1].(*ir.MakeInterface)
  717. if ok {
  718. if !checkType(verb.Letter, arg.X.Type(), true) {
  719. carg.Invalid(fmt.Sprintf("Printf format %s has arg #%d of wrong type %s",
  720. verb.Raw, ptr, args[ptr-1].(*ir.MakeInterface).X.Type()))
  721. return
  722. }
  723. }
  724. }
  725. switch verb.Value {
  726. case -1:
  727. // Consume next argument
  728. ptr++
  729. case 0:
  730. // Don't consume any arguments
  731. default:
  732. ptr = verb.Value + 1
  733. }
  734. }
  735. if !hasExplicit && ptr <= len(args) {
  736. carg.Invalid(fmt.Sprintf("Printf call needs %d args but has %d args", ptr-1, len(args)))
  737. }
  738. }
  739. func checkAtomicAlignmentImpl(call *Call) {
  740. sizes := call.Pass.TypesSizes
  741. if sizes.Sizeof(types.Typ[types.Uintptr]) != 4 {
  742. // Not running on a 32-bit platform
  743. return
  744. }
  745. v, ok := irutil.Flatten(call.Args[0].Value.Value).(*ir.FieldAddr)
  746. if !ok {
  747. // TODO(dh): also check indexing into arrays and slices
  748. return
  749. }
  750. T := v.X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct)
  751. fields := make([]*types.Var, 0, T.NumFields())
  752. for i := 0; i < T.NumFields() && i <= v.Field; i++ {
  753. fields = append(fields, T.Field(i))
  754. }
  755. off := sizes.Offsetsof(fields)[v.Field]
  756. if off%8 != 0 {
  757. msg := fmt.Sprintf("address of non 64-bit aligned field %s passed to %s",
  758. T.Field(v.Field).Name(),
  759. irutil.CallName(call.Instr.Common()))
  760. call.Invalid(msg)
  761. }
  762. }
  763. func checkNoopMarshalImpl(argN int, meths ...string) CallCheck {
  764. return func(call *Call) {
  765. if code.IsGenerated(call.Pass, call.Instr.Pos()) {
  766. return
  767. }
  768. arg := call.Args[argN]
  769. T := arg.Value.Value.Type()
  770. Ts, ok := typeutil.Dereference(T).Underlying().(*types.Struct)
  771. if !ok {
  772. return
  773. }
  774. if Ts.NumFields() == 0 {
  775. return
  776. }
  777. fields := typeutil.FlattenFields(Ts)
  778. for _, field := range fields {
  779. if field.Var.Exported() {
  780. return
  781. }
  782. }
  783. // OPT(dh): we could use a method set cache here
  784. ms := call.Instr.Parent().Prog.MethodSets.MethodSet(T)
  785. // TODO(dh): we're not checking the signature, which can cause false negatives.
  786. // This isn't a huge problem, however, since vet complains about incorrect signatures.
  787. for _, meth := range meths {
  788. if ms.Lookup(nil, meth) != nil {
  789. return
  790. }
  791. }
  792. arg.Invalid(fmt.Sprintf("struct type '%s' doesn't have any exported fields, nor custom marshaling", typeutil.Dereference(T)))
  793. }
  794. }
  795. func checkUnsupportedMarshalJSON(call *Call) {
  796. arg := call.Args[0]
  797. T := arg.Value.Value.Type()
  798. if err := fakejson.Marshal(T); err != nil {
  799. typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
  800. if err.Path == "x" {
  801. arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
  802. } else {
  803. arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
  804. }
  805. }
  806. }
  807. func checkUnsupportedMarshalXML(call *Call) {
  808. arg := call.Args[0]
  809. T := arg.Value.Value.Type()
  810. if err := fakexml.Marshal(T); err != nil {
  811. switch err := err.(type) {
  812. case *fakexml.UnsupportedTypeError:
  813. typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
  814. if err.Path == "x" {
  815. arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
  816. } else {
  817. arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
  818. }
  819. case *fakexml.CyclicTypeError:
  820. typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
  821. if err.Path == "x" {
  822. arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s", typ))
  823. } else {
  824. arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s, via %s", typ, err.Path))
  825. }
  826. case *fakexml.TagPathError:
  827. // Vet does a better job at reporting this error, because it can flag the actual struct tags, not just the call to Marshal
  828. default:
  829. // These errors get reported by SA5008 instead, which can flag the actual fields, independently of calls to xml.Marshal
  830. }
  831. }
  832. }
  833. func isInLoop(b *ir.BasicBlock) bool {
  834. sets := irutil.FindLoops(b.Parent())
  835. for _, set := range sets {
  836. if set.Has(b) {
  837. return true
  838. }
  839. }
  840. return false
  841. }
  842. func CheckUntrappableSignal(pass *analysis.Pass) (interface{}, error) {
  843. isSignal := func(pass *analysis.Pass, expr ast.Expr, name string) bool {
  844. if expr, ok := expr.(*ast.SelectorExpr); ok {
  845. return code.SelectorName(pass, expr) == name
  846. } else {
  847. return false
  848. }
  849. }
  850. fn := func(node ast.Node) {
  851. call := node.(*ast.CallExpr)
  852. if !code.IsCallToAny(pass, call,
  853. "os/signal.Ignore", "os/signal.Notify", "os/signal.Reset") {
  854. return
  855. }
  856. hasSigterm := false
  857. for _, arg := range call.Args {
  858. if conv, ok := arg.(*ast.CallExpr); ok && isSignal(pass, conv.Fun, "os.Signal") {
  859. arg = conv.Args[0]
  860. }
  861. if isSignal(pass, arg, "syscall.SIGTERM") {
  862. hasSigterm = true
  863. break
  864. }
  865. }
  866. for i, arg := range call.Args {
  867. if conv, ok := arg.(*ast.CallExpr); ok && isSignal(pass, conv.Fun, "os.Signal") {
  868. arg = conv.Args[0]
  869. }
  870. if isSignal(pass, arg, "os.Kill") || isSignal(pass, arg, "syscall.SIGKILL") {
  871. var fixes []analysis.SuggestedFix
  872. if !hasSigterm {
  873. nargs := make([]ast.Expr, len(call.Args))
  874. for j, a := range call.Args {
  875. if i == j {
  876. nargs[j] = edit.Selector("syscall", "SIGTERM")
  877. } else {
  878. nargs[j] = a
  879. }
  880. }
  881. ncall := *call
  882. ncall.Args = nargs
  883. fixes = append(fixes, edit.Fix(fmt.Sprintf("use syscall.SIGTERM instead of %s", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
  884. }
  885. nargs := make([]ast.Expr, 0, len(call.Args))
  886. for j, a := range call.Args {
  887. if i == j {
  888. continue
  889. }
  890. nargs = append(nargs, a)
  891. }
  892. ncall := *call
  893. ncall.Args = nargs
  894. fixes = append(fixes, edit.Fix(fmt.Sprintf("remove %s from list of arguments", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
  895. report.Report(pass, arg, fmt.Sprintf("%s cannot be trapped (did you mean syscall.SIGTERM?)", report.Render(pass, arg)), report.Fixes(fixes...))
  896. }
  897. if isSignal(pass, arg, "syscall.SIGSTOP") {
  898. nargs := make([]ast.Expr, 0, len(call.Args)-1)
  899. for j, a := range call.Args {
  900. if i == j {
  901. continue
  902. }
  903. nargs = append(nargs, a)
  904. }
  905. ncall := *call
  906. ncall.Args = nargs
  907. report.Report(pass, arg, "syscall.SIGSTOP cannot be trapped", report.Fixes(edit.Fix("remove syscall.SIGSTOP from list of arguments", edit.ReplaceWithNode(pass.Fset, call, &ncall))))
  908. }
  909. }
  910. }
  911. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  912. return nil, nil
  913. }
  914. func CheckTemplate(pass *analysis.Pass) (interface{}, error) {
  915. fn := func(node ast.Node) {
  916. call := node.(*ast.CallExpr)
  917. // OPT(dh): use integer for kind
  918. var kind string
  919. switch code.CallName(pass, call) {
  920. case "(*text/template.Template).Parse":
  921. kind = "text"
  922. case "(*html/template.Template).Parse":
  923. kind = "html"
  924. default:
  925. return
  926. }
  927. sel := call.Fun.(*ast.SelectorExpr)
  928. if !code.IsCallToAny(pass, sel.X, "text/template.New", "html/template.New") {
  929. // TODO(dh): this is a cheap workaround for templates with
  930. // different delims. A better solution with less false
  931. // negatives would use data flow analysis to see where the
  932. // template comes from and where it has been
  933. return
  934. }
  935. s, ok := code.ExprToString(pass, call.Args[knowledge.Arg("(*text/template.Template).Parse.text")])
  936. if !ok {
  937. return
  938. }
  939. var err error
  940. switch kind {
  941. case "text":
  942. _, err = texttemplate.New("").Parse(s)
  943. case "html":
  944. _, err = htmltemplate.New("").Parse(s)
  945. }
  946. if err != nil {
  947. // TODO(dominikh): whitelist other parse errors, if any
  948. if strings.Contains(err.Error(), "unexpected") {
  949. report.Report(pass, call.Args[knowledge.Arg("(*text/template.Template).Parse.text")], err.Error())
  950. }
  951. }
  952. }
  953. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  954. return nil, nil
  955. }
  956. var (
  957. checkTimeSleepConstantPatternQ = pattern.MustParse(`(CallExpr (Function "time.Sleep") lit@(IntegerLiteral value))`)
  958. checkTimeSleepConstantPatternRns = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Nanosecond")))`)
  959. checkTimeSleepConstantPatternRs = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Second")))`)
  960. )
  961. func CheckTimeSleepConstant(pass *analysis.Pass) (interface{}, error) {
  962. fn := func(node ast.Node) {
  963. m, ok := code.Match(pass, checkTimeSleepConstantPatternQ, node)
  964. if !ok {
  965. return
  966. }
  967. n, ok := constant.Int64Val(m.State["value"].(types.TypeAndValue).Value)
  968. if !ok {
  969. return
  970. }
  971. if n == 0 || n > 120 {
  972. // time.Sleep(0) is a seldom used pattern in concurrency
  973. // tests. >120 might be intentional. 120 was chosen
  974. // because the user could've meant 2 minutes.
  975. return
  976. }
  977. lit := m.State["lit"].(ast.Node)
  978. report.Report(pass, lit,
  979. fmt.Sprintf("sleeping for %d nanoseconds is probably a bug; be explicit if it isn't", n), report.Fixes(
  980. edit.Fix("explicitly use nanoseconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRns, pattern.State{"duration": lit})),
  981. edit.Fix("use seconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRs, pattern.State{"duration": lit}))))
  982. }
  983. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  984. return nil, nil
  985. }
  986. var checkWaitgroupAddQ = pattern.MustParse(`
  987. (GoStmt
  988. (CallExpr
  989. (FuncLit
  990. _
  991. call@(CallExpr (Function "(*sync.WaitGroup).Add") _):_) _))`)
  992. func CheckWaitgroupAdd(pass *analysis.Pass) (interface{}, error) {
  993. fn := func(node ast.Node) {
  994. if m, ok := code.Match(pass, checkWaitgroupAddQ, node); ok {
  995. call := m.State["call"].(ast.Node)
  996. report.Report(pass, call, fmt.Sprintf("should call %s before starting the goroutine to avoid a race", report.Render(pass, call)))
  997. }
  998. }
  999. code.Preorder(pass, fn, (*ast.GoStmt)(nil))
  1000. return nil, nil
  1001. }
  1002. func CheckInfiniteEmptyLoop(pass *analysis.Pass) (interface{}, error) {
  1003. fn := func(node ast.Node) {
  1004. loop := node.(*ast.ForStmt)
  1005. if len(loop.Body.List) != 0 || loop.Post != nil {
  1006. return
  1007. }
  1008. if loop.Init != nil {
  1009. // TODO(dh): this isn't strictly necessary, it just makes
  1010. // the check easier.
  1011. return
  1012. }
  1013. // An empty loop is bad news in two cases: 1) The loop has no
  1014. // condition. In that case, it's just a loop that spins
  1015. // forever and as fast as it can, keeping a core busy. 2) The
  1016. // loop condition only consists of variable or field reads and
  1017. // operators on those. The only way those could change their
  1018. // value is with unsynchronised access, which constitutes a
  1019. // data race.
  1020. //
  1021. // If the condition contains any function calls, its behaviour
  1022. // is dynamic and the loop might terminate. Similarly for
  1023. // channel receives.
  1024. if loop.Cond != nil {
  1025. if code.MayHaveSideEffects(pass, loop.Cond, nil) {
  1026. return
  1027. }
  1028. if ident, ok := loop.Cond.(*ast.Ident); ok {
  1029. if k, ok := pass.TypesInfo.ObjectOf(ident).(*types.Const); ok {
  1030. if !constant.BoolVal(k.Val()) {
  1031. // don't flag `for false {}` loops. They're a debug aid.
  1032. return
  1033. }
  1034. }
  1035. }
  1036. report.Report(pass, loop, "loop condition never changes or has a race condition")
  1037. }
  1038. report.Report(pass, loop, "this loop will spin, using 100% CPU", report.ShortRange())
  1039. }
  1040. code.Preorder(pass, fn, (*ast.ForStmt)(nil))
  1041. return nil, nil
  1042. }
  1043. func CheckDeferInInfiniteLoop(pass *analysis.Pass) (interface{}, error) {
  1044. fn := func(node ast.Node) {
  1045. mightExit := false
  1046. var defers []ast.Stmt
  1047. loop := node.(*ast.ForStmt)
  1048. if loop.Cond != nil {
  1049. return
  1050. }
  1051. fn2 := func(node ast.Node) bool {
  1052. switch stmt := node.(type) {
  1053. case *ast.ReturnStmt:
  1054. mightExit = true
  1055. return false
  1056. case *ast.BranchStmt:
  1057. // TODO(dominikh): if this sees a break in a switch or
  1058. // select, it doesn't check if it breaks the loop or
  1059. // just the select/switch. This causes some false
  1060. // negatives.
  1061. if stmt.Tok == token.BREAK {
  1062. mightExit = true
  1063. return false
  1064. }
  1065. case *ast.DeferStmt:
  1066. defers = append(defers, stmt)
  1067. case *ast.FuncLit:
  1068. // Don't look into function bodies
  1069. return false
  1070. }
  1071. return true
  1072. }
  1073. ast.Inspect(loop.Body, fn2)
  1074. if mightExit {
  1075. return
  1076. }
  1077. for _, stmt := range defers {
  1078. report.Report(pass, stmt, "defers in this infinite loop will never run")
  1079. }
  1080. }
  1081. code.Preorder(pass, fn, (*ast.ForStmt)(nil))
  1082. return nil, nil
  1083. }
  1084. func CheckDubiousDeferInChannelRangeLoop(pass *analysis.Pass) (interface{}, error) {
  1085. fn := func(node ast.Node) {
  1086. loop := node.(*ast.RangeStmt)
  1087. typ := pass.TypesInfo.TypeOf(loop.X)
  1088. _, ok := typeutil.CoreType(typ).(*types.Chan)
  1089. if !ok {
  1090. return
  1091. }
  1092. fn2 := func(node ast.Node) bool {
  1093. switch stmt := node.(type) {
  1094. case *ast.DeferStmt:
  1095. report.Report(pass, stmt, "defers in this range loop won't run unless the channel gets closed")
  1096. case *ast.FuncLit:
  1097. // Don't look into function bodies
  1098. return false
  1099. }
  1100. return true
  1101. }
  1102. ast.Inspect(loop.Body, fn2)
  1103. }
  1104. code.Preorder(pass, fn, (*ast.RangeStmt)(nil))
  1105. return nil, nil
  1106. }
  1107. func CheckTestMainExit(pass *analysis.Pass) (interface{}, error) {
  1108. if code.IsGoVersion(pass, 15) {
  1109. // Beginning with Go 1.15, the test framework will call
  1110. // os.Exit for us.
  1111. return nil, nil
  1112. }
  1113. var (
  1114. fnmain ast.Node
  1115. callsExit bool
  1116. callsRun bool
  1117. arg types.Object
  1118. )
  1119. fn := func(node ast.Node, push bool) bool {
  1120. if !push {
  1121. if fnmain != nil && node == fnmain {
  1122. if !callsExit && callsRun {
  1123. report.Report(pass, fnmain, "TestMain should call os.Exit to set exit code")
  1124. }
  1125. fnmain = nil
  1126. callsExit = false
  1127. callsRun = false
  1128. arg = nil
  1129. }
  1130. return true
  1131. }
  1132. switch node := node.(type) {
  1133. case *ast.FuncDecl:
  1134. if fnmain != nil {
  1135. return true
  1136. }
  1137. if !isTestMain(pass, node) {
  1138. return false
  1139. }
  1140. fnmain = node
  1141. arg = pass.TypesInfo.ObjectOf(node.Type.Params.List[0].Names[0])
  1142. return true
  1143. case *ast.CallExpr:
  1144. if code.IsCallTo(pass, node, "os.Exit") {
  1145. callsExit = true
  1146. return false
  1147. }
  1148. sel, ok := node.Fun.(*ast.SelectorExpr)
  1149. if !ok {
  1150. return true
  1151. }
  1152. ident, ok := sel.X.(*ast.Ident)
  1153. if !ok {
  1154. return true
  1155. }
  1156. if arg != pass.TypesInfo.ObjectOf(ident) {
  1157. return true
  1158. }
  1159. if sel.Sel.Name == "Run" {
  1160. callsRun = true
  1161. return false
  1162. }
  1163. return true
  1164. default:
  1165. lint.ExhaustiveTypeSwitch(node)
  1166. return true
  1167. }
  1168. }
  1169. pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.FuncDecl)(nil), (*ast.CallExpr)(nil)}, fn)
  1170. return nil, nil
  1171. }
  1172. func isTestMain(pass *analysis.Pass, decl *ast.FuncDecl) bool {
  1173. if decl.Name.Name != "TestMain" {
  1174. return false
  1175. }
  1176. if len(decl.Type.Params.List) != 1 {
  1177. return false
  1178. }
  1179. arg := decl.Type.Params.List[0]
  1180. if len(arg.Names) != 1 {
  1181. return false
  1182. }
  1183. return code.IsOfType(pass, arg.Type, "*testing.M")
  1184. }
  1185. func CheckExec(pass *analysis.Pass) (interface{}, error) {
  1186. fn := func(node ast.Node) {
  1187. call := node.(*ast.CallExpr)
  1188. if !code.IsCallTo(pass, call, "os/exec.Command") {
  1189. return
  1190. }
  1191. val, ok := code.ExprToString(pass, call.Args[knowledge.Arg("os/exec.Command.name")])
  1192. if !ok {
  1193. return
  1194. }
  1195. if !strings.Contains(val, " ") || strings.Contains(val, `\`) || strings.Contains(val, "/") {
  1196. return
  1197. }
  1198. report.Report(pass, call.Args[knowledge.Arg("os/exec.Command.name")],
  1199. "first argument to exec.Command looks like a shell command, but a program name or path are expected")
  1200. }
  1201. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  1202. return nil, nil
  1203. }
  1204. func CheckLoopEmptyDefault(pass *analysis.Pass) (interface{}, error) {
  1205. fn := func(node ast.Node) {
  1206. loop := node.(*ast.ForStmt)
  1207. if len(loop.Body.List) != 1 || loop.Cond != nil || loop.Init != nil {
  1208. return
  1209. }
  1210. sel, ok := loop.Body.List[0].(*ast.SelectStmt)
  1211. if !ok {
  1212. return
  1213. }
  1214. for _, c := range sel.Body.List {
  1215. // FIXME this leaves behind an empty line, and possibly
  1216. // comments in the default branch. We can't easily fix
  1217. // either.
  1218. if comm, ok := c.(*ast.CommClause); ok && comm.Comm == nil && len(comm.Body) == 0 {
  1219. report.Report(pass, comm, "should not have an empty default case in a for+select loop; the loop will spin",
  1220. report.Fixes(edit.Fix("remove empty default branch", edit.Delete(comm))))
  1221. // there can only be one default case
  1222. break
  1223. }
  1224. }
  1225. }
  1226. code.Preorder(pass, fn, (*ast.ForStmt)(nil))
  1227. return nil, nil
  1228. }
  1229. func CheckLhsRhsIdentical(pass *analysis.Pass) (interface{}, error) {
  1230. var isFloat func(T types.Type) bool
  1231. isFloat = func(T types.Type) bool {
  1232. tset := typeutil.NewTypeSet(T)
  1233. if len(tset.Terms) == 0 {
  1234. // no terms, so floats are a possibility
  1235. return true
  1236. }
  1237. return tset.Any(func(term *typeparams.Term) bool {
  1238. switch typ := term.Type().Underlying().(type) {
  1239. case *types.Basic:
  1240. kind := typ.Kind()
  1241. return kind == types.Float32 || kind == types.Float64
  1242. case *types.Array:
  1243. return isFloat(typ.Elem())
  1244. case *types.Struct:
  1245. for i := 0; i < typ.NumFields(); i++ {
  1246. if !isFloat(typ.Field(i).Type()) {
  1247. return false
  1248. }
  1249. }
  1250. return true
  1251. default:
  1252. return false
  1253. }
  1254. })
  1255. }
  1256. // TODO(dh): this check ignores the existence of side-effects and
  1257. // happily flags fn() == fn() – so far, we've had nobody complain
  1258. // about a false positive, and it's caught several bugs in real
  1259. // code.
  1260. //
  1261. // We special case functions from the math/rand package. Someone ran
  1262. // into the following false positive: "rand.Intn(2) - rand.Intn(2), which I wrote to generate values {-1, 0, 1} with {0.25, 0.5, 0.25} probability."
  1263. fn := func(node ast.Node) {
  1264. op := node.(*ast.BinaryExpr)
  1265. switch op.Op {
  1266. case token.EQL, token.NEQ:
  1267. case token.SUB, token.QUO, token.AND, token.REM, token.OR, token.XOR, token.AND_NOT,
  1268. token.LAND, token.LOR, token.LSS, token.GTR, token.LEQ, token.GEQ:
  1269. default:
  1270. // For some ops, such as + and *, it can make sense to
  1271. // have identical operands
  1272. return
  1273. }
  1274. if isFloat(pass.TypesInfo.TypeOf(op.X)) {
  1275. // 'float <op> float' makes sense for several operators.
  1276. // We've tried keeping an exact list of operators to allow, but floats keep surprising us. Let's just give up instead.
  1277. return
  1278. }
  1279. if reflect.TypeOf(op.X) != reflect.TypeOf(op.Y) {
  1280. return
  1281. }
  1282. if report.Render(pass, op.X) != report.Render(pass, op.Y) {
  1283. return
  1284. }
  1285. l1, ok1 := op.X.(*ast.BasicLit)
  1286. l2, ok2 := op.Y.(*ast.BasicLit)
  1287. if ok1 && ok2 && l1.Kind == token.INT && l2.Kind == l1.Kind && l1.Value == "0" && l2.Value == l1.Value && code.IsGenerated(pass, l1.Pos()) {
  1288. // cgo generates the following function call:
  1289. // _cgoCheckPointer(_cgoBase0, 0 == 0) – it uses 0 == 0
  1290. // instead of true in case the user shadowed the
  1291. // identifier. Ideally we'd restrict this exception to
  1292. // calls of _cgoCheckPointer, but it's not worth the
  1293. // hassle of keeping track of the stack. <lit> <op> <lit>
  1294. // are very rare to begin with, and we're mostly checking
  1295. // for them to catch typos such as 1 == 1 where the user
  1296. // meant to type i == 1. The odds of a false negative for
  1297. // 0 == 0 are slim.
  1298. return
  1299. }
  1300. if expr, ok := op.X.(*ast.CallExpr); ok {
  1301. call := code.CallName(pass, expr)
  1302. switch call {
  1303. case "math/rand.Int",
  1304. "math/rand.Int31",
  1305. "math/rand.Int31n",
  1306. "math/rand.Int63",
  1307. "math/rand.Int63n",
  1308. "math/rand.Intn",
  1309. "math/rand.Uint32",
  1310. "math/rand.Uint64",
  1311. "math/rand.ExpFloat64",
  1312. "math/rand.Float32",
  1313. "math/rand.Float64",
  1314. "math/rand.NormFloat64",
  1315. "(*math/rand.Rand).Int",
  1316. "(*math/rand.Rand).Int31",
  1317. "(*math/rand.Rand).Int31n",
  1318. "(*math/rand.Rand).Int63",
  1319. "(*math/rand.Rand).Int63n",
  1320. "(*math/rand.Rand).Intn",
  1321. "(*math/rand.Rand).Uint32",
  1322. "(*math/rand.Rand).Uint64",
  1323. "(*math/rand.Rand).ExpFloat64",
  1324. "(*math/rand.Rand).Float32",
  1325. "(*math/rand.Rand).Float64",
  1326. "(*math/rand.Rand).NormFloat64":
  1327. return
  1328. }
  1329. }
  1330. report.Report(pass, op, fmt.Sprintf("identical expressions on the left and right side of the '%s' operator", op.Op))
  1331. }
  1332. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  1333. return nil, nil
  1334. }
  1335. func CheckScopedBreak(pass *analysis.Pass) (interface{}, error) {
  1336. fn := func(node ast.Node) {
  1337. var body *ast.BlockStmt
  1338. switch node := node.(type) {
  1339. case *ast.ForStmt:
  1340. body = node.Body
  1341. case *ast.RangeStmt:
  1342. body = node.Body
  1343. default:
  1344. lint.ExhaustiveTypeSwitch(node)
  1345. }
  1346. for _, stmt := range body.List {
  1347. var blocks [][]ast.Stmt
  1348. switch stmt := stmt.(type) {
  1349. case *ast.SwitchStmt:
  1350. for _, c := range stmt.Body.List {
  1351. blocks = append(blocks, c.(*ast.CaseClause).Body)
  1352. }
  1353. case *ast.SelectStmt:
  1354. for _, c := range stmt.Body.List {
  1355. blocks = append(blocks, c.(*ast.CommClause).Body)
  1356. }
  1357. default:
  1358. continue
  1359. }
  1360. for _, body := range blocks {
  1361. if len(body) == 0 {
  1362. continue
  1363. }
  1364. lasts := []ast.Stmt{body[len(body)-1]}
  1365. // TODO(dh): unfold all levels of nested block
  1366. // statements, not just a single level if statement
  1367. if ifs, ok := lasts[0].(*ast.IfStmt); ok {
  1368. if len(ifs.Body.List) == 0 {
  1369. continue
  1370. }
  1371. lasts[0] = ifs.Body.List[len(ifs.Body.List)-1]
  1372. if block, ok := ifs.Else.(*ast.BlockStmt); ok {
  1373. if len(block.List) != 0 {
  1374. lasts = append(lasts, block.List[len(block.List)-1])
  1375. }
  1376. }
  1377. }
  1378. for _, last := range lasts {
  1379. branch, ok := last.(*ast.BranchStmt)
  1380. if !ok || branch.Tok != token.BREAK || branch.Label != nil {
  1381. continue
  1382. }
  1383. report.Report(pass, branch, "ineffective break statement. Did you mean to break out of the outer loop?")
  1384. }
  1385. }
  1386. }
  1387. }
  1388. code.Preorder(pass, fn, (*ast.ForStmt)(nil), (*ast.RangeStmt)(nil))
  1389. return nil, nil
  1390. }
  1391. func CheckUnsafePrintf(pass *analysis.Pass) (interface{}, error) {
  1392. fn := func(node ast.Node) {
  1393. call := node.(*ast.CallExpr)
  1394. name := code.CallName(pass, call)
  1395. var arg int
  1396. switch name {
  1397. case "fmt.Printf", "fmt.Sprintf", "log.Printf":
  1398. arg = knowledge.Arg("fmt.Printf.format")
  1399. case "fmt.Fprintf":
  1400. arg = knowledge.Arg("fmt.Fprintf.format")
  1401. default:
  1402. return
  1403. }
  1404. if len(call.Args) != arg+1 {
  1405. return
  1406. }
  1407. switch call.Args[arg].(type) {
  1408. case *ast.CallExpr, *ast.Ident:
  1409. default:
  1410. return
  1411. }
  1412. if _, ok := pass.TypesInfo.TypeOf(call.Args[arg]).(*types.Tuple); ok {
  1413. // the called function returns multiple values and got
  1414. // splatted into the call. for all we know, it is
  1415. // returning good arguments.
  1416. return
  1417. }
  1418. alt := name[:len(name)-1]
  1419. report.Report(pass, call,
  1420. "printf-style function with dynamic format string and no further arguments should use print-style function instead",
  1421. report.Fixes(edit.Fix(fmt.Sprintf("use %s instead of %s", alt, name), edit.ReplaceWithString(call.Fun, alt))))
  1422. }
  1423. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  1424. return nil, nil
  1425. }
  1426. func CheckEarlyDefer(pass *analysis.Pass) (interface{}, error) {
  1427. fn := func(node ast.Node) {
  1428. block := node.(*ast.BlockStmt)
  1429. if len(block.List) < 2 {
  1430. return
  1431. }
  1432. for i, stmt := range block.List {
  1433. if i == len(block.List)-1 {
  1434. break
  1435. }
  1436. assign, ok := stmt.(*ast.AssignStmt)
  1437. if !ok {
  1438. continue
  1439. }
  1440. if len(assign.Rhs) != 1 {
  1441. continue
  1442. }
  1443. if len(assign.Lhs) < 2 {
  1444. continue
  1445. }
  1446. if lhs, ok := assign.Lhs[len(assign.Lhs)-1].(*ast.Ident); ok && lhs.Name == "_" {
  1447. continue
  1448. }
  1449. call, ok := assign.Rhs[0].(*ast.CallExpr)
  1450. if !ok {
  1451. continue
  1452. }
  1453. sig, ok := pass.TypesInfo.TypeOf(call.Fun).(*types.Signature)
  1454. if !ok {
  1455. continue
  1456. }
  1457. if sig.Results().Len() < 2 {
  1458. continue
  1459. }
  1460. last := sig.Results().At(sig.Results().Len() - 1)
  1461. // FIXME(dh): check that it's error from universe, not
  1462. // another type of the same name
  1463. if last.Type().String() != "error" {
  1464. continue
  1465. }
  1466. lhs, ok := assign.Lhs[0].(*ast.Ident)
  1467. if !ok {
  1468. continue
  1469. }
  1470. def, ok := block.List[i+1].(*ast.DeferStmt)
  1471. if !ok {
  1472. continue
  1473. }
  1474. sel, ok := def.Call.Fun.(*ast.SelectorExpr)
  1475. if !ok {
  1476. continue
  1477. }
  1478. ident, ok := selectorX(sel).(*ast.Ident)
  1479. if !ok {
  1480. continue
  1481. }
  1482. if ident.Obj != lhs.Obj {
  1483. continue
  1484. }
  1485. if sel.Sel.Name != "Close" {
  1486. continue
  1487. }
  1488. report.Report(pass, def, fmt.Sprintf("should check returned error before deferring %s", report.Render(pass, def.Call)))
  1489. }
  1490. }
  1491. code.Preorder(pass, fn, (*ast.BlockStmt)(nil))
  1492. return nil, nil
  1493. }
  1494. func selectorX(sel *ast.SelectorExpr) ast.Node {
  1495. switch x := sel.X.(type) {
  1496. case *ast.SelectorExpr:
  1497. return selectorX(x)
  1498. default:
  1499. return x
  1500. }
  1501. }
  1502. func CheckEmptyCriticalSection(pass *analysis.Pass) (interface{}, error) {
  1503. if pass.Pkg.Path() == "sync_test" {
  1504. // exception for the sync package's tests
  1505. return nil, nil
  1506. }
  1507. // Initially it might seem like this check would be easier to
  1508. // implement using IR. After all, we're only checking for two
  1509. // consecutive method calls. In reality, however, there may be any
  1510. // number of other instructions between the lock and unlock, while
  1511. // still constituting an empty critical section. For example,
  1512. // given `m.x().Lock(); m.x().Unlock()`, there will be a call to
  1513. // x(). In the AST-based approach, this has a tiny potential for a
  1514. // false positive (the second call to x might be doing work that
  1515. // is protected by the mutex). In an IR-based approach, however,
  1516. // it would miss a lot of real bugs.
  1517. mutexParams := func(s ast.Stmt) (x ast.Expr, funcName string, ok bool) {
  1518. expr, ok := s.(*ast.ExprStmt)
  1519. if !ok {
  1520. return nil, "", false
  1521. }
  1522. call, ok := expr.X.(*ast.CallExpr)
  1523. if !ok {
  1524. return nil, "", false
  1525. }
  1526. sel, ok := call.Fun.(*ast.SelectorExpr)
  1527. if !ok {
  1528. return nil, "", false
  1529. }
  1530. fn, ok := pass.TypesInfo.ObjectOf(sel.Sel).(*types.Func)
  1531. if !ok {
  1532. return nil, "", false
  1533. }
  1534. sig := fn.Type().(*types.Signature)
  1535. if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
  1536. return nil, "", false
  1537. }
  1538. return sel.X, fn.Name(), true
  1539. }
  1540. fn := func(node ast.Node) {
  1541. block := node.(*ast.BlockStmt)
  1542. if len(block.List) < 2 {
  1543. return
  1544. }
  1545. for i := range block.List[:len(block.List)-1] {
  1546. sel1, method1, ok1 := mutexParams(block.List[i])
  1547. sel2, method2, ok2 := mutexParams(block.List[i+1])
  1548. if !ok1 || !ok2 || report.Render(pass, sel1) != report.Render(pass, sel2) {
  1549. continue
  1550. }
  1551. if (method1 == "Lock" && method2 == "Unlock") ||
  1552. (method1 == "RLock" && method2 == "RUnlock") {
  1553. report.Report(pass, block.List[i+1], "empty critical section")
  1554. }
  1555. }
  1556. }
  1557. code.Preorder(pass, fn, (*ast.BlockStmt)(nil))
  1558. return nil, nil
  1559. }
  1560. var (
  1561. // cgo produces code like fn(&*_Cvar_kSomeCallbacks) which we don't
  1562. // want to flag.
  1563. cgoIdent = regexp.MustCompile(`^_C(func|var)_.+$`)
  1564. checkIneffectiveCopyQ1 = pattern.MustParse(`(UnaryExpr "&" (StarExpr obj))`)
  1565. checkIneffectiveCopyQ2 = pattern.MustParse(`(StarExpr (UnaryExpr "&" _))`)
  1566. )
  1567. func CheckIneffectiveCopy(pass *analysis.Pass) (interface{}, error) {
  1568. fn := func(node ast.Node) {
  1569. if m, ok := code.Match(pass, checkIneffectiveCopyQ1, node); ok {
  1570. if ident, ok := m.State["obj"].(*ast.Ident); !ok || !cgoIdent.MatchString(ident.Name) {
  1571. report.Report(pass, node, "&*x will be simplified to x. It will not copy x.")
  1572. }
  1573. } else if _, ok := code.Match(pass, checkIneffectiveCopyQ2, node); ok {
  1574. report.Report(pass, node, "*&x will be simplified to x. It will not copy x.")
  1575. }
  1576. }
  1577. code.Preorder(pass, fn, (*ast.UnaryExpr)(nil), (*ast.StarExpr)(nil))
  1578. return nil, nil
  1579. }
  1580. func CheckCanonicalHeaderKey(pass *analysis.Pass) (interface{}, error) {
  1581. fn := func(node ast.Node, push bool) bool {
  1582. if !push {
  1583. return false
  1584. }
  1585. if assign, ok := node.(*ast.AssignStmt); ok {
  1586. // TODO(dh): This risks missing some Header reads, for
  1587. // example in `h1["foo"] = h2["foo"]` – these edge
  1588. // cases are probably rare enough to ignore for now.
  1589. for _, expr := range assign.Lhs {
  1590. op, ok := expr.(*ast.IndexExpr)
  1591. if !ok {
  1592. continue
  1593. }
  1594. if code.IsOfType(pass, op.X, "net/http.Header") {
  1595. return false
  1596. }
  1597. }
  1598. return true
  1599. }
  1600. op, ok := node.(*ast.IndexExpr)
  1601. if !ok {
  1602. return true
  1603. }
  1604. if !code.IsOfType(pass, op.X, "net/http.Header") {
  1605. return true
  1606. }
  1607. s, ok := code.ExprToString(pass, op.Index)
  1608. if !ok {
  1609. return true
  1610. }
  1611. canonical := http.CanonicalHeaderKey(s)
  1612. if s == canonical {
  1613. return true
  1614. }
  1615. var fix analysis.SuggestedFix
  1616. switch op.Index.(type) {
  1617. case *ast.BasicLit:
  1618. fix = edit.Fix("canonicalize header key", edit.ReplaceWithString(op.Index, strconv.Quote(canonical)))
  1619. case *ast.Ident:
  1620. call := &ast.CallExpr{
  1621. Fun: edit.Selector("http", "CanonicalHeaderKey"),
  1622. Args: []ast.Expr{op.Index},
  1623. }
  1624. fix = edit.Fix("wrap in http.CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, op.Index, call))
  1625. }
  1626. msg := fmt.Sprintf("keys in http.Header are canonicalized, %q is not canonical; fix the constant or use http.CanonicalHeaderKey", s)
  1627. if fix.Message != "" {
  1628. report.Report(pass, op, msg, report.Fixes(fix))
  1629. } else {
  1630. report.Report(pass, op, msg)
  1631. }
  1632. return true
  1633. }
  1634. pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.AssignStmt)(nil), (*ast.IndexExpr)(nil)}, fn)
  1635. return nil, nil
  1636. }
  1637. func CheckBenchmarkN(pass *analysis.Pass) (interface{}, error) {
  1638. fn := func(node ast.Node) {
  1639. assign := node.(*ast.AssignStmt)
  1640. if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
  1641. return
  1642. }
  1643. sel, ok := assign.Lhs[0].(*ast.SelectorExpr)
  1644. if !ok {
  1645. return
  1646. }
  1647. if sel.Sel.Name != "N" {
  1648. return
  1649. }
  1650. if !code.IsOfType(pass, sel.X, "*testing.B") {
  1651. return
  1652. }
  1653. report.Report(pass, assign, fmt.Sprintf("should not assign to %s", report.Render(pass, sel)))
  1654. }
  1655. code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
  1656. return nil, nil
  1657. }
  1658. func CheckUnreadVariableValues(pass *analysis.Pass) (interface{}, error) {
  1659. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  1660. if irutil.IsExample(fn) {
  1661. continue
  1662. }
  1663. node := fn.Source()
  1664. if node == nil {
  1665. continue
  1666. }
  1667. if gen, ok := code.Generator(pass, node.Pos()); ok && gen == facts.Goyacc {
  1668. // Don't flag unused values in code generated by goyacc.
  1669. // There may be hundreds of those due to the way the state
  1670. // machine is constructed.
  1671. continue
  1672. }
  1673. switchTags := map[ir.Value]struct{}{}
  1674. ast.Inspect(node, func(node ast.Node) bool {
  1675. s, ok := node.(*ast.SwitchStmt)
  1676. if !ok {
  1677. return true
  1678. }
  1679. v, _ := fn.ValueForExpr(s.Tag)
  1680. switchTags[v] = struct{}{}
  1681. return true
  1682. })
  1683. // OPT(dh): don't use a map, possibly use a bitset
  1684. var hasUse func(v ir.Value, seen map[ir.Value]struct{}) bool
  1685. hasUse = func(v ir.Value, seen map[ir.Value]struct{}) bool {
  1686. if _, ok := seen[v]; ok {
  1687. return false
  1688. }
  1689. if _, ok := switchTags[v]; ok {
  1690. return true
  1691. }
  1692. refs := v.Referrers()
  1693. if refs == nil {
  1694. // TODO investigate why refs can be nil
  1695. return true
  1696. }
  1697. for _, ref := range *refs {
  1698. switch ref := ref.(type) {
  1699. case *ir.DebugRef:
  1700. case *ir.Sigma:
  1701. if seen == nil {
  1702. seen = map[ir.Value]struct{}{}
  1703. }
  1704. seen[v] = struct{}{}
  1705. if hasUse(ref, seen) {
  1706. return true
  1707. }
  1708. case *ir.Phi:
  1709. if seen == nil {
  1710. seen = map[ir.Value]struct{}{}
  1711. }
  1712. seen[v] = struct{}{}
  1713. if hasUse(ref, seen) {
  1714. return true
  1715. }
  1716. default:
  1717. return true
  1718. }
  1719. }
  1720. return false
  1721. }
  1722. ast.Inspect(node, func(node ast.Node) bool {
  1723. assign, ok := node.(*ast.AssignStmt)
  1724. if !ok {
  1725. return true
  1726. }
  1727. if len(assign.Lhs) > 1 && len(assign.Rhs) == 1 {
  1728. // Either a function call with multiple return values,
  1729. // or a comma-ok assignment
  1730. val, _ := fn.ValueForExpr(assign.Rhs[0])
  1731. if val == nil {
  1732. return true
  1733. }
  1734. refs := val.Referrers()
  1735. if refs == nil {
  1736. return true
  1737. }
  1738. for _, ref := range *refs {
  1739. ex, ok := ref.(*ir.Extract)
  1740. if !ok {
  1741. continue
  1742. }
  1743. if !hasUse(ex, nil) {
  1744. lhs := assign.Lhs[ex.Index]
  1745. if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
  1746. continue
  1747. }
  1748. report.Report(pass, assign, fmt.Sprintf("this value of %s is never used", lhs))
  1749. }
  1750. }
  1751. return true
  1752. }
  1753. for i, lhs := range assign.Lhs {
  1754. rhs := assign.Rhs[i]
  1755. if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
  1756. continue
  1757. }
  1758. val, _ := fn.ValueForExpr(rhs)
  1759. if val == nil {
  1760. continue
  1761. }
  1762. if _, ok := val.(*ir.Const); ok {
  1763. // a zero-valued constant, for example in 'foo := []string(nil)'
  1764. continue
  1765. }
  1766. if !hasUse(val, nil) {
  1767. report.Report(pass, assign, fmt.Sprintf("this value of %s is never used", lhs))
  1768. }
  1769. }
  1770. return true
  1771. })
  1772. }
  1773. return nil, nil
  1774. }
  1775. func CheckPredeterminedBooleanExprs(pass *analysis.Pass) (interface{}, error) {
  1776. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  1777. for _, block := range fn.Blocks {
  1778. for _, ins := range block.Instrs {
  1779. binop, ok := ins.(*ir.BinOp)
  1780. if !ok {
  1781. continue
  1782. }
  1783. switch binop.Op {
  1784. case token.GTR, token.LSS, token.EQL, token.NEQ, token.LEQ, token.GEQ:
  1785. default:
  1786. continue
  1787. }
  1788. xs, ok1 := consts(binop.X, nil, nil)
  1789. ys, ok2 := consts(binop.Y, nil, nil)
  1790. if !ok1 || !ok2 || len(xs) == 0 || len(ys) == 0 {
  1791. continue
  1792. }
  1793. trues := 0
  1794. for _, x := range xs {
  1795. for _, y := range ys {
  1796. if x.Value == nil {
  1797. if y.Value == nil {
  1798. trues++
  1799. }
  1800. continue
  1801. }
  1802. if constant.Compare(x.Value, binop.Op, y.Value) {
  1803. trues++
  1804. }
  1805. }
  1806. }
  1807. b := trues != 0
  1808. if trues == 0 || trues == len(xs)*len(ys) {
  1809. report.Report(pass, binop, fmt.Sprintf("binary expression is always %t for all possible values (%s %s %s)", b, xs, binop.Op, ys))
  1810. }
  1811. }
  1812. }
  1813. }
  1814. return nil, nil
  1815. }
  1816. func CheckNilMaps(pass *analysis.Pass) (interface{}, error) {
  1817. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  1818. for _, block := range fn.Blocks {
  1819. for _, ins := range block.Instrs {
  1820. mu, ok := ins.(*ir.MapUpdate)
  1821. if !ok {
  1822. continue
  1823. }
  1824. c, ok := irutil.Flatten(mu.Map).(*ir.Const)
  1825. if !ok {
  1826. continue
  1827. }
  1828. if c.Value != nil {
  1829. continue
  1830. }
  1831. report.Report(pass, mu, "assignment to nil map")
  1832. }
  1833. }
  1834. }
  1835. return nil, nil
  1836. }
  1837. func CheckExtremeComparison(pass *analysis.Pass) (interface{}, error) {
  1838. isobj := func(expr ast.Expr, name string) bool {
  1839. sel, ok := expr.(*ast.SelectorExpr)
  1840. if !ok {
  1841. return false
  1842. }
  1843. return typeutil.IsObject(pass.TypesInfo.ObjectOf(sel.Sel), name)
  1844. }
  1845. fn := func(node ast.Node) {
  1846. expr := node.(*ast.BinaryExpr)
  1847. tx := pass.TypesInfo.TypeOf(expr.X)
  1848. basic, ok := tx.Underlying().(*types.Basic)
  1849. if !ok {
  1850. return
  1851. }
  1852. var max string
  1853. var min string
  1854. switch basic.Kind() {
  1855. case types.Uint8:
  1856. max = "math.MaxUint8"
  1857. case types.Uint16:
  1858. max = "math.MaxUint16"
  1859. case types.Uint32:
  1860. max = "math.MaxUint32"
  1861. case types.Uint64:
  1862. max = "math.MaxUint64"
  1863. case types.Uint:
  1864. max = "math.MaxUint64"
  1865. case types.Int8:
  1866. min = "math.MinInt8"
  1867. max = "math.MaxInt8"
  1868. case types.Int16:
  1869. min = "math.MinInt16"
  1870. max = "math.MaxInt16"
  1871. case types.Int32:
  1872. min = "math.MinInt32"
  1873. max = "math.MaxInt32"
  1874. case types.Int64:
  1875. min = "math.MinInt64"
  1876. max = "math.MaxInt64"
  1877. case types.Int:
  1878. min = "math.MinInt64"
  1879. max = "math.MaxInt64"
  1880. }
  1881. if (expr.Op == token.GTR || expr.Op == token.GEQ) && isobj(expr.Y, max) ||
  1882. (expr.Op == token.LSS || expr.Op == token.LEQ) && isobj(expr.X, max) {
  1883. report.Report(pass, expr, fmt.Sprintf("no value of type %s is greater than %s", basic, max))
  1884. }
  1885. if expr.Op == token.LEQ && isobj(expr.Y, max) ||
  1886. expr.Op == token.GEQ && isobj(expr.X, max) {
  1887. report.Report(pass, expr, fmt.Sprintf("every value of type %s is <= %s", basic, max))
  1888. }
  1889. isZeroLiteral := func(expr ast.Expr) bool {
  1890. return code.IsIntegerLiteral(pass, expr, constant.MakeInt64(0))
  1891. }
  1892. if (basic.Info() & types.IsUnsigned) != 0 {
  1893. if (expr.Op == token.LSS && isZeroLiteral(expr.Y)) ||
  1894. (expr.Op == token.GTR && isZeroLiteral(expr.X)) {
  1895. report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than 0", basic))
  1896. }
  1897. if expr.Op == token.GEQ && isZeroLiteral(expr.Y) ||
  1898. expr.Op == token.LEQ && isZeroLiteral(expr.X) {
  1899. report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= 0", basic))
  1900. }
  1901. } else {
  1902. if (expr.Op == token.LSS || expr.Op == token.LEQ) && isobj(expr.Y, min) ||
  1903. (expr.Op == token.GTR || expr.Op == token.GEQ) && isobj(expr.X, min) {
  1904. report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than %s", basic, min))
  1905. }
  1906. if expr.Op == token.GEQ && isobj(expr.Y, min) ||
  1907. expr.Op == token.LEQ && isobj(expr.X, min) {
  1908. report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= %s", basic, min))
  1909. }
  1910. }
  1911. }
  1912. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  1913. return nil, nil
  1914. }
  1915. func consts(val ir.Value, out []*ir.Const, visitedPhis map[string]bool) ([]*ir.Const, bool) {
  1916. if visitedPhis == nil {
  1917. visitedPhis = map[string]bool{}
  1918. }
  1919. var ok bool
  1920. switch val := val.(type) {
  1921. case *ir.Phi:
  1922. if visitedPhis[val.Name()] {
  1923. break
  1924. }
  1925. visitedPhis[val.Name()] = true
  1926. vals := val.Operands(nil)
  1927. for _, phival := range vals {
  1928. out, ok = consts(*phival, out, visitedPhis)
  1929. if !ok {
  1930. return nil, false
  1931. }
  1932. }
  1933. case *ir.Const:
  1934. out = append(out, val)
  1935. case *ir.Convert:
  1936. out, ok = consts(val.X, out, visitedPhis)
  1937. if !ok {
  1938. return nil, false
  1939. }
  1940. default:
  1941. return nil, false
  1942. }
  1943. if len(out) < 2 {
  1944. return out, true
  1945. }
  1946. uniq := []*ir.Const{out[0]}
  1947. for _, val := range out[1:] {
  1948. if val.Value == uniq[len(uniq)-1].Value {
  1949. continue
  1950. }
  1951. uniq = append(uniq, val)
  1952. }
  1953. return uniq, true
  1954. }
  1955. func CheckLoopCondition(pass *analysis.Pass) (interface{}, error) {
  1956. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  1957. cb := func(node ast.Node) bool {
  1958. loop, ok := node.(*ast.ForStmt)
  1959. if !ok {
  1960. return true
  1961. }
  1962. if loop.Init == nil || loop.Cond == nil || loop.Post == nil {
  1963. return true
  1964. }
  1965. init, ok := loop.Init.(*ast.AssignStmt)
  1966. if !ok || len(init.Lhs) != 1 || len(init.Rhs) != 1 {
  1967. return true
  1968. }
  1969. cond, ok := loop.Cond.(*ast.BinaryExpr)
  1970. if !ok {
  1971. return true
  1972. }
  1973. x, ok := cond.X.(*ast.Ident)
  1974. if !ok {
  1975. return true
  1976. }
  1977. lhs, ok := init.Lhs[0].(*ast.Ident)
  1978. if !ok {
  1979. return true
  1980. }
  1981. if x.Obj != lhs.Obj {
  1982. return true
  1983. }
  1984. if _, ok := loop.Post.(*ast.IncDecStmt); !ok {
  1985. return true
  1986. }
  1987. v, isAddr := fn.ValueForExpr(cond.X)
  1988. if v == nil || isAddr {
  1989. return true
  1990. }
  1991. switch v := v.(type) {
  1992. case *ir.Phi:
  1993. ops := v.Operands(nil)
  1994. if len(ops) != 2 {
  1995. return true
  1996. }
  1997. _, ok := (*ops[0]).(*ir.Const)
  1998. if !ok {
  1999. return true
  2000. }
  2001. sigma, ok := (*ops[1]).(*ir.Sigma)
  2002. if !ok {
  2003. return true
  2004. }
  2005. if sigma.X != v {
  2006. return true
  2007. }
  2008. case *ir.Load:
  2009. return true
  2010. }
  2011. report.Report(pass, cond, "variable in loop condition never changes")
  2012. return true
  2013. }
  2014. if source := fn.Source(); source != nil {
  2015. ast.Inspect(source, cb)
  2016. }
  2017. }
  2018. return nil, nil
  2019. }
  2020. func CheckArgOverwritten(pass *analysis.Pass) (interface{}, error) {
  2021. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2022. cb := func(node ast.Node) bool {
  2023. var typ *ast.FuncType
  2024. var body *ast.BlockStmt
  2025. switch fn := node.(type) {
  2026. case *ast.FuncDecl:
  2027. typ = fn.Type
  2028. body = fn.Body
  2029. case *ast.FuncLit:
  2030. typ = fn.Type
  2031. body = fn.Body
  2032. }
  2033. if body == nil {
  2034. return true
  2035. }
  2036. if len(typ.Params.List) == 0 {
  2037. return true
  2038. }
  2039. for _, field := range typ.Params.List {
  2040. for _, arg := range field.Names {
  2041. obj := pass.TypesInfo.ObjectOf(arg)
  2042. var irobj *ir.Parameter
  2043. for _, param := range fn.Params {
  2044. if param.Object() == obj {
  2045. irobj = param
  2046. break
  2047. }
  2048. }
  2049. if irobj == nil {
  2050. continue
  2051. }
  2052. refs := irobj.Referrers()
  2053. if refs == nil {
  2054. continue
  2055. }
  2056. if len(irutil.FilterDebug(*refs)) != 0 {
  2057. continue
  2058. }
  2059. var assignment ast.Node
  2060. ast.Inspect(body, func(node ast.Node) bool {
  2061. if assignment != nil {
  2062. return false
  2063. }
  2064. assign, ok := node.(*ast.AssignStmt)
  2065. if !ok {
  2066. return true
  2067. }
  2068. for _, lhs := range assign.Lhs {
  2069. ident, ok := lhs.(*ast.Ident)
  2070. if !ok {
  2071. continue
  2072. }
  2073. if pass.TypesInfo.ObjectOf(ident) == obj {
  2074. assignment = assign
  2075. return false
  2076. }
  2077. }
  2078. return true
  2079. })
  2080. if assignment != nil {
  2081. report.Report(pass, arg, fmt.Sprintf("argument %s is overwritten before first use", arg),
  2082. report.Related(assignment, fmt.Sprintf("assignment to %s", arg)))
  2083. }
  2084. }
  2085. }
  2086. return true
  2087. }
  2088. if source := fn.Source(); source != nil {
  2089. ast.Inspect(source, cb)
  2090. }
  2091. }
  2092. return nil, nil
  2093. }
  2094. func CheckIneffectiveLoop(pass *analysis.Pass) (interface{}, error) {
  2095. // This check detects some, but not all unconditional loop exits.
  2096. // We give up in the following cases:
  2097. //
  2098. // - a goto anywhere in the loop. The goto might skip over our
  2099. // return, and we don't check that it doesn't.
  2100. //
  2101. // - any nested, unlabelled continue, even if it is in another
  2102. // loop or closure.
  2103. fn := func(node ast.Node) {
  2104. var body *ast.BlockStmt
  2105. switch fn := node.(type) {
  2106. case *ast.FuncDecl:
  2107. body = fn.Body
  2108. case *ast.FuncLit:
  2109. body = fn.Body
  2110. default:
  2111. lint.ExhaustiveTypeSwitch(node)
  2112. }
  2113. if body == nil {
  2114. return
  2115. }
  2116. labels := map[*ast.Object]ast.Stmt{}
  2117. ast.Inspect(body, func(node ast.Node) bool {
  2118. label, ok := node.(*ast.LabeledStmt)
  2119. if !ok {
  2120. return true
  2121. }
  2122. labels[label.Label.Obj] = label.Stmt
  2123. return true
  2124. })
  2125. ast.Inspect(body, func(node ast.Node) bool {
  2126. var loop ast.Node
  2127. var body *ast.BlockStmt
  2128. switch node := node.(type) {
  2129. case *ast.ForStmt:
  2130. body = node.Body
  2131. loop = node
  2132. case *ast.RangeStmt:
  2133. ok := typeutil.All(pass.TypesInfo.TypeOf(node.X), func(term *typeparams.Term) bool {
  2134. switch term.Type().Underlying().(type) {
  2135. case *types.Slice, *types.Chan, *types.Basic, *types.Pointer, *types.Array:
  2136. return true
  2137. case *types.Map:
  2138. // looping once over a map is a valid pattern for
  2139. // getting an arbitrary element.
  2140. return false
  2141. default:
  2142. lint.ExhaustiveTypeSwitch(term.Type().Underlying())
  2143. return false
  2144. }
  2145. })
  2146. if !ok {
  2147. return true
  2148. }
  2149. body = node.Body
  2150. loop = node
  2151. default:
  2152. return true
  2153. }
  2154. if len(body.List) < 2 {
  2155. // TODO(dh): is this check needed? when body.List < 2,
  2156. // then we can't find both an unconditional exit and a
  2157. // branching statement (if, ...). and we don't flag
  2158. // unconditional exits if there has been no branching
  2159. // in the loop body.
  2160. // avoid flagging the somewhat common pattern of using
  2161. // a range loop to get the first element in a slice,
  2162. // or the first rune in a string.
  2163. return true
  2164. }
  2165. var unconditionalExit ast.Node
  2166. hasBranching := false
  2167. for _, stmt := range body.List {
  2168. switch stmt := stmt.(type) {
  2169. case *ast.BranchStmt:
  2170. switch stmt.Tok {
  2171. case token.BREAK:
  2172. if stmt.Label == nil || labels[stmt.Label.Obj] == loop {
  2173. unconditionalExit = stmt
  2174. }
  2175. case token.CONTINUE:
  2176. if stmt.Label == nil || labels[stmt.Label.Obj] == loop {
  2177. unconditionalExit = nil
  2178. return false
  2179. }
  2180. }
  2181. case *ast.ReturnStmt:
  2182. unconditionalExit = stmt
  2183. case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.SwitchStmt, *ast.SelectStmt:
  2184. hasBranching = true
  2185. }
  2186. }
  2187. if unconditionalExit == nil || !hasBranching {
  2188. return false
  2189. }
  2190. ast.Inspect(body, func(node ast.Node) bool {
  2191. if branch, ok := node.(*ast.BranchStmt); ok {
  2192. switch branch.Tok {
  2193. case token.GOTO:
  2194. unconditionalExit = nil
  2195. return false
  2196. case token.CONTINUE:
  2197. if branch.Label != nil && labels[branch.Label.Obj] != loop {
  2198. return true
  2199. }
  2200. unconditionalExit = nil
  2201. return false
  2202. }
  2203. }
  2204. return true
  2205. })
  2206. if unconditionalExit != nil {
  2207. report.Report(pass, unconditionalExit, "the surrounding loop is unconditionally terminated")
  2208. }
  2209. return true
  2210. })
  2211. }
  2212. code.Preorder(pass, fn, (*ast.FuncDecl)(nil), (*ast.FuncLit)(nil))
  2213. return nil, nil
  2214. }
  2215. var checkNilContextQ = pattern.MustParse(`(CallExpr fun@(Function _) (Builtin "nil"):_)`)
  2216. func CheckNilContext(pass *analysis.Pass) (interface{}, error) {
  2217. todo := &ast.CallExpr{
  2218. Fun: edit.Selector("context", "TODO"),
  2219. }
  2220. bg := &ast.CallExpr{
  2221. Fun: edit.Selector("context", "Background"),
  2222. }
  2223. fn := func(node ast.Node) {
  2224. m, ok := code.Match(pass, checkNilContextQ, node)
  2225. if !ok {
  2226. return
  2227. }
  2228. call := node.(*ast.CallExpr)
  2229. fun, ok := m.State["fun"].(*types.Func)
  2230. if !ok {
  2231. // it might also be a builtin
  2232. return
  2233. }
  2234. sig := fun.Type().(*types.Signature)
  2235. if sig.Params().Len() == 0 {
  2236. // Our CallExpr might've matched a method expression, like
  2237. // (*T).Foo(nil) – here, nil isn't the first argument of
  2238. // the Foo method, but the method receiver.
  2239. return
  2240. }
  2241. if !typeutil.IsType(sig.Params().At(0).Type(), "context.Context") {
  2242. return
  2243. }
  2244. report.Report(pass, call.Args[0],
  2245. "do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use", report.Fixes(
  2246. edit.Fix("use context.TODO", edit.ReplaceWithNode(pass.Fset, call.Args[0], todo)),
  2247. edit.Fix("use context.Background", edit.ReplaceWithNode(pass.Fset, call.Args[0], bg))))
  2248. }
  2249. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  2250. return nil, nil
  2251. }
  2252. var (
  2253. checkSeekerQ = pattern.MustParse(`(CallExpr fun@(SelectorExpr _ (Ident "Seek")) [arg1@(SelectorExpr (Ident "io") (Ident (Or "SeekStart" "SeekCurrent" "SeekEnd"))) arg2])`)
  2254. checkSeekerR = pattern.MustParse(`(CallExpr fun [arg2 arg1])`)
  2255. )
  2256. func CheckSeeker(pass *analysis.Pass) (interface{}, error) {
  2257. fn := func(node ast.Node) {
  2258. if _, edits, ok := code.MatchAndEdit(pass, checkSeekerQ, checkSeekerR, node); ok {
  2259. report.Report(pass, node, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead",
  2260. report.Fixes(edit.Fix("swap arguments", edits...)))
  2261. }
  2262. }
  2263. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  2264. return nil, nil
  2265. }
  2266. func CheckIneffectiveAppend(pass *analysis.Pass) (interface{}, error) {
  2267. isAppend := func(ins ir.Value) bool {
  2268. call, ok := ins.(*ir.Call)
  2269. if !ok {
  2270. return false
  2271. }
  2272. if call.Call.IsInvoke() {
  2273. return false
  2274. }
  2275. if builtin, ok := call.Call.Value.(*ir.Builtin); !ok || builtin.Name() != "append" {
  2276. return false
  2277. }
  2278. return true
  2279. }
  2280. // We have to be careful about aliasing.
  2281. // Multiple slices may refer to the same backing array,
  2282. // making appends observable even when we don't see the result of append be used anywhere.
  2283. //
  2284. // We will have to restrict ourselves to slices that have been allocated within the function,
  2285. // haven't been sliced,
  2286. // and haven't been passed anywhere that could retain them (such as function calls or memory stores).
  2287. //
  2288. // We check whether an append should be flagged in two steps.
  2289. //
  2290. // In the first step, we look at the data flow graph, starting in reverse from the argument to append, till we reach the root.
  2291. // This graph must only consist of the following instructions:
  2292. //
  2293. // - phi
  2294. // - sigma
  2295. // - slice
  2296. // - const nil
  2297. // - MakeSlice
  2298. // - Alloc
  2299. // - calls to append
  2300. //
  2301. // If this step succeeds, we look at all referrers of the values found in the first step, recursively.
  2302. // These referrers must either be in the set of values found in the first step,
  2303. // be DebugRefs,
  2304. // or fulfill the same type requirements as step 1, with the exception of appends, which are forbidden.
  2305. //
  2306. // If both steps succeed then we know that the backing array hasn't been aliased in an observable manner.
  2307. //
  2308. // We could relax these restrictions by making use of additional information:
  2309. // - if we passed the slice to a function that doesn't retain the slice then we can still flag it
  2310. // - if a slice has been sliced but is dead afterwards, we can flag appends to the new slice
  2311. // OPT(dh): We could cache the results of both validate functions.
  2312. // However, we only use these functions on values that we otherwise want to flag, which are very few.
  2313. // Not caching values hasn't increased the runtimes for the standard library nor k8s.
  2314. var validateArgument func(v ir.Value, seen map[ir.Value]struct{}) bool
  2315. validateArgument = func(v ir.Value, seen map[ir.Value]struct{}) bool {
  2316. if _, ok := seen[v]; ok {
  2317. // break cycle
  2318. return true
  2319. }
  2320. seen[v] = struct{}{}
  2321. switch v := v.(type) {
  2322. case *ir.Phi:
  2323. for _, edge := range v.Edges {
  2324. if !validateArgument(edge, seen) {
  2325. return false
  2326. }
  2327. }
  2328. return true
  2329. case *ir.Sigma:
  2330. return validateArgument(v.X, seen)
  2331. case *ir.Slice:
  2332. return validateArgument(v.X, seen)
  2333. case *ir.Const:
  2334. return true
  2335. case *ir.MakeSlice:
  2336. return true
  2337. case *ir.Alloc:
  2338. return true
  2339. case *ir.Call:
  2340. if isAppend(v) {
  2341. return validateArgument(v.Call.Args[0], seen)
  2342. }
  2343. return false
  2344. default:
  2345. return false
  2346. }
  2347. }
  2348. var validateReferrers func(v ir.Value, seen map[ir.Instruction]struct{}) bool
  2349. validateReferrers = func(v ir.Value, seen map[ir.Instruction]struct{}) bool {
  2350. for _, ref := range *v.Referrers() {
  2351. if _, ok := seen[ref]; ok {
  2352. continue
  2353. }
  2354. seen[ref] = struct{}{}
  2355. switch ref.(type) {
  2356. case *ir.Phi:
  2357. case *ir.Sigma:
  2358. case *ir.Slice:
  2359. case *ir.Const:
  2360. case *ir.MakeSlice:
  2361. case *ir.Alloc:
  2362. case *ir.DebugRef:
  2363. default:
  2364. return false
  2365. }
  2366. if ref, ok := ref.(ir.Value); ok {
  2367. if !validateReferrers(ref, seen) {
  2368. return false
  2369. }
  2370. }
  2371. }
  2372. return true
  2373. }
  2374. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2375. for _, block := range fn.Blocks {
  2376. for _, ins := range block.Instrs {
  2377. val, ok := ins.(ir.Value)
  2378. if !ok || !isAppend(val) {
  2379. continue
  2380. }
  2381. isUsed := false
  2382. visited := map[ir.Instruction]bool{}
  2383. var walkRefs func(refs []ir.Instruction)
  2384. walkRefs = func(refs []ir.Instruction) {
  2385. loop:
  2386. for _, ref := range refs {
  2387. if visited[ref] {
  2388. continue
  2389. }
  2390. visited[ref] = true
  2391. if _, ok := ref.(*ir.DebugRef); ok {
  2392. continue
  2393. }
  2394. switch ref := ref.(type) {
  2395. case *ir.Phi:
  2396. walkRefs(*ref.Referrers())
  2397. case *ir.Sigma:
  2398. walkRefs(*ref.Referrers())
  2399. case ir.Value:
  2400. if !isAppend(ref) {
  2401. isUsed = true
  2402. } else {
  2403. walkRefs(*ref.Referrers())
  2404. }
  2405. case ir.Instruction:
  2406. isUsed = true
  2407. break loop
  2408. }
  2409. }
  2410. }
  2411. refs := val.Referrers()
  2412. if refs == nil {
  2413. continue
  2414. }
  2415. walkRefs(*refs)
  2416. if isUsed {
  2417. continue
  2418. }
  2419. seen := map[ir.Value]struct{}{}
  2420. if !validateArgument(ins.(*ir.Call).Call.Args[0], seen) {
  2421. continue
  2422. }
  2423. seen2 := map[ir.Instruction]struct{}{}
  2424. for k := range seen {
  2425. // the only values we allow are also instructions, so this type assertion cannot fail
  2426. seen2[k.(ir.Instruction)] = struct{}{}
  2427. }
  2428. seen2[ins] = struct{}{}
  2429. failed := false
  2430. for v := range seen {
  2431. if !validateReferrers(v, seen2) {
  2432. failed = true
  2433. break
  2434. }
  2435. }
  2436. if !failed {
  2437. report.Report(pass, ins, "this result of append is never used, except maybe in other appends")
  2438. }
  2439. }
  2440. }
  2441. }
  2442. return nil, nil
  2443. }
  2444. func CheckConcurrentTesting(pass *analysis.Pass) (interface{}, error) {
  2445. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2446. for _, block := range fn.Blocks {
  2447. for _, ins := range block.Instrs {
  2448. gostmt, ok := ins.(*ir.Go)
  2449. if !ok {
  2450. continue
  2451. }
  2452. var fn *ir.Function
  2453. switch val := gostmt.Call.Value.(type) {
  2454. case *ir.Function:
  2455. fn = val
  2456. case *ir.MakeClosure:
  2457. fn = val.Fn.(*ir.Function)
  2458. default:
  2459. continue
  2460. }
  2461. if fn.Blocks == nil {
  2462. continue
  2463. }
  2464. for _, block := range fn.Blocks {
  2465. for _, ins := range block.Instrs {
  2466. call, ok := ins.(*ir.Call)
  2467. if !ok {
  2468. continue
  2469. }
  2470. if call.Call.IsInvoke() {
  2471. continue
  2472. }
  2473. callee := call.Call.StaticCallee()
  2474. if callee == nil {
  2475. continue
  2476. }
  2477. recv := callee.Signature.Recv()
  2478. if recv == nil {
  2479. continue
  2480. }
  2481. if !typeutil.IsType(recv.Type(), "*testing.common") {
  2482. continue
  2483. }
  2484. fn, ok := call.Call.StaticCallee().Object().(*types.Func)
  2485. if !ok {
  2486. continue
  2487. }
  2488. name := fn.Name()
  2489. switch name {
  2490. case "FailNow", "Fatal", "Fatalf", "SkipNow", "Skip", "Skipf":
  2491. default:
  2492. continue
  2493. }
  2494. // TODO(dh): don't report multiple diagnostics
  2495. // for multiple calls to T.Fatal, but do
  2496. // collect all of them as related information
  2497. report.Report(pass, gostmt, fmt.Sprintf("the goroutine calls T.%s, which must be called in the same goroutine as the test", name),
  2498. report.Related(call, fmt.Sprintf("call to T.%s", name)))
  2499. }
  2500. }
  2501. }
  2502. }
  2503. }
  2504. return nil, nil
  2505. }
  2506. func eachCall(fn *ir.Function, cb func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function)) {
  2507. for _, b := range fn.Blocks {
  2508. for _, instr := range b.Instrs {
  2509. if site, ok := instr.(ir.CallInstruction); ok {
  2510. if g := site.Common().StaticCallee(); g != nil {
  2511. cb(fn, site, g)
  2512. }
  2513. }
  2514. }
  2515. }
  2516. }
  2517. func CheckCyclicFinalizer(pass *analysis.Pass) (interface{}, error) {
  2518. cb := func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
  2519. if callee.RelString(nil) != "runtime.SetFinalizer" {
  2520. return
  2521. }
  2522. arg0 := site.Common().Args[knowledge.Arg("runtime.SetFinalizer.obj")]
  2523. if iface, ok := arg0.(*ir.MakeInterface); ok {
  2524. arg0 = iface.X
  2525. }
  2526. load, ok := arg0.(*ir.Load)
  2527. if !ok {
  2528. return
  2529. }
  2530. v, ok := load.X.(*ir.Alloc)
  2531. if !ok {
  2532. return
  2533. }
  2534. arg1 := site.Common().Args[knowledge.Arg("runtime.SetFinalizer.finalizer")]
  2535. if iface, ok := arg1.(*ir.MakeInterface); ok {
  2536. arg1 = iface.X
  2537. }
  2538. mc, ok := arg1.(*ir.MakeClosure)
  2539. if !ok {
  2540. return
  2541. }
  2542. for _, b := range mc.Bindings {
  2543. if b == v {
  2544. pos := report.DisplayPosition(pass.Fset, mc.Fn.Pos())
  2545. report.Report(pass, site, fmt.Sprintf("the finalizer closes over the object, preventing the finalizer from ever running (at %s)", pos))
  2546. }
  2547. }
  2548. }
  2549. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2550. eachCall(fn, cb)
  2551. }
  2552. return nil, nil
  2553. }
  2554. /*
  2555. func CheckSliceOutOfBounds(pass *analysis.Pass) (interface{}, error) {
  2556. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2557. for _, block := range fn.Blocks {
  2558. for _, ins := range block.Instrs {
  2559. ia, ok := ins.(*ir.IndexAddr)
  2560. if !ok {
  2561. continue
  2562. }
  2563. if _, ok := ia.X.Type().Underlying().(*types.Slice); !ok {
  2564. continue
  2565. }
  2566. sr, ok1 := c.funcDescs.Get(fn).Ranges[ia.X].(vrp.SliceInterval)
  2567. idxr, ok2 := c.funcDescs.Get(fn).Ranges[ia.Index].(vrp.IntInterval)
  2568. if !ok1 || !ok2 || !sr.IsKnown() || !idxr.IsKnown() || sr.Length.Empty() || idxr.Empty() {
  2569. continue
  2570. }
  2571. if idxr.Lower.Cmp(sr.Length.Upper) >= 0 {
  2572. report.Nodef(pass, ia, "index out of bounds")
  2573. }
  2574. }
  2575. }
  2576. }
  2577. return nil, nil
  2578. }
  2579. */
  2580. func CheckDeferLock(pass *analysis.Pass) (interface{}, error) {
  2581. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2582. for _, block := range fn.Blocks {
  2583. instrs := irutil.FilterDebug(block.Instrs)
  2584. if len(instrs) < 2 {
  2585. continue
  2586. }
  2587. for i, ins := range instrs[:len(instrs)-1] {
  2588. call, ok := ins.(*ir.Call)
  2589. if !ok {
  2590. continue
  2591. }
  2592. if !irutil.IsCallToAny(call.Common(), "(*sync.Mutex).Lock", "(*sync.RWMutex).RLock") {
  2593. continue
  2594. }
  2595. nins, ok := instrs[i+1].(*ir.Defer)
  2596. if !ok {
  2597. continue
  2598. }
  2599. if !irutil.IsCallToAny(&nins.Call, "(*sync.Mutex).Lock", "(*sync.RWMutex).RLock") {
  2600. continue
  2601. }
  2602. if call.Common().Args[0] != nins.Call.Args[0] {
  2603. continue
  2604. }
  2605. name := shortCallName(call.Common())
  2606. alt := ""
  2607. switch name {
  2608. case "Lock":
  2609. alt = "Unlock"
  2610. case "RLock":
  2611. alt = "RUnlock"
  2612. }
  2613. report.Report(pass, nins, fmt.Sprintf("deferring %s right after having locked already; did you mean to defer %s?", name, alt))
  2614. }
  2615. }
  2616. }
  2617. return nil, nil
  2618. }
  2619. func CheckNaNComparison(pass *analysis.Pass) (interface{}, error) {
  2620. isNaN := func(v ir.Value) bool {
  2621. call, ok := v.(*ir.Call)
  2622. if !ok {
  2623. return false
  2624. }
  2625. return irutil.IsCallTo(call.Common(), "math.NaN")
  2626. }
  2627. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2628. for _, block := range fn.Blocks {
  2629. for _, ins := range block.Instrs {
  2630. ins, ok := ins.(*ir.BinOp)
  2631. if !ok {
  2632. continue
  2633. }
  2634. if isNaN(irutil.Flatten(ins.X)) || isNaN(irutil.Flatten(ins.Y)) {
  2635. report.Report(pass, ins, "no value is equal to NaN, not even NaN itself")
  2636. }
  2637. }
  2638. }
  2639. }
  2640. return nil, nil
  2641. }
  2642. func CheckInfiniteRecursion(pass *analysis.Pass) (interface{}, error) {
  2643. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2644. eachCall(fn, func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
  2645. if callee != fn {
  2646. return
  2647. }
  2648. if _, ok := site.(*ir.Go); ok {
  2649. // Recursively spawning goroutines doesn't consume
  2650. // stack space infinitely, so don't flag it.
  2651. return
  2652. }
  2653. block := site.Block()
  2654. for _, b := range fn.Blocks {
  2655. if block.Dominates(b) {
  2656. continue
  2657. }
  2658. if len(b.Instrs) == 0 {
  2659. continue
  2660. }
  2661. if _, ok := b.Control().(*ir.Return); ok {
  2662. return
  2663. }
  2664. }
  2665. report.Report(pass, site, "infinite recursive call")
  2666. })
  2667. }
  2668. return nil, nil
  2669. }
  2670. func CheckLeakyTimeTick(pass *analysis.Pass) (interface{}, error) {
  2671. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2672. if code.IsMainLike(pass) || code.IsInTest(pass, fn) {
  2673. continue
  2674. }
  2675. for _, block := range fn.Blocks {
  2676. for _, ins := range block.Instrs {
  2677. call, ok := ins.(*ir.Call)
  2678. if !ok || !irutil.IsCallTo(call.Common(), "time.Tick") {
  2679. continue
  2680. }
  2681. if !irutil.Terminates(call.Parent()) {
  2682. continue
  2683. }
  2684. report.Report(pass, call, "using time.Tick leaks the underlying ticker, consider using it only in endless functions, tests and the main package, and use time.NewTicker here")
  2685. }
  2686. }
  2687. }
  2688. return nil, nil
  2689. }
  2690. var checkDoubleNegationQ = pattern.MustParse(`(UnaryExpr "!" single@(UnaryExpr "!" x))`)
  2691. func CheckDoubleNegation(pass *analysis.Pass) (interface{}, error) {
  2692. fn := func(node ast.Node) {
  2693. if m, ok := code.Match(pass, checkDoubleNegationQ, node); ok {
  2694. report.Report(pass, node, "negating a boolean twice has no effect; is this a typo?", report.Fixes(
  2695. edit.Fix("turn into single negation", edit.ReplaceWithNode(pass.Fset, node, m.State["single"].(ast.Node))),
  2696. edit.Fix("remove double negation", edit.ReplaceWithNode(pass.Fset, node, m.State["x"].(ast.Node)))))
  2697. }
  2698. }
  2699. code.Preorder(pass, fn, (*ast.UnaryExpr)(nil))
  2700. return nil, nil
  2701. }
  2702. func CheckRepeatedIfElse(pass *analysis.Pass) (interface{}, error) {
  2703. seen := map[ast.Node]bool{}
  2704. var collectConds func(ifstmt *ast.IfStmt, conds []ast.Expr) ([]ast.Expr, bool)
  2705. collectConds = func(ifstmt *ast.IfStmt, conds []ast.Expr) ([]ast.Expr, bool) {
  2706. seen[ifstmt] = true
  2707. // Bail if any if-statement has an Init statement or side effects in its condition
  2708. if ifstmt.Init != nil {
  2709. return nil, false
  2710. }
  2711. if code.MayHaveSideEffects(pass, ifstmt.Cond, nil) {
  2712. return nil, false
  2713. }
  2714. conds = append(conds, ifstmt.Cond)
  2715. if elsestmt, ok := ifstmt.Else.(*ast.IfStmt); ok {
  2716. return collectConds(elsestmt, conds)
  2717. }
  2718. return conds, true
  2719. }
  2720. fn := func(node ast.Node) {
  2721. ifstmt := node.(*ast.IfStmt)
  2722. if seen[ifstmt] {
  2723. // this if-statement is part of an if/else-if chain that we've already processed
  2724. return
  2725. }
  2726. if ifstmt.Else == nil {
  2727. // there can be at most one condition
  2728. return
  2729. }
  2730. conds, ok := collectConds(ifstmt, nil)
  2731. if !ok {
  2732. return
  2733. }
  2734. if len(conds) < 2 {
  2735. return
  2736. }
  2737. counts := map[string]int{}
  2738. for _, cond := range conds {
  2739. s := report.Render(pass, cond)
  2740. counts[s]++
  2741. if counts[s] == 2 {
  2742. report.Report(pass, cond, "this condition occurs multiple times in this if/else if chain")
  2743. }
  2744. }
  2745. }
  2746. code.Preorder(pass, fn, (*ast.IfStmt)(nil))
  2747. return nil, nil
  2748. }
  2749. func CheckSillyBitwiseOps(pass *analysis.Pass) (interface{}, error) {
  2750. fn := func(node ast.Node) {
  2751. binop := node.(*ast.BinaryExpr)
  2752. if !typeutil.All(pass.TypesInfo.TypeOf(binop), func(term *typeparams.Term) bool {
  2753. b, ok := term.Type().Underlying().(*types.Basic)
  2754. if !ok {
  2755. return false
  2756. }
  2757. return (b.Info() & types.IsInteger) != 0
  2758. }) {
  2759. return
  2760. }
  2761. switch binop.Op {
  2762. case token.AND, token.OR, token.XOR:
  2763. default:
  2764. // we do not flag shifts because too often, x<<0 is part
  2765. // of a pattern, x<<0, x<<8, x<<16, ...
  2766. return
  2767. }
  2768. if y, ok := binop.Y.(*ast.Ident); ok {
  2769. obj, ok := pass.TypesInfo.ObjectOf(y).(*types.Const)
  2770. if !ok {
  2771. return
  2772. }
  2773. if obj.Pkg() != pass.Pkg {
  2774. // identifier was dot-imported
  2775. return
  2776. }
  2777. if v, _ := constant.Int64Val(obj.Val()); v != 0 {
  2778. return
  2779. }
  2780. path, _ := astutil.PathEnclosingInterval(code.File(pass, obj), obj.Pos(), obj.Pos())
  2781. if len(path) < 2 {
  2782. return
  2783. }
  2784. spec, ok := path[1].(*ast.ValueSpec)
  2785. if !ok {
  2786. return
  2787. }
  2788. if len(spec.Names) != 1 || len(spec.Values) != 1 {
  2789. // TODO(dh): we could support this
  2790. return
  2791. }
  2792. ident, ok := spec.Values[0].(*ast.Ident)
  2793. if !ok {
  2794. return
  2795. }
  2796. if !isIota(pass.TypesInfo.ObjectOf(ident)) {
  2797. return
  2798. }
  2799. switch binop.Op {
  2800. case token.AND:
  2801. report.Report(pass, node,
  2802. fmt.Sprintf("%s always equals 0; %s is defined as iota and has value 0, maybe %s is meant to be 1 << iota?", report.Render(pass, binop), report.Render(pass, binop.Y), report.Render(pass, binop.Y)))
  2803. case token.OR, token.XOR:
  2804. report.Report(pass, node,
  2805. fmt.Sprintf("%s always equals %s; %s is defined as iota and has value 0, maybe %s is meant to be 1 << iota?", report.Render(pass, binop), report.Render(pass, binop.X), report.Render(pass, binop.Y), report.Render(pass, binop.Y)))
  2806. }
  2807. } else if code.IsIntegerLiteral(pass, binop.Y, constant.MakeInt64(0)) {
  2808. switch binop.Op {
  2809. case token.AND:
  2810. report.Report(pass, node, fmt.Sprintf("%s always equals 0", report.Render(pass, binop)))
  2811. case token.OR, token.XOR:
  2812. report.Report(pass, node, fmt.Sprintf("%s always equals %s", report.Render(pass, binop), report.Render(pass, binop.X)))
  2813. }
  2814. }
  2815. }
  2816. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  2817. return nil, nil
  2818. }
  2819. func isIota(obj types.Object) bool {
  2820. if obj.Name() != "iota" {
  2821. return false
  2822. }
  2823. c, ok := obj.(*types.Const)
  2824. if !ok {
  2825. return false
  2826. }
  2827. return c.Pkg() == nil
  2828. }
  2829. func CheckNonOctalFileMode(pass *analysis.Pass) (interface{}, error) {
  2830. fn := func(node ast.Node) {
  2831. call := node.(*ast.CallExpr)
  2832. for _, arg := range call.Args {
  2833. lit, ok := arg.(*ast.BasicLit)
  2834. if !ok {
  2835. continue
  2836. }
  2837. if !typeutil.IsType(pass.TypesInfo.TypeOf(lit), "os.FileMode") &&
  2838. !typeutil.IsType(pass.TypesInfo.TypeOf(lit), "io/fs.FileMode") {
  2839. continue
  2840. }
  2841. if len(lit.Value) == 3 &&
  2842. lit.Value[0] != '0' &&
  2843. lit.Value[0] >= '0' && lit.Value[0] <= '7' &&
  2844. lit.Value[1] >= '0' && lit.Value[1] <= '7' &&
  2845. lit.Value[2] >= '0' && lit.Value[2] <= '7' {
  2846. v, err := strconv.ParseInt(lit.Value, 10, 64)
  2847. if err != nil {
  2848. continue
  2849. }
  2850. report.Report(pass, arg, fmt.Sprintf("file mode '%s' evaluates to %#o; did you mean '0%s'?", lit.Value, v, lit.Value),
  2851. report.Fixes(edit.Fix("fix octal literal", edit.ReplaceWithString(arg, "0"+lit.Value))))
  2852. }
  2853. }
  2854. }
  2855. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  2856. return nil, nil
  2857. }
  2858. func CheckPureFunctions(pass *analysis.Pass) (interface{}, error) {
  2859. pure := pass.ResultOf[facts.Purity].(facts.PurityResult)
  2860. fnLoop:
  2861. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  2862. if code.IsInTest(pass, fn) {
  2863. params := fn.Signature.Params()
  2864. for i := 0; i < params.Len(); i++ {
  2865. param := params.At(i)
  2866. if typeutil.IsType(param.Type(), "*testing.B") {
  2867. // Ignore discarded pure functions in code related
  2868. // to benchmarks. Instead of matching BenchmarkFoo
  2869. // functions, we match any function accepting a
  2870. // *testing.B. Benchmarks sometimes call generic
  2871. // functions for doing the actual work, and
  2872. // checking for the parameter is a lot easier and
  2873. // faster than analyzing call trees.
  2874. continue fnLoop
  2875. }
  2876. }
  2877. }
  2878. for _, b := range fn.Blocks {
  2879. for _, ins := range b.Instrs {
  2880. ins, ok := ins.(*ir.Call)
  2881. if !ok {
  2882. continue
  2883. }
  2884. refs := ins.Referrers()
  2885. if refs == nil || len(irutil.FilterDebug(*refs)) > 0 {
  2886. continue
  2887. }
  2888. callee := ins.Common().StaticCallee()
  2889. if callee == nil {
  2890. continue
  2891. }
  2892. if callee.Object() == nil {
  2893. // TODO(dh): support anonymous functions
  2894. continue
  2895. }
  2896. if _, ok := pure[callee.Object().(*types.Func)]; ok {
  2897. if pass.Pkg.Path() == "fmt_test" && callee.Object().(*types.Func).FullName() == "fmt.Sprintf" {
  2898. // special case for benchmarks in the fmt package
  2899. continue
  2900. }
  2901. report.Report(pass, ins, fmt.Sprintf("%s is a pure function but its return value is ignored", callee.Object().Name()))
  2902. }
  2903. }
  2904. }
  2905. }
  2906. return nil, nil
  2907. }
  2908. func CheckDeprecated(pass *analysis.Pass) (interface{}, error) {
  2909. deprs := pass.ResultOf[facts.Deprecated].(facts.DeprecatedResult)
  2910. // Selectors can appear outside of function literals, e.g. when
  2911. // declaring package level variables.
  2912. isStdlib := func(obj types.Object) bool {
  2913. // Modules with no dot in the first path element are reserved for the standard library and tooling.
  2914. // This is the best we can currently do.
  2915. // Nobody tells us which import paths are part of the standard library.
  2916. //
  2917. // We check the entire path instead of just the first path element, because the standard library doesn't contain paths with any dots, anyway.
  2918. return !strings.Contains(obj.Pkg().Path(), ".")
  2919. }
  2920. var tfn types.Object
  2921. stack := 0
  2922. fn := func(node ast.Node, push bool) bool {
  2923. if !push {
  2924. stack--
  2925. return false
  2926. }
  2927. stack++
  2928. if stack == 1 {
  2929. tfn = nil
  2930. }
  2931. if fn, ok := node.(*ast.FuncDecl); ok {
  2932. tfn = pass.TypesInfo.ObjectOf(fn.Name)
  2933. }
  2934. sel, ok := node.(*ast.SelectorExpr)
  2935. if !ok {
  2936. return true
  2937. }
  2938. obj := pass.TypesInfo.ObjectOf(sel.Sel)
  2939. if obj_, ok := obj.(*types.Func); ok {
  2940. obj = typeparams.OriginMethod(obj_)
  2941. }
  2942. if obj.Pkg() == nil {
  2943. return true
  2944. }
  2945. if pass.Pkg == obj.Pkg() || obj.Pkg().Path()+"_test" == pass.Pkg.Path() {
  2946. // Don't flag stuff in our own package
  2947. return true
  2948. }
  2949. if depr, ok := deprs.Objects[obj]; ok {
  2950. // Note: gopls doesn't correctly run analyzers on
  2951. // dependencies, so we'll never be able to find deprecated
  2952. // objects in imported code. We've experimented with
  2953. // lifting the stdlib handling out of the general check,
  2954. // to at least work for deprecated objects in the stdlib,
  2955. // but we gave up on that, because we wouldn't have access
  2956. // to the deprecation message.
  2957. std, ok := knowledge.StdlibDeprecations[code.SelectorName(pass, sel)]
  2958. if !ok && isStdlib(obj) {
  2959. // Deprecated object in the standard library, but we don't know the details of the deprecation.
  2960. // Don't flag it at all, to avoid flagging an object that was deprecated in 1.N when targeting 1.N-1.
  2961. // See https://staticcheck.io/issues/1108 for the background on this.
  2962. return true
  2963. }
  2964. if ok {
  2965. switch std.AlternativeAvailableSince {
  2966. case knowledge.DeprecatedNeverUse:
  2967. // This should never be used, regardless of the
  2968. // targeted Go version. Examples include insecure
  2969. // cryptography or inherently broken APIs.
  2970. //
  2971. // We always want to flag these.
  2972. case knowledge.DeprecatedUseNoLonger:
  2973. // This should no longer be used. Using it with
  2974. // older Go versions might still make sense.
  2975. if !code.IsGoVersion(pass, std.DeprecatedSince) {
  2976. return true
  2977. }
  2978. default:
  2979. if std.AlternativeAvailableSince < 0 {
  2980. panic(fmt.Sprintf("unhandled case %d", std.AlternativeAvailableSince))
  2981. }
  2982. // Look for the first available alternative, not the first
  2983. // version something was deprecated in. If a function was
  2984. // deprecated in Go 1.6, an alternative has been available
  2985. // already in 1.0, and we're targeting 1.2, it still
  2986. // makes sense to use the alternative from 1.0, to be
  2987. // future-proof.
  2988. if !code.IsGoVersion(pass, std.AlternativeAvailableSince) {
  2989. return true
  2990. }
  2991. }
  2992. }
  2993. if tfn != nil {
  2994. if _, ok := deprs.Objects[tfn]; ok {
  2995. // functions that are deprecated may use deprecated
  2996. // symbols
  2997. return true
  2998. }
  2999. }
  3000. if ok {
  3001. if std.AlternativeAvailableSince == knowledge.DeprecatedNeverUse {
  3002. report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d because it shouldn't be used: %s", report.Render(pass, sel), std.DeprecatedSince, depr.Msg))
  3003. } else if std.AlternativeAvailableSince == std.DeprecatedSince || std.AlternativeAvailableSince == knowledge.DeprecatedUseNoLonger {
  3004. report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d: %s", report.Render(pass, sel), std.DeprecatedSince, depr.Msg))
  3005. } else {
  3006. report.Report(pass, sel, fmt.Sprintf("%s has been deprecated since Go 1.%d and an alternative has been available since Go 1.%d: %s", report.Render(pass, sel), std.DeprecatedSince, std.AlternativeAvailableSince, depr.Msg))
  3007. }
  3008. } else {
  3009. report.Report(pass, sel, fmt.Sprintf("%s is deprecated: %s", report.Render(pass, sel), depr.Msg))
  3010. }
  3011. return true
  3012. }
  3013. return true
  3014. }
  3015. fn2 := func(node ast.Node) {
  3016. spec := node.(*ast.ImportSpec)
  3017. var imp *types.Package
  3018. if spec.Name != nil {
  3019. imp = pass.TypesInfo.ObjectOf(spec.Name).(*types.PkgName).Imported()
  3020. } else {
  3021. imp = pass.TypesInfo.Implicits[spec].(*types.PkgName).Imported()
  3022. }
  3023. p := spec.Path.Value
  3024. path := p[1 : len(p)-1]
  3025. if depr, ok := deprs.Packages[imp]; ok {
  3026. if path == "github.com/golang/protobuf/proto" {
  3027. gen, ok := code.Generator(pass, spec.Path.Pos())
  3028. if ok && gen == facts.ProtocGenGo {
  3029. return
  3030. }
  3031. }
  3032. report.Report(pass, spec, fmt.Sprintf("package %s is deprecated: %s", path, depr.Msg))
  3033. }
  3034. }
  3035. pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes(nil, fn)
  3036. code.Preorder(pass, fn2, (*ast.ImportSpec)(nil))
  3037. return nil, nil
  3038. }
  3039. func callChecker(rules map[string]CallCheck) func(pass *analysis.Pass) (interface{}, error) {
  3040. return func(pass *analysis.Pass) (interface{}, error) {
  3041. return checkCalls(pass, rules)
  3042. }
  3043. }
  3044. func checkCalls(pass *analysis.Pass, rules map[string]CallCheck) (interface{}, error) {
  3045. cb := func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
  3046. obj, ok := callee.Object().(*types.Func)
  3047. if !ok {
  3048. return
  3049. }
  3050. r, ok := rules[typeutil.FuncName(obj)]
  3051. if !ok {
  3052. return
  3053. }
  3054. var args []*Argument
  3055. irargs := site.Common().Args
  3056. if callee.Signature.Recv() != nil {
  3057. irargs = irargs[1:]
  3058. }
  3059. for _, arg := range irargs {
  3060. if iarg, ok := arg.(*ir.MakeInterface); ok {
  3061. arg = iarg.X
  3062. }
  3063. args = append(args, &Argument{Value: Value{arg}})
  3064. }
  3065. call := &Call{
  3066. Pass: pass,
  3067. Instr: site,
  3068. Args: args,
  3069. Parent: site.Parent(),
  3070. }
  3071. r(call)
  3072. var astcall *ast.CallExpr
  3073. switch source := site.Source().(type) {
  3074. case *ast.CallExpr:
  3075. astcall = source
  3076. case *ast.DeferStmt:
  3077. astcall = source.Call
  3078. case *ast.GoStmt:
  3079. astcall = source.Call
  3080. case nil:
  3081. // TODO(dh): I am not sure this can actually happen. If it
  3082. // can't, we should remove this case, and also stop
  3083. // checking for astcall == nil in the code that follows.
  3084. default:
  3085. panic(fmt.Sprintf("unhandled case %T", source))
  3086. }
  3087. for idx, arg := range call.Args {
  3088. for _, e := range arg.invalids {
  3089. if astcall != nil {
  3090. if idx < len(astcall.Args) {
  3091. report.Report(pass, astcall.Args[idx], e)
  3092. } else {
  3093. // this is an instance of fn1(fn2()) where fn2
  3094. // returns multiple values. Report the error
  3095. // at the next-best position that we have, the
  3096. // first argument. An example of a check that
  3097. // triggers this is checkEncodingBinaryRules.
  3098. report.Report(pass, astcall.Args[0], e)
  3099. }
  3100. } else {
  3101. report.Report(pass, site, e)
  3102. }
  3103. }
  3104. }
  3105. for _, e := range call.invalids {
  3106. report.Report(pass, call.Instr, e)
  3107. }
  3108. }
  3109. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3110. eachCall(fn, cb)
  3111. }
  3112. return nil, nil
  3113. }
  3114. func shortCallName(call *ir.CallCommon) string {
  3115. if call.IsInvoke() {
  3116. return ""
  3117. }
  3118. switch v := call.Value.(type) {
  3119. case *ir.Function:
  3120. fn, ok := v.Object().(*types.Func)
  3121. if !ok {
  3122. return ""
  3123. }
  3124. return fn.Name()
  3125. case *ir.Builtin:
  3126. return v.Name()
  3127. }
  3128. return ""
  3129. }
  3130. func CheckWriterBufferModified(pass *analysis.Pass) (interface{}, error) {
  3131. // TODO(dh): this might be a good candidate for taint analysis.
  3132. // Taint the argument as MUST_NOT_MODIFY, then propagate that
  3133. // through functions like bytes.Split
  3134. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3135. sig := fn.Signature
  3136. if fn.Name() != "Write" || sig.Recv() == nil || sig.Params().Len() != 1 || sig.Results().Len() != 2 {
  3137. continue
  3138. }
  3139. tArg, ok := sig.Params().At(0).Type().(*types.Slice)
  3140. if !ok {
  3141. continue
  3142. }
  3143. if basic, ok := tArg.Elem().(*types.Basic); !ok || basic.Kind() != types.Byte {
  3144. continue
  3145. }
  3146. if basic, ok := sig.Results().At(0).Type().(*types.Basic); !ok || basic.Kind() != types.Int {
  3147. continue
  3148. }
  3149. if named, ok := sig.Results().At(1).Type().(*types.Named); !ok || !typeutil.IsType(named, "error") {
  3150. continue
  3151. }
  3152. for _, block := range fn.Blocks {
  3153. for _, ins := range block.Instrs {
  3154. switch ins := ins.(type) {
  3155. case *ir.Store:
  3156. addr, ok := ins.Addr.(*ir.IndexAddr)
  3157. if !ok {
  3158. continue
  3159. }
  3160. if addr.X != fn.Params[1] {
  3161. continue
  3162. }
  3163. report.Report(pass, ins, "io.Writer.Write must not modify the provided buffer, not even temporarily")
  3164. case *ir.Call:
  3165. if !irutil.IsCallTo(ins.Common(), "append") {
  3166. continue
  3167. }
  3168. if ins.Common().Args[0] != fn.Params[1] {
  3169. continue
  3170. }
  3171. report.Report(pass, ins, "io.Writer.Write must not modify the provided buffer, not even temporarily")
  3172. }
  3173. }
  3174. }
  3175. }
  3176. return nil, nil
  3177. }
  3178. func loopedRegexp(name string) CallCheck {
  3179. return func(call *Call) {
  3180. if extractConst(call.Args[0].Value.Value) == nil {
  3181. return
  3182. }
  3183. if !isInLoop(call.Instr.Block()) {
  3184. return
  3185. }
  3186. call.Invalid(fmt.Sprintf("calling %s in a loop has poor performance, consider using regexp.Compile", name))
  3187. }
  3188. }
  3189. func CheckEmptyBranch(pass *analysis.Pass) (interface{}, error) {
  3190. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3191. if fn.Source() == nil {
  3192. continue
  3193. }
  3194. if irutil.IsExample(fn) {
  3195. continue
  3196. }
  3197. cb := func(node ast.Node) bool {
  3198. ifstmt, ok := node.(*ast.IfStmt)
  3199. if !ok {
  3200. return true
  3201. }
  3202. if ifstmt.Else != nil {
  3203. b, ok := ifstmt.Else.(*ast.BlockStmt)
  3204. if !ok || len(b.List) != 0 {
  3205. return true
  3206. }
  3207. report.Report(pass, ifstmt.Else, "empty branch", report.FilterGenerated(), report.ShortRange())
  3208. }
  3209. if len(ifstmt.Body.List) != 0 {
  3210. return true
  3211. }
  3212. report.Report(pass, ifstmt, "empty branch", report.FilterGenerated(), report.ShortRange())
  3213. return true
  3214. }
  3215. if source := fn.Source(); source != nil {
  3216. ast.Inspect(source, cb)
  3217. }
  3218. }
  3219. return nil, nil
  3220. }
  3221. func CheckMapBytesKey(pass *analysis.Pass) (interface{}, error) {
  3222. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3223. for _, b := range fn.Blocks {
  3224. insLoop:
  3225. for _, ins := range b.Instrs {
  3226. // find []byte -> string conversions
  3227. conv, ok := ins.(*ir.Convert)
  3228. if !ok || conv.Type() != types.Universe.Lookup("string").Type() {
  3229. continue
  3230. }
  3231. tset := typeutil.NewTypeSet(conv.X.Type())
  3232. // If at least one of the types is []byte, then it's more efficient to inline the conversion
  3233. if !tset.Any(func(term *typeparams.Term) bool {
  3234. s, ok := term.Type().Underlying().(*types.Slice)
  3235. return ok && s.Elem().Underlying() == types.Universe.Lookup("byte").Type()
  3236. }) {
  3237. continue
  3238. }
  3239. refs := conv.Referrers()
  3240. // need at least two (DebugRef) references: the
  3241. // conversion and the *ast.Ident
  3242. if refs == nil || len(*refs) < 2 {
  3243. continue
  3244. }
  3245. ident := false
  3246. // skip first reference, that's the conversion itself
  3247. for _, ref := range (*refs)[1:] {
  3248. switch ref := ref.(type) {
  3249. case *ir.DebugRef:
  3250. if _, ok := ref.Expr.(*ast.Ident); !ok {
  3251. // the string seems to be used somewhere
  3252. // unexpected; the default branch should
  3253. // catch this already, but be safe
  3254. continue insLoop
  3255. } else {
  3256. ident = true
  3257. }
  3258. case *ir.MapLookup:
  3259. default:
  3260. // the string is used somewhere else than a
  3261. // map lookup
  3262. continue insLoop
  3263. }
  3264. }
  3265. // the result of the conversion wasn't assigned to an
  3266. // identifier
  3267. if !ident {
  3268. continue
  3269. }
  3270. report.Report(pass, conv, "m[string(key)] would be more efficient than k := string(key); m[k]")
  3271. }
  3272. }
  3273. }
  3274. return nil, nil
  3275. }
  3276. func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
  3277. return sharedcheck.CheckRangeStringRunes(pass)
  3278. }
  3279. func CheckSelfAssignment(pass *analysis.Pass) (interface{}, error) {
  3280. pure := pass.ResultOf[facts.Purity].(facts.PurityResult)
  3281. fn := func(node ast.Node) {
  3282. assign := node.(*ast.AssignStmt)
  3283. if assign.Tok != token.ASSIGN || len(assign.Lhs) != len(assign.Rhs) {
  3284. return
  3285. }
  3286. for i, lhs := range assign.Lhs {
  3287. rhs := assign.Rhs[i]
  3288. if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
  3289. continue
  3290. }
  3291. if code.MayHaveSideEffects(pass, lhs, pure) || code.MayHaveSideEffects(pass, rhs, pure) {
  3292. continue
  3293. }
  3294. rlh := report.Render(pass, lhs)
  3295. rrh := report.Render(pass, rhs)
  3296. if rlh == rrh {
  3297. report.Report(pass, assign, fmt.Sprintf("self-assignment of %s to %s", rrh, rlh), report.FilterGenerated())
  3298. }
  3299. }
  3300. }
  3301. code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
  3302. return nil, nil
  3303. }
  3304. func buildTagsIdentical(s1, s2 []string) bool {
  3305. if len(s1) != len(s2) {
  3306. return false
  3307. }
  3308. s1s := make([]string, len(s1))
  3309. copy(s1s, s1)
  3310. sort.Strings(s1s)
  3311. s2s := make([]string, len(s2))
  3312. copy(s2s, s2)
  3313. sort.Strings(s2s)
  3314. for i, s := range s1s {
  3315. if s != s2s[i] {
  3316. return false
  3317. }
  3318. }
  3319. return true
  3320. }
  3321. func CheckDuplicateBuildConstraints(pass *analysis.Pass) (interface{}, error) {
  3322. for _, f := range pass.Files {
  3323. constraints := buildTags(f)
  3324. for i, constraint1 := range constraints {
  3325. for j, constraint2 := range constraints {
  3326. if i >= j {
  3327. continue
  3328. }
  3329. if buildTagsIdentical(constraint1, constraint2) {
  3330. msg := fmt.Sprintf("identical build constraints %q and %q",
  3331. strings.Join(constraint1, " "),
  3332. strings.Join(constraint2, " "))
  3333. report.Report(pass, f, msg, report.FilterGenerated(), report.ShortRange())
  3334. }
  3335. }
  3336. }
  3337. }
  3338. return nil, nil
  3339. }
  3340. func CheckSillyRegexp(pass *analysis.Pass) (interface{}, error) {
  3341. // We could use the rule checking engine for this, but the
  3342. // arguments aren't really invalid.
  3343. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3344. for _, b := range fn.Blocks {
  3345. for _, ins := range b.Instrs {
  3346. call, ok := ins.(*ir.Call)
  3347. if !ok {
  3348. continue
  3349. }
  3350. if !irutil.IsCallToAny(call.Common(), "regexp.MustCompile", "regexp.Compile", "regexp.Match", "regexp.MatchReader", "regexp.MatchString") {
  3351. continue
  3352. }
  3353. c, ok := call.Common().Args[0].(*ir.Const)
  3354. if !ok {
  3355. continue
  3356. }
  3357. s := constant.StringVal(c.Value)
  3358. re, err := syntax.Parse(s, 0)
  3359. if err != nil {
  3360. continue
  3361. }
  3362. if re.Op != syntax.OpLiteral && re.Op != syntax.OpEmptyMatch {
  3363. continue
  3364. }
  3365. report.Report(pass, call, "regular expression does not contain any meta characters")
  3366. }
  3367. }
  3368. }
  3369. return nil, nil
  3370. }
  3371. func CheckMissingEnumTypesInDeclaration(pass *analysis.Pass) (interface{}, error) {
  3372. convertibleTo := func(V, T types.Type) bool {
  3373. if types.ConvertibleTo(V, T) {
  3374. return true
  3375. }
  3376. // Go <1.16 returns false for untyped string to string conversion
  3377. if V, ok := V.(*types.Basic); ok && V.Kind() == types.UntypedString {
  3378. if T, ok := T.Underlying().(*types.Basic); ok && T.Kind() == types.String {
  3379. return true
  3380. }
  3381. }
  3382. return false
  3383. }
  3384. fn := func(node ast.Node) {
  3385. decl := node.(*ast.GenDecl)
  3386. if !decl.Lparen.IsValid() {
  3387. return
  3388. }
  3389. if decl.Tok != token.CONST {
  3390. return
  3391. }
  3392. groups := astutil.GroupSpecs(pass.Fset, decl.Specs)
  3393. groupLoop:
  3394. for _, group := range groups {
  3395. if len(group) < 2 {
  3396. continue
  3397. }
  3398. if group[0].(*ast.ValueSpec).Type == nil {
  3399. // first constant doesn't have a type
  3400. continue groupLoop
  3401. }
  3402. firstType := pass.TypesInfo.TypeOf(group[0].(*ast.ValueSpec).Values[0])
  3403. for i, spec := range group {
  3404. spec := spec.(*ast.ValueSpec)
  3405. if i > 0 && spec.Type != nil {
  3406. continue groupLoop
  3407. }
  3408. if len(spec.Names) != 1 || len(spec.Values) != 1 {
  3409. continue groupLoop
  3410. }
  3411. if !convertibleTo(pass.TypesInfo.TypeOf(spec.Values[0]), firstType) {
  3412. continue groupLoop
  3413. }
  3414. switch v := spec.Values[0].(type) {
  3415. case *ast.BasicLit:
  3416. case *ast.UnaryExpr:
  3417. if _, ok := v.X.(*ast.BasicLit); !ok {
  3418. continue groupLoop
  3419. }
  3420. default:
  3421. // if it's not a literal it might be typed, such as
  3422. // time.Microsecond = 1000 * Nanosecond
  3423. continue groupLoop
  3424. }
  3425. }
  3426. var edits []analysis.TextEdit
  3427. typ := group[0].(*ast.ValueSpec).Type
  3428. for _, spec := range group[1:] {
  3429. nspec := *spec.(*ast.ValueSpec)
  3430. nspec.Type = typ
  3431. // The position of `spec` node excludes comments (if any).
  3432. // However, on generating the source back from the node, the comments are included. Setting `Comment` to nil ensures deduplication of comments.
  3433. nspec.Comment = nil
  3434. edits = append(edits, edit.ReplaceWithNode(pass.Fset, spec, &nspec))
  3435. }
  3436. report.Report(pass, group[0], "only the first constant in this group has an explicit type", report.Fixes(edit.Fix("add type to all constants in group", edits...)))
  3437. }
  3438. }
  3439. code.Preorder(pass, fn, (*ast.GenDecl)(nil))
  3440. return nil, nil
  3441. }
  3442. func CheckTimerResetReturnValue(pass *analysis.Pass) (interface{}, error) {
  3443. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3444. for _, block := range fn.Blocks {
  3445. for _, ins := range block.Instrs {
  3446. call, ok := ins.(*ir.Call)
  3447. if !ok {
  3448. continue
  3449. }
  3450. if !irutil.IsCallTo(call.Common(), "(*time.Timer).Reset") {
  3451. continue
  3452. }
  3453. refs := call.Referrers()
  3454. if refs == nil {
  3455. continue
  3456. }
  3457. for _, ref := range irutil.FilterDebug(*refs) {
  3458. ifstmt, ok := ref.(*ir.If)
  3459. if !ok {
  3460. continue
  3461. }
  3462. found := false
  3463. for _, succ := range ifstmt.Block().Succs {
  3464. if len(succ.Preds) != 1 {
  3465. // Merge point, not a branch in the
  3466. // syntactical sense.
  3467. // FIXME(dh): this is broken for if
  3468. // statements a la "if x || y"
  3469. continue
  3470. }
  3471. irutil.Walk(succ, func(b *ir.BasicBlock) bool {
  3472. if !succ.Dominates(b) {
  3473. // We've reached the end of the branch
  3474. return false
  3475. }
  3476. for _, ins := range b.Instrs {
  3477. // TODO(dh): we should check that
  3478. // we're receiving from the channel of
  3479. // a time.Timer to further reduce
  3480. // false positives. Not a key
  3481. // priority, considering the rarity of
  3482. // Reset and the tiny likeliness of a
  3483. // false positive
  3484. if ins, ok := ins.(*ir.Recv); ok && typeutil.IsType(ins.Chan.Type(), "<-chan time.Time") {
  3485. found = true
  3486. return false
  3487. }
  3488. }
  3489. return true
  3490. })
  3491. }
  3492. if found {
  3493. report.Report(pass, call, "it is not possible to use Reset's return value correctly, as there is a race condition between draining the channel and the new timer expiring")
  3494. }
  3495. }
  3496. }
  3497. }
  3498. }
  3499. return nil, nil
  3500. }
  3501. var (
  3502. checkToLowerToUpperComparisonQ = pattern.MustParse(`
  3503. (BinaryExpr
  3504. (CallExpr fun@(Function (Or "strings.ToLower" "strings.ToUpper")) [a])
  3505. tok@(Or "==" "!=")
  3506. (CallExpr fun [b]))`)
  3507. checkToLowerToUpperComparisonR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "strings") (Ident "EqualFold")) [a b])`)
  3508. )
  3509. func CheckToLowerToUpperComparison(pass *analysis.Pass) (interface{}, error) {
  3510. fn := func(node ast.Node) {
  3511. m, ok := code.Match(pass, checkToLowerToUpperComparisonQ, node)
  3512. if !ok {
  3513. return
  3514. }
  3515. rn := pattern.NodeToAST(checkToLowerToUpperComparisonR.Root, m.State).(ast.Expr)
  3516. if m.State["tok"].(token.Token) == token.NEQ {
  3517. rn = &ast.UnaryExpr{
  3518. Op: token.NOT,
  3519. X: rn,
  3520. }
  3521. }
  3522. report.Report(pass, node, "should use strings.EqualFold instead", report.Fixes(edit.Fix("replace with strings.EqualFold", edit.ReplaceWithNode(pass.Fset, node, rn))))
  3523. }
  3524. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  3525. return nil, nil
  3526. }
  3527. func CheckUnreachableTypeCases(pass *analysis.Pass) (interface{}, error) {
  3528. // Check if T subsumes V in a type switch. T subsumes V if T is an interface and T's method set is a subset of V's method set.
  3529. subsumes := func(T, V types.Type) bool {
  3530. if typeparams.IsTypeParam(T) {
  3531. return false
  3532. }
  3533. tIface, ok := T.Underlying().(*types.Interface)
  3534. if !ok {
  3535. return false
  3536. }
  3537. return types.Implements(V, tIface)
  3538. }
  3539. subsumesAny := func(Ts, Vs []types.Type) (types.Type, types.Type, bool) {
  3540. for _, T := range Ts {
  3541. for _, V := range Vs {
  3542. if subsumes(T, V) {
  3543. return T, V, true
  3544. }
  3545. }
  3546. }
  3547. return nil, nil, false
  3548. }
  3549. fn := func(node ast.Node) {
  3550. tsStmt := node.(*ast.TypeSwitchStmt)
  3551. type ccAndTypes struct {
  3552. cc *ast.CaseClause
  3553. types []types.Type
  3554. }
  3555. // All asserted types in the order of case clauses.
  3556. ccs := make([]ccAndTypes, 0, len(tsStmt.Body.List))
  3557. for _, stmt := range tsStmt.Body.List {
  3558. cc, _ := stmt.(*ast.CaseClause)
  3559. // Exclude the 'default' case.
  3560. if len(cc.List) == 0 {
  3561. continue
  3562. }
  3563. Ts := make([]types.Type, 0, len(cc.List))
  3564. for _, expr := range cc.List {
  3565. // Exclude the 'nil' value from any 'case' statement (it is always reachable).
  3566. if typ := pass.TypesInfo.TypeOf(expr); typ != types.Typ[types.UntypedNil] {
  3567. Ts = append(Ts, typ)
  3568. }
  3569. }
  3570. ccs = append(ccs, ccAndTypes{cc: cc, types: Ts})
  3571. }
  3572. if len(ccs) <= 1 {
  3573. // Zero or one case clauses, nothing to check.
  3574. return
  3575. }
  3576. // Check if case clauses following cc have types that are subsumed by cc.
  3577. for i, cc := range ccs[:len(ccs)-1] {
  3578. for _, next := range ccs[i+1:] {
  3579. if T, V, yes := subsumesAny(cc.types, next.types); yes {
  3580. report.Report(pass, next.cc, fmt.Sprintf("unreachable case clause: %s will always match before %s", T.String(), V.String()),
  3581. report.ShortRange())
  3582. }
  3583. }
  3584. }
  3585. }
  3586. code.Preorder(pass, fn, (*ast.TypeSwitchStmt)(nil))
  3587. return nil, nil
  3588. }
  3589. var checkSingleArgAppendQ = pattern.MustParse(`(CallExpr (Builtin "append") [_])`)
  3590. func CheckSingleArgAppend(pass *analysis.Pass) (interface{}, error) {
  3591. fn := func(node ast.Node) {
  3592. _, ok := code.Match(pass, checkSingleArgAppendQ, node)
  3593. if !ok {
  3594. return
  3595. }
  3596. report.Report(pass, node, "x = append(y) is equivalent to x = y", report.FilterGenerated())
  3597. }
  3598. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  3599. return nil, nil
  3600. }
  3601. func CheckStructTags(pass *analysis.Pass) (interface{}, error) {
  3602. importsGoFlags := false
  3603. // we use the AST instead of (*types.Package).Imports to work
  3604. // around vendored packages in GOPATH mode. A vendored package's
  3605. // path will include the vendoring subtree as a prefix.
  3606. for _, f := range pass.Files {
  3607. for _, imp := range f.Imports {
  3608. v := imp.Path.Value
  3609. if v[1:len(v)-1] == "github.com/jessevdk/go-flags" {
  3610. importsGoFlags = true
  3611. break
  3612. }
  3613. }
  3614. }
  3615. fn := func(node ast.Node) {
  3616. structNode := node.(*ast.StructType)
  3617. T := pass.TypesInfo.Types[structNode].Type.(*types.Struct)
  3618. rt := fakereflect.TypeAndCanAddr{
  3619. Type: T,
  3620. }
  3621. for i, field := range structNode.Fields.List {
  3622. if field.Tag == nil {
  3623. continue
  3624. }
  3625. tags, err := parseStructTag(field.Tag.Value[1 : len(field.Tag.Value)-1])
  3626. if err != nil {
  3627. report.Report(pass, field.Tag, fmt.Sprintf("unparseable struct tag: %s", err))
  3628. continue
  3629. }
  3630. for k, v := range tags {
  3631. if len(v) > 1 {
  3632. isGoFlagsTag := importsGoFlags &&
  3633. (k == "choice" || k == "optional-value" || k == "default")
  3634. if !isGoFlagsTag {
  3635. report.Report(pass, field.Tag, fmt.Sprintf("duplicate struct tag %q", k))
  3636. }
  3637. }
  3638. switch k {
  3639. case "json":
  3640. checkJSONTag(pass, field, v[0])
  3641. case "xml":
  3642. if _, err := fakexml.StructFieldInfo(rt.Field(i)); err != nil {
  3643. report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: %s", err))
  3644. }
  3645. checkXMLTag(pass, field, v[0])
  3646. }
  3647. }
  3648. }
  3649. }
  3650. code.Preorder(pass, fn, (*ast.StructType)(nil))
  3651. return nil, nil
  3652. }
  3653. func checkJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
  3654. if pass.Pkg.Path() == "encoding/json" || pass.Pkg.Path() == "encoding/json_test" {
  3655. // don't flag malformed JSON tags in the encoding/json
  3656. // package; it knows what it is doing, and it is testing
  3657. // itself.
  3658. return
  3659. }
  3660. //lint:ignore SA9003 TODO(dh): should we flag empty tags?
  3661. if len(tag) == 0 {
  3662. }
  3663. fields := strings.Split(tag, ",")
  3664. for _, r := range fields[0] {
  3665. if !unicode.IsLetter(r) && !unicode.IsDigit(r) && !strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", r) {
  3666. report.Report(pass, field.Tag, fmt.Sprintf("invalid JSON field name %q", fields[0]))
  3667. }
  3668. }
  3669. var co, cs, ci int
  3670. for _, s := range fields[1:] {
  3671. switch s {
  3672. case "omitempty":
  3673. co++
  3674. case "":
  3675. // allow stuff like "-,"
  3676. case "string":
  3677. cs++
  3678. // only for string, floating point, integer and bool
  3679. tset := typeutil.NewTypeSet(pass.TypesInfo.TypeOf(field.Type))
  3680. if len(tset.Terms) == 0 {
  3681. // TODO(dh): improve message, call out the use of type parameters
  3682. report.Report(pass, field.Tag, "the JSON string option only applies to fields of type string, floating point, integer or bool, or pointers to those")
  3683. continue
  3684. }
  3685. for _, term := range tset.Terms {
  3686. T := typeutil.Dereference(term.Type().Underlying())
  3687. for _, term2 := range typeutil.NewTypeSet(T).Terms {
  3688. basic, ok := term2.Type().Underlying().(*types.Basic)
  3689. if !ok || (basic.Info()&(types.IsBoolean|types.IsInteger|types.IsFloat|types.IsString)) == 0 {
  3690. // TODO(dh): improve message, show how we arrived at the type
  3691. report.Report(pass, field.Tag, "the JSON string option only applies to fields of type string, floating point, integer or bool, or pointers to those")
  3692. }
  3693. }
  3694. }
  3695. case "inline":
  3696. ci++
  3697. default:
  3698. report.Report(pass, field.Tag, fmt.Sprintf("unknown JSON option %q", s))
  3699. }
  3700. }
  3701. if co > 1 {
  3702. report.Report(pass, field.Tag, `duplicate JSON option "omitempty"`)
  3703. }
  3704. if cs > 1 {
  3705. report.Report(pass, field.Tag, `duplicate JSON option "string"`)
  3706. }
  3707. if ci > 1 {
  3708. report.Report(pass, field.Tag, `duplicate JSON option "inline"`)
  3709. }
  3710. }
  3711. func checkXMLTag(pass *analysis.Pass, field *ast.Field, tag string) {
  3712. //lint:ignore SA9003 TODO(dh): should we flag empty tags?
  3713. if len(tag) == 0 {
  3714. }
  3715. fields := strings.Split(tag, ",")
  3716. counts := map[string]int{}
  3717. for _, s := range fields[1:] {
  3718. switch s {
  3719. case "attr", "chardata", "cdata", "innerxml", "comment":
  3720. counts[s]++
  3721. case "omitempty", "any":
  3722. counts[s]++
  3723. case "":
  3724. default:
  3725. report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: unknown option %q", s))
  3726. }
  3727. }
  3728. for k, v := range counts {
  3729. if v > 1 {
  3730. report.Report(pass, field.Tag, fmt.Sprintf("invalid XML tag: duplicate option %q", k))
  3731. }
  3732. }
  3733. }
  3734. func CheckImpossibleTypeAssertion(pass *analysis.Pass) (interface{}, error) {
  3735. type entry struct {
  3736. l, r *types.Func
  3737. }
  3738. msc := &pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg.Prog.MethodSets
  3739. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3740. for _, b := range fn.Blocks {
  3741. for _, instr := range b.Instrs {
  3742. assert, ok := instr.(*ir.TypeAssert)
  3743. if !ok {
  3744. continue
  3745. }
  3746. var wrong []entry
  3747. left := assert.X.Type()
  3748. right := assert.AssertedType
  3749. righti, ok := right.Underlying().(*types.Interface)
  3750. if !ok {
  3751. // We only care about interface->interface
  3752. // assertions. The Go compiler already catches
  3753. // impossible interface->concrete assertions.
  3754. continue
  3755. }
  3756. ms := msc.MethodSet(left)
  3757. for i := 0; i < righti.NumMethods(); i++ {
  3758. mr := righti.Method(i)
  3759. sel := ms.Lookup(mr.Pkg(), mr.Name())
  3760. if sel == nil {
  3761. continue
  3762. }
  3763. ml := sel.Obj().(*types.Func)
  3764. if types.AssignableTo(ml.Type(), mr.Type()) {
  3765. continue
  3766. }
  3767. wrong = append(wrong, entry{ml, mr})
  3768. }
  3769. if len(wrong) != 0 {
  3770. s := fmt.Sprintf("impossible type assertion; %s and %s contradict each other:",
  3771. types.TypeString(left, types.RelativeTo(pass.Pkg)),
  3772. types.TypeString(right, types.RelativeTo(pass.Pkg)))
  3773. for _, e := range wrong {
  3774. s += fmt.Sprintf("\n\twrong type for %s method", e.l.Name())
  3775. s += fmt.Sprintf("\n\t\thave %s", e.l.Type())
  3776. s += fmt.Sprintf("\n\t\twant %s", e.r.Type())
  3777. }
  3778. report.Report(pass, assert, s)
  3779. }
  3780. }
  3781. }
  3782. }
  3783. return nil, nil
  3784. }
  3785. func checkWithValueKey(call *Call) {
  3786. arg := call.Args[1]
  3787. T := arg.Value.Value.Type()
  3788. if T, ok := T.(*types.Basic); ok {
  3789. arg.Invalid(
  3790. fmt.Sprintf("should not use built-in type %s as key for value; define your own type to avoid collisions", T))
  3791. }
  3792. if !types.Comparable(T) {
  3793. arg.Invalid(fmt.Sprintf("keys used with context.WithValue must be comparable, but type %s is not comparable", T))
  3794. }
  3795. }
  3796. func CheckMaybeNil(pass *analysis.Pass) (interface{}, error) {
  3797. // This is an extremely trivial check that doesn't try to reason
  3798. // about control flow. That is, phis and sigmas do not propagate
  3799. // any information. As such, we can flag this:
  3800. //
  3801. // _ = *x
  3802. // if x == nil { return }
  3803. //
  3804. // but we cannot flag this:
  3805. //
  3806. // if x == nil { println(x) }
  3807. // _ = *x
  3808. //
  3809. // but we can flag this, because the if's body doesn't use x:
  3810. //
  3811. // if x == nil { println("this is bad") }
  3812. // _ = *x
  3813. //
  3814. // nor many other variations of conditional uses of or assignments to x.
  3815. //
  3816. // However, even this trivial implementation finds plenty of
  3817. // real-world bugs, such as dereference before nil pointer check,
  3818. // or using t.Error instead of t.Fatal when encountering nil
  3819. // pointers.
  3820. //
  3821. // On the flip side, our naive implementation avoids false positives in branches, such as
  3822. //
  3823. // if x != nil { _ = *x }
  3824. //
  3825. // due to the same lack of propagating information through sigma
  3826. // nodes. x inside the branch will be independent of the x in the
  3827. // nil pointer check.
  3828. //
  3829. //
  3830. // We could implement a more powerful check, but then we'd be
  3831. // getting false positives instead of false negatives because
  3832. // we're incapable of deducing relationships between variables.
  3833. // For example, a function might return a pointer and an error,
  3834. // and the error being nil guarantees that the pointer is not nil.
  3835. // Depending on the surrounding code, the pointer may still end up
  3836. // being checked against nil in one place, and guarded by a check
  3837. // on the error in another, which would lead to us marking some
  3838. // loads as unsafe.
  3839. //
  3840. // Unfortunately, simply hard-coding the relationship between
  3841. // return values wouldn't eliminate all false positives, either.
  3842. // Many other more subtle relationships exist. An abridged example
  3843. // from real code:
  3844. //
  3845. // if a == nil && b == nil { return }
  3846. // c := fn(a)
  3847. // if c != "" { _ = *a }
  3848. //
  3849. // where `fn` is guaranteed to return a non-empty string if a
  3850. // isn't nil.
  3851. //
  3852. // We choose to err on the side of false negatives.
  3853. isNilConst := func(v ir.Value) bool {
  3854. if typeutil.IsPointerLike(v.Type()) {
  3855. if k, ok := v.(*ir.Const); ok {
  3856. return k.IsNil()
  3857. }
  3858. }
  3859. return false
  3860. }
  3861. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3862. maybeNil := map[ir.Value]ir.Instruction{}
  3863. for _, b := range fn.Blocks {
  3864. for _, instr := range b.Instrs {
  3865. // Originally we looked at all ir.BinOp, but that would lead to calls like 'assert(x != nil)' causing false positives.
  3866. // Restrict ourselves to actual if statements, as these are more likely to affect control flow in a way we can observe.
  3867. if instr, ok := instr.(*ir.If); ok {
  3868. if cond, ok := instr.Cond.(*ir.BinOp); ok {
  3869. var ptr ir.Value
  3870. if isNilConst(cond.X) {
  3871. ptr = cond.Y
  3872. } else if isNilConst(cond.Y) {
  3873. ptr = cond.X
  3874. }
  3875. maybeNil[ptr] = cond
  3876. }
  3877. }
  3878. }
  3879. }
  3880. for _, b := range fn.Blocks {
  3881. for _, instr := range b.Instrs {
  3882. var ptr ir.Value
  3883. switch instr := instr.(type) {
  3884. case *ir.Load:
  3885. ptr = instr.X
  3886. case *ir.Store:
  3887. ptr = instr.Addr
  3888. case *ir.IndexAddr:
  3889. ptr = instr.X
  3890. if typeutil.All(ptr.Type(), func(term *typeparams.Term) bool {
  3891. if _, ok := term.Type().Underlying().(*types.Slice); ok {
  3892. return true
  3893. }
  3894. return false
  3895. }) {
  3896. // indexing a nil slice does not cause a nil pointer panic
  3897. //
  3898. // Note: This also works around the bad lowering of range loops over slices
  3899. // (https://github.com/dominikh/go-tools/issues/1053)
  3900. continue
  3901. }
  3902. case *ir.FieldAddr:
  3903. ptr = instr.X
  3904. }
  3905. if ptr != nil {
  3906. switch ptr.(type) {
  3907. case *ir.Alloc, *ir.FieldAddr, *ir.IndexAddr:
  3908. // these cannot be nil
  3909. continue
  3910. }
  3911. if r, ok := maybeNil[ptr]; ok {
  3912. report.Report(pass, instr, "possible nil pointer dereference",
  3913. report.Related(r, "this check suggests that the pointer can be nil"))
  3914. }
  3915. }
  3916. }
  3917. }
  3918. }
  3919. return nil, nil
  3920. }
  3921. var checkAddressIsNilQ = pattern.MustParse(
  3922. `(BinaryExpr
  3923. (UnaryExpr "&" _)
  3924. (Or "==" "!=")
  3925. (Builtin "nil"))`)
  3926. func CheckAddressIsNil(pass *analysis.Pass) (interface{}, error) {
  3927. fn := func(node ast.Node) {
  3928. _, ok := code.Match(pass, checkAddressIsNilQ, node)
  3929. if !ok {
  3930. return
  3931. }
  3932. report.Report(pass, node, "the address of a variable cannot be nil")
  3933. }
  3934. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  3935. return nil, nil
  3936. }
  3937. var (
  3938. checkFixedLengthTypeShiftQ = pattern.MustParse(`
  3939. (Or
  3940. (AssignStmt _ (Or ">>=" "<<=") _)
  3941. (BinaryExpr _ (Or ">>" "<<") _))
  3942. `)
  3943. )
  3944. func CheckStaticBitShift(pass *analysis.Pass) (interface{}, error) {
  3945. isDubiousShift := func(x, y ast.Expr) (int64, int64, bool) {
  3946. typ, ok := pass.TypesInfo.TypeOf(x).Underlying().(*types.Basic)
  3947. if !ok {
  3948. return 0, 0, false
  3949. }
  3950. switch typ.Kind() {
  3951. case types.Int8, types.Int16, types.Int32, types.Int64,
  3952. types.Uint8, types.Uint16, types.Uint32, types.Uint64:
  3953. // We're only interested in fixed–size types.
  3954. default:
  3955. return 0, 0, false
  3956. }
  3957. const bitsInByte = 8
  3958. typeBits := pass.TypesSizes.Sizeof(typ) * bitsInByte
  3959. shiftLength, ok := code.ExprToInt(pass, y)
  3960. if !ok {
  3961. return 0, 0, false
  3962. }
  3963. return typeBits, shiftLength, shiftLength >= typeBits
  3964. }
  3965. fn := func(node ast.Node) {
  3966. if _, ok := code.Match(pass, checkFixedLengthTypeShiftQ, node); !ok {
  3967. return
  3968. }
  3969. switch e := node.(type) {
  3970. case *ast.AssignStmt:
  3971. if size, shift, yes := isDubiousShift(e.Lhs[0], e.Rhs[0]); yes {
  3972. report.Report(pass, e, fmt.Sprintf("shifting %d-bit value by %d bits will always clear it", size, shift))
  3973. }
  3974. case *ast.BinaryExpr:
  3975. if size, shift, yes := isDubiousShift(e.X, e.Y); yes {
  3976. report.Report(pass, e, fmt.Sprintf("shifting %d-bit value by %d bits will always clear it", size, shift))
  3977. }
  3978. }
  3979. }
  3980. code.Preorder(pass, fn, (*ast.AssignStmt)(nil), (*ast.BinaryExpr)(nil))
  3981. return nil, nil
  3982. }
  3983. func findSliceLenChecks(pass *analysis.Pass) {
  3984. // mark all function parameters that have to be of even length
  3985. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  3986. for _, b := range fn.Blocks {
  3987. // all paths go through this block
  3988. if !b.Dominates(fn.Exit) {
  3989. continue
  3990. }
  3991. // if foo % 2 != 0
  3992. ifi, ok := b.Control().(*ir.If)
  3993. if !ok {
  3994. continue
  3995. }
  3996. cmp, ok := ifi.Cond.(*ir.BinOp)
  3997. if !ok {
  3998. continue
  3999. }
  4000. var needle uint64
  4001. switch cmp.Op {
  4002. case token.NEQ:
  4003. // look for != 0
  4004. needle = 0
  4005. case token.EQL:
  4006. // look for == 1
  4007. needle = 1
  4008. default:
  4009. continue
  4010. }
  4011. rem, ok1 := cmp.X.(*ir.BinOp)
  4012. k, ok2 := cmp.Y.(*ir.Const)
  4013. if ok1 != ok2 {
  4014. continue
  4015. }
  4016. if !ok1 {
  4017. rem, ok1 = cmp.Y.(*ir.BinOp)
  4018. k, ok2 = cmp.X.(*ir.Const)
  4019. }
  4020. if !ok1 || !ok2 || rem.Op != token.REM || k.Value.Kind() != constant.Int || k.Uint64() != needle {
  4021. continue
  4022. }
  4023. k, ok = rem.Y.(*ir.Const)
  4024. if !ok || k.Value.Kind() != constant.Int || k.Uint64() != 2 {
  4025. continue
  4026. }
  4027. // if len(foo) % 2 != 0
  4028. call, ok := rem.X.(*ir.Call)
  4029. if !ok || !irutil.IsCallTo(call.Common(), "len") {
  4030. continue
  4031. }
  4032. // we're checking the length of a parameter that is a slice
  4033. // TODO(dh): support parameters that have flown through sigmas and phis
  4034. param, ok := call.Call.Args[0].(*ir.Parameter)
  4035. if !ok {
  4036. continue
  4037. }
  4038. if !typeutil.All(param.Type(), typeutil.IsSlice) {
  4039. continue
  4040. }
  4041. // if len(foo) % 2 != 0 then panic
  4042. if _, ok := b.Succs[0].Control().(*ir.Panic); !ok {
  4043. continue
  4044. }
  4045. pass.ExportObjectFact(param.Object(), new(evenElements))
  4046. }
  4047. }
  4048. }
  4049. func findIndirectSliceLenChecks(pass *analysis.Pass) {
  4050. seen := map[*ir.Function]struct{}{}
  4051. var doFunction func(fn *ir.Function)
  4052. doFunction = func(fn *ir.Function) {
  4053. if _, ok := seen[fn]; ok {
  4054. return
  4055. }
  4056. seen[fn] = struct{}{}
  4057. for _, b := range fn.Blocks {
  4058. // all paths go through this block
  4059. if !b.Dominates(fn.Exit) {
  4060. continue
  4061. }
  4062. for _, instr := range b.Instrs {
  4063. call, ok := instr.(*ir.Call)
  4064. if !ok {
  4065. continue
  4066. }
  4067. callee := call.Call.StaticCallee()
  4068. if callee == nil {
  4069. continue
  4070. }
  4071. if callee.Pkg == fn.Pkg || callee.Pkg == nil {
  4072. doFunction(callee)
  4073. }
  4074. for argi, arg := range call.Call.Args {
  4075. if callee.Signature.Recv() != nil {
  4076. if argi == 0 {
  4077. continue
  4078. }
  4079. argi--
  4080. }
  4081. // TODO(dh): support parameters that have flown through length-preserving instructions
  4082. param, ok := arg.(*ir.Parameter)
  4083. if !ok {
  4084. continue
  4085. }
  4086. if !typeutil.All(param.Type(), typeutil.IsSlice) {
  4087. continue
  4088. }
  4089. // We can't use callee.Params to look up the
  4090. // parameter, because Params is not populated for
  4091. // external functions. In our modular analysis.
  4092. // any function in any package that isn't the
  4093. // current package is considered "external", as it
  4094. // has been loaded from export data only.
  4095. sigParams := callee.Signature.Params()
  4096. if !pass.ImportObjectFact(sigParams.At(argi), new(evenElements)) {
  4097. continue
  4098. }
  4099. pass.ExportObjectFact(param.Object(), new(evenElements))
  4100. }
  4101. }
  4102. }
  4103. }
  4104. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  4105. doFunction(fn)
  4106. }
  4107. }
  4108. func findSliceLength(v ir.Value) int {
  4109. // TODO(dh): VRP would help here
  4110. v = irutil.Flatten(v)
  4111. val := func(v ir.Value) int {
  4112. if v, ok := v.(*ir.Const); ok {
  4113. return int(v.Int64())
  4114. }
  4115. return -1
  4116. }
  4117. switch v := v.(type) {
  4118. case *ir.Slice:
  4119. low := 0
  4120. high := -1
  4121. if v.Low != nil {
  4122. low = val(v.Low)
  4123. }
  4124. if v.High != nil {
  4125. high = val(v.High)
  4126. } else {
  4127. switch vv := v.X.(type) {
  4128. case *ir.Alloc:
  4129. high = int(typeutil.Dereference(vv.Type()).Underlying().(*types.Array).Len())
  4130. case *ir.Slice:
  4131. high = findSliceLength(vv)
  4132. }
  4133. }
  4134. if low == -1 || high == -1 {
  4135. return -1
  4136. }
  4137. return high - low
  4138. default:
  4139. return -1
  4140. }
  4141. }
  4142. type evenElements struct{}
  4143. func (evenElements) AFact() {}
  4144. func (evenElements) String() string { return "needs even elements" }
  4145. func flagSliceLens(pass *analysis.Pass) {
  4146. var tag evenElements
  4147. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  4148. for _, b := range fn.Blocks {
  4149. for _, instr := range b.Instrs {
  4150. call, ok := instr.(ir.CallInstruction)
  4151. if !ok {
  4152. continue
  4153. }
  4154. callee := call.Common().StaticCallee()
  4155. if callee == nil {
  4156. continue
  4157. }
  4158. for argi, arg := range call.Common().Args {
  4159. if callee.Signature.Recv() != nil {
  4160. if argi == 0 {
  4161. continue
  4162. }
  4163. argi--
  4164. }
  4165. _, ok := arg.Type().Underlying().(*types.Slice)
  4166. if !ok {
  4167. continue
  4168. }
  4169. param := callee.Signature.Params().At(argi)
  4170. if !pass.ImportObjectFact(param, &tag) {
  4171. continue
  4172. }
  4173. // TODO handle stubs
  4174. // we know the argument has to have even length.
  4175. // now let's try to find its length
  4176. if n := findSliceLength(arg); n > -1 && n%2 != 0 {
  4177. src := call.Source().(*ast.CallExpr).Args[argi]
  4178. sig := call.Common().Signature()
  4179. var label string
  4180. if argi == sig.Params().Len()-1 && sig.Variadic() {
  4181. label = "variadic argument"
  4182. } else {
  4183. label = "argument"
  4184. }
  4185. // Note that param.Name() is guaranteed to not
  4186. // be empty, otherwise the function couldn't
  4187. // have enforced its length.
  4188. report.Report(pass, src, fmt.Sprintf("%s %q is expected to have even number of elements, but has %d elements", label, param.Name(), n))
  4189. }
  4190. }
  4191. }
  4192. }
  4193. }
  4194. }
  4195. func CheckEvenSliceLength(pass *analysis.Pass) (interface{}, error) {
  4196. findSliceLenChecks(pass)
  4197. findIndirectSliceLenChecks(pass)
  4198. flagSliceLens(pass)
  4199. return nil, nil
  4200. }
  4201. func CheckTypedNilInterface(pass *analysis.Pass) (interface{}, error) {
  4202. // The comparison 'fn() == nil' can never be true if fn() returns
  4203. // an interface value and only returns typed nils. This is usually
  4204. // a mistake in the function itself, but all we can say for
  4205. // certain is that the comparison is pointless.
  4206. //
  4207. // Flag results if no untyped nils are being returned, but either
  4208. // known typed nils, or typed unknown nilness are being returned.
  4209. irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR)
  4210. typedness := pass.ResultOf[typedness.Analysis].(*typedness.Result)
  4211. nilness := pass.ResultOf[nilness.Analysis].(*nilness.Result)
  4212. for _, fn := range irpkg.SrcFuncs {
  4213. for _, b := range fn.Blocks {
  4214. for _, instr := range b.Instrs {
  4215. binop, ok := instr.(*ir.BinOp)
  4216. if !ok || !(binop.Op == token.EQL || binop.Op == token.NEQ) {
  4217. continue
  4218. }
  4219. if _, ok := binop.X.Type().Underlying().(*types.Interface); !ok || typeparams.IsTypeParam(binop.X.Type()) {
  4220. // TODO support swapped X and Y
  4221. continue
  4222. }
  4223. k, ok := binop.Y.(*ir.Const)
  4224. if !ok || !k.IsNil() {
  4225. // if binop.X is an interface, then binop.Y can
  4226. // only be a Const if its untyped. A typed nil
  4227. // constant would first be passed to
  4228. // MakeInterface.
  4229. continue
  4230. }
  4231. var idx int
  4232. var obj *types.Func
  4233. switch x := irutil.Flatten(binop.X).(type) {
  4234. case *ir.Call:
  4235. callee := x.Call.StaticCallee()
  4236. if callee == nil {
  4237. continue
  4238. }
  4239. obj, _ = callee.Object().(*types.Func)
  4240. idx = 0
  4241. case *ir.Extract:
  4242. call, ok := irutil.Flatten(x.Tuple).(*ir.Call)
  4243. if !ok {
  4244. continue
  4245. }
  4246. callee := call.Call.StaticCallee()
  4247. if callee == nil {
  4248. continue
  4249. }
  4250. obj, _ = callee.Object().(*types.Func)
  4251. idx = x.Index
  4252. case *ir.MakeInterface:
  4253. var qualifier string
  4254. switch binop.Op {
  4255. case token.EQL:
  4256. qualifier = "never"
  4257. case token.NEQ:
  4258. qualifier = "always"
  4259. default:
  4260. panic("unreachable")
  4261. }
  4262. terms, err := typeparams.NormalTerms(x.X.Type())
  4263. if len(terms) == 0 || err != nil {
  4264. // Type is a type parameter with no type terms (or we couldn't determine the terms). Such a type
  4265. // _can_ be nil when put in an interface value.
  4266. continue
  4267. }
  4268. if report.HasRange(x.X) {
  4269. report.Report(pass, binop, fmt.Sprintf("this comparison is %s true", qualifier),
  4270. report.Related(x.X, "the lhs of the comparison gets its value from here and has a concrete type"))
  4271. } else {
  4272. // we can't generate related information for this, so make the diagnostic itself slightly more useful
  4273. report.Report(pass, binop, fmt.Sprintf("this comparison is %s true; the lhs of the comparison has been assigned a concretely typed value", qualifier))
  4274. }
  4275. continue
  4276. }
  4277. if obj == nil {
  4278. continue
  4279. }
  4280. isNil, onlyGlobal := nilness.MayReturnNil(obj, idx)
  4281. if typedness.MustReturnTyped(obj, idx) && isNil && !onlyGlobal && !code.IsInTest(pass, binop) {
  4282. // Don't flag these comparisons in tests. Tests
  4283. // may be explicitly enforcing the invariant that
  4284. // a value isn't nil.
  4285. var qualifier string
  4286. switch binop.Op {
  4287. case token.EQL:
  4288. qualifier = "never"
  4289. case token.NEQ:
  4290. qualifier = "always"
  4291. default:
  4292. panic("unreachable")
  4293. }
  4294. report.Report(pass, binop, fmt.Sprintf("this comparison is %s true", qualifier),
  4295. // TODO support swapped X and Y
  4296. report.Related(binop.X, fmt.Sprintf("the lhs of the comparison is the %s return value of this function call", report.Ordinal(idx+1))),
  4297. report.Related(obj, fmt.Sprintf("%s never returns a nil interface value", typeutil.FuncName(obj))))
  4298. }
  4299. }
  4300. }
  4301. }
  4302. return nil, nil
  4303. }
  4304. var builtinLessThanZeroQ = pattern.MustParse(`
  4305. (Or
  4306. (BinaryExpr
  4307. (IntegerLiteral "0")
  4308. ">"
  4309. (CallExpr builtin@(Builtin (Or "len" "cap")) _))
  4310. (BinaryExpr
  4311. (CallExpr builtin@(Builtin (Or "len" "cap")) _)
  4312. "<"
  4313. (IntegerLiteral "0")))
  4314. `)
  4315. func CheckBuiltinZeroComparison(pass *analysis.Pass) (interface{}, error) {
  4316. fn := func(node ast.Node) {
  4317. matcher, ok := code.Match(pass, builtinLessThanZeroQ, node)
  4318. if !ok {
  4319. return
  4320. }
  4321. builtin := matcher.State["builtin"].(*ast.Ident)
  4322. report.Report(pass, node, fmt.Sprintf("builtin function %s does not return negative values", builtin.Name))
  4323. }
  4324. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  4325. return nil, nil
  4326. }
  4327. var integerDivisionQ = pattern.MustParse(`(BinaryExpr (IntegerLiteral _) "/" (IntegerLiteral _))`)
  4328. func CheckIntegerDivisionEqualsZero(pass *analysis.Pass) (interface{}, error) {
  4329. fn := func(node ast.Node) {
  4330. _, ok := code.Match(pass, integerDivisionQ, node)
  4331. if !ok {
  4332. return
  4333. }
  4334. val := constant.ToInt(pass.TypesInfo.Types[node.(ast.Expr)].Value)
  4335. if v, ok := constant.Uint64Val(val); ok && v == 0 {
  4336. report.Report(pass, node, fmt.Sprintf("the integer division '%s' results in zero", report.Render(pass, node)))
  4337. }
  4338. // TODO: we could offer a suggested fix here, but I am not
  4339. // sure what it should be. There are many options to choose
  4340. // from.
  4341. // Note: we experimented with flagging divisions that truncate
  4342. // (e.g. 4 / 3), but it ran into false positives in Go's
  4343. // 'time' package, which does this, deliberately:
  4344. //
  4345. // unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
  4346. //
  4347. // The check also found a real bug in other code, but I don't
  4348. // think we can outright ban this kind of division.
  4349. }
  4350. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  4351. return nil, nil
  4352. }
  4353. func CheckIneffectiveFieldAssignments(pass *analysis.Pass) (interface{}, error) {
  4354. // The analysis only considers the receiver and its first level
  4355. // fields. It doesn't look at other parameters, nor at nested
  4356. // fields.
  4357. //
  4358. // The analysis does not detect all kinds of dead stores, only
  4359. // those of fields that are never read after the write. That is,
  4360. // we do not flag 'a.x = 1; a.x = 2; _ = a.x'. We might explore
  4361. // this again if we add support for SROA to go/ir and implement
  4362. // https://github.com/dominikh/go-tools/issues/191.
  4363. irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR)
  4364. fnLoop:
  4365. for _, fn := range irpkg.SrcFuncs {
  4366. if recv := fn.Signature.Recv(); recv == nil {
  4367. continue
  4368. } else if _, ok := recv.Type().Underlying().(*types.Struct); !ok {
  4369. continue
  4370. }
  4371. recv := fn.Params[0]
  4372. refs := irutil.FilterDebug(*recv.Referrers())
  4373. if len(refs) != 1 {
  4374. continue
  4375. }
  4376. store, ok := refs[0].(*ir.Store)
  4377. if !ok {
  4378. continue
  4379. }
  4380. alloc, ok := store.Addr.(*ir.Alloc)
  4381. if !ok || alloc.Heap {
  4382. continue
  4383. }
  4384. reads := map[int][]ir.Instruction{}
  4385. writes := map[int][]ir.Instruction{}
  4386. for _, ref := range *alloc.Referrers() {
  4387. switch ref := ref.(type) {
  4388. case *ir.FieldAddr:
  4389. for _, refref := range *ref.Referrers() {
  4390. switch refref.(type) {
  4391. case *ir.Store:
  4392. writes[ref.Field] = append(writes[ref.Field], refref)
  4393. case *ir.Load:
  4394. reads[ref.Field] = append(reads[ref.Field], refref)
  4395. case *ir.DebugRef:
  4396. continue
  4397. default:
  4398. // this should be safe… if the field address
  4399. // escapes, then alloc.Heap will be true.
  4400. // there should be no instructions left that,
  4401. // given this FieldAddr, without escaping, can
  4402. // effect a load or store.
  4403. continue
  4404. }
  4405. }
  4406. case *ir.Store:
  4407. // we could treat this as a store to every field, but
  4408. // we don't want to decide the semantics of partial
  4409. // struct initializers. should `v = t{x: 1}` also mark
  4410. // v.y as being written to?
  4411. if ref != store {
  4412. continue fnLoop
  4413. }
  4414. case *ir.Load:
  4415. // a load of the entire struct loads every field
  4416. for i := 0; i < recv.Type().Underlying().(*types.Struct).NumFields(); i++ {
  4417. reads[i] = append(reads[i], ref)
  4418. }
  4419. case *ir.DebugRef:
  4420. continue
  4421. default:
  4422. continue fnLoop
  4423. }
  4424. }
  4425. offset := func(instr ir.Instruction) int {
  4426. for i, other := range instr.Block().Instrs {
  4427. if instr == other {
  4428. return i
  4429. }
  4430. }
  4431. panic("couldn't find instruction in its block")
  4432. }
  4433. for field, ws := range writes {
  4434. rs := reads[field]
  4435. wLoop:
  4436. for _, w := range ws {
  4437. for _, r := range rs {
  4438. if w.Block() == r.Block() {
  4439. if offset(r) > offset(w) {
  4440. // found a reachable read of our write
  4441. continue wLoop
  4442. }
  4443. } else if irutil.Reachable(w.Block(), r.Block()) {
  4444. // found a reachable read of our write
  4445. continue wLoop
  4446. }
  4447. }
  4448. fieldName := recv.Type().Underlying().(*types.Struct).Field(field).Name()
  4449. report.Report(pass, w, fmt.Sprintf("ineffective assignment to field %s.%s", recv.Type().(*types.Named).Obj().Name(), fieldName))
  4450. }
  4451. }
  4452. }
  4453. return nil, nil
  4454. }
  4455. var negativeZeroFloatQ = pattern.MustParse(`
  4456. (Or
  4457. (UnaryExpr
  4458. "-"
  4459. (BasicLit "FLOAT" "0.0"))
  4460. (UnaryExpr
  4461. "-"
  4462. (CallExpr conv@(Object (Or "float32" "float64")) lit@(Or (BasicLit "INT" "0") (BasicLit "FLOAT" "0.0"))))
  4463. (CallExpr
  4464. conv@(Object (Or "float32" "float64"))
  4465. (UnaryExpr "-" lit@(BasicLit "INT" "0"))))`)
  4466. func CheckNegativeZeroFloat(pass *analysis.Pass) (interface{}, error) {
  4467. fn := func(node ast.Node) {
  4468. m, ok := code.Match(pass, negativeZeroFloatQ, node)
  4469. if !ok {
  4470. return
  4471. }
  4472. if conv, ok := m.State["conv"].(*types.TypeName); ok {
  4473. var replacement string
  4474. // TODO(dh): how does this handle type aliases?
  4475. if conv.Name() == "float32" {
  4476. replacement = `float32(math.Copysign(0, -1))`
  4477. } else {
  4478. replacement = `math.Copysign(0, -1)`
  4479. }
  4480. report.Report(pass, node,
  4481. fmt.Sprintf("in Go, the floating-point expression '%s' is the same as '%s(%s)', it does not produce a negative zero",
  4482. report.Render(pass, node),
  4483. conv.Name(),
  4484. report.Render(pass, m.State["lit"])),
  4485. report.Fixes(edit.Fix("use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
  4486. } else {
  4487. const replacement = `math.Copysign(0, -1)`
  4488. report.Report(pass, node,
  4489. "in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero",
  4490. report.Fixes(edit.Fix("use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
  4491. }
  4492. }
  4493. code.Preorder(pass, fn, (*ast.UnaryExpr)(nil), (*ast.CallExpr)(nil))
  4494. return nil, nil
  4495. }
  4496. var ineffectiveURLQueryAddQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (SelectorExpr recv (Ident "Query")) []) (Ident meth)) _)`)
  4497. func CheckIneffectiveURLQueryModification(pass *analysis.Pass) (interface{}, error) {
  4498. // TODO(dh): We could make this check more complex and detect
  4499. // pointless modifications of net/url.Values in general, but that
  4500. // requires us to get the state machine correct, else we'll cause
  4501. // false positives.
  4502. fn := func(node ast.Node) {
  4503. m, ok := code.Match(pass, ineffectiveURLQueryAddQ, node)
  4504. if !ok {
  4505. return
  4506. }
  4507. if !code.IsOfType(pass, m.State["recv"].(ast.Expr), "*net/url.URL") {
  4508. return
  4509. }
  4510. switch m.State["meth"].(string) {
  4511. case "Add", "Del", "Set":
  4512. default:
  4513. return
  4514. }
  4515. report.Report(pass, node, "(*net/url.URL).Query returns a copy, modifying it doesn't change the URL")
  4516. }
  4517. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  4518. return nil, nil
  4519. }
  4520. func CheckBadRemoveAll(pass *analysis.Pass) (interface{}, error) {
  4521. for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
  4522. for _, b := range fn.Blocks {
  4523. for _, instr := range b.Instrs {
  4524. call, ok := instr.(ir.CallInstruction)
  4525. if !ok {
  4526. continue
  4527. }
  4528. if !irutil.IsCallTo(call.Common(), "os.RemoveAll") {
  4529. continue
  4530. }
  4531. kind := ""
  4532. ex := ""
  4533. callName := ""
  4534. arg := irutil.Flatten(call.Common().Args[0])
  4535. switch arg := arg.(type) {
  4536. case *ir.Call:
  4537. callName = irutil.CallName(&arg.Call)
  4538. if callName != "os.TempDir" {
  4539. continue
  4540. }
  4541. kind = "temporary"
  4542. ex = os.TempDir()
  4543. case *ir.Extract:
  4544. if arg.Index != 0 {
  4545. continue
  4546. }
  4547. first, ok := arg.Tuple.(*ir.Call)
  4548. if !ok {
  4549. continue
  4550. }
  4551. callName = irutil.CallName(&first.Call)
  4552. switch callName {
  4553. case "os.UserCacheDir":
  4554. kind = "cache"
  4555. ex, _ = os.UserCacheDir()
  4556. case "os.UserConfigDir":
  4557. kind = "config"
  4558. ex, _ = os.UserConfigDir()
  4559. case "os.UserHomeDir":
  4560. kind = "home"
  4561. ex, _ = os.UserHomeDir()
  4562. default:
  4563. continue
  4564. }
  4565. default:
  4566. continue
  4567. }
  4568. if ex == "" {
  4569. report.Report(pass, call, fmt.Sprintf("this call to os.RemoveAll deletes the user's entire %s directory, not a subdirectory therein", kind),
  4570. report.Related(arg, fmt.Sprintf("this call to %s returns the user's %s directory", callName, kind)))
  4571. } else {
  4572. report.Report(pass, call, fmt.Sprintf("this call to os.RemoveAll deletes the user's entire %s directory, not a subdirectory therein", kind),
  4573. report.Related(arg, fmt.Sprintf("this call to %s returns the user's %s directory, for example %s", callName, kind, ex)))
  4574. }
  4575. }
  4576. }
  4577. }
  4578. return nil, nil
  4579. }
  4580. var moduloOneQ = pattern.MustParse(`(BinaryExpr _ "%" (IntegerLiteral "1"))`)
  4581. func CheckModuloOne(pass *analysis.Pass) (interface{}, error) {
  4582. fn := func(node ast.Node) {
  4583. _, ok := code.Match(pass, moduloOneQ, node)
  4584. if !ok {
  4585. return
  4586. }
  4587. report.Report(pass, node, "x % 1 is always zero")
  4588. }
  4589. code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
  4590. return nil, nil
  4591. }
  4592. var typeAssertionShadowingElseQ = pattern.MustParse(`(IfStmt (AssignStmt [obj@(Ident _) ok@(Ident _)] ":=" assert@(TypeAssertExpr obj _)) ok _ elseBranch)`)
  4593. func CheckTypeAssertionShadowingElse(pass *analysis.Pass) (interface{}, error) {
  4594. // TODO(dh): without the IR-based verification, this check is able
  4595. // to find more bugs, but also more prone to false positives. It
  4596. // would be a good candidate for the 'codereview' category of
  4597. // checks.
  4598. irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
  4599. fn := func(node ast.Node) {
  4600. m, ok := code.Match(pass, typeAssertionShadowingElseQ, node)
  4601. if !ok {
  4602. return
  4603. }
  4604. shadow := pass.TypesInfo.ObjectOf(m.State["obj"].(*ast.Ident))
  4605. shadowed := m.State["assert"].(*ast.TypeAssertExpr).X
  4606. path, exact := astutil.PathEnclosingInterval(code.File(pass, shadow), shadow.Pos(), shadow.Pos())
  4607. if !exact {
  4608. // TODO(dh): when can this happen?
  4609. return
  4610. }
  4611. irfn := ir.EnclosingFunction(irpkg, path)
  4612. shadoweeIR, isAddr := irfn.ValueForExpr(m.State["obj"].(*ast.Ident))
  4613. if shadoweeIR == nil || isAddr {
  4614. // TODO(dh): is this possible?
  4615. return
  4616. }
  4617. var branch ast.Node
  4618. switch br := m.State["elseBranch"].(type) {
  4619. case ast.Node:
  4620. branch = br
  4621. case []ast.Stmt:
  4622. branch = &ast.BlockStmt{List: br}
  4623. case nil:
  4624. return
  4625. default:
  4626. panic(fmt.Sprintf("unexpected type %T", br))
  4627. }
  4628. ast.Inspect(branch, func(node ast.Node) bool {
  4629. ident, ok := node.(*ast.Ident)
  4630. if !ok {
  4631. return true
  4632. }
  4633. if pass.TypesInfo.ObjectOf(ident) != shadow {
  4634. return true
  4635. }
  4636. v, isAddr := irfn.ValueForExpr(ident)
  4637. if v == nil || isAddr {
  4638. return true
  4639. }
  4640. if irutil.Flatten(v) != shadoweeIR {
  4641. // Same types.Object, but different IR value. This
  4642. // either means that the variable has been
  4643. // assigned to since the type assertion, or that
  4644. // the variable has escaped to the heap. Either
  4645. // way, we shouldn't flag reads of it.
  4646. return true
  4647. }
  4648. report.Report(pass, ident,
  4649. fmt.Sprintf("%s refers to the result of a failed type assertion and is a zero value, not the value that was being type-asserted", report.Render(pass, ident)),
  4650. report.Related(shadow, "this is the variable being read"),
  4651. report.Related(shadowed, "this is the variable being shadowed"))
  4652. return true
  4653. })
  4654. }
  4655. code.Preorder(pass, fn, (*ast.IfStmt)(nil))
  4656. return nil, nil
  4657. }
  4658. var ineffectiveSortQ = pattern.MustParse(`(AssignStmt target@(Ident _) "=" (CallExpr typ@(Function (Or "sort.Float64Slice" "sort.IntSlice" "sort.StringSlice")) [target]))`)
  4659. func CheckIneffectiveSort(pass *analysis.Pass) (interface{}, error) {
  4660. fn := func(node ast.Node) {
  4661. m, ok := code.Match(pass, ineffectiveSortQ, node)
  4662. if !ok {
  4663. return
  4664. }
  4665. _, ok = pass.TypesInfo.TypeOf(m.State["target"].(ast.Expr)).(*types.Slice)
  4666. if !ok {
  4667. // Avoid flagging 'x = sort.StringSlice(x)' where TypeOf(x) == sort.StringSlice
  4668. return
  4669. }
  4670. var alternative string
  4671. typeName := types.TypeString(m.State["typ"].(*types.TypeName).Type(), nil)
  4672. switch typeName {
  4673. case "sort.Float64Slice":
  4674. alternative = "Float64s"
  4675. case "sort.IntSlice":
  4676. alternative = "Ints"
  4677. case "sort.StringSlice":
  4678. alternative = "Strings"
  4679. default:
  4680. panic(fmt.Sprintf("unreachable: %q", typeName))
  4681. }
  4682. r := &ast.CallExpr{
  4683. Fun: &ast.SelectorExpr{
  4684. X: &ast.Ident{Name: "sort"},
  4685. Sel: &ast.Ident{Name: alternative},
  4686. },
  4687. Args: []ast.Expr{m.State["target"].(ast.Expr)},
  4688. }
  4689. report.Report(pass, node,
  4690. fmt.Sprintf("%s is a type, not a function, and %s doesn't sort your values; consider using sort.%s instead",
  4691. typeName,
  4692. report.Render(pass, node.(*ast.AssignStmt).Rhs[0]),
  4693. alternative),
  4694. report.Fixes(edit.Fix(fmt.Sprintf("replace with call to sort.%s", alternative), edit.ReplaceWithNode(pass.Fset, node, r))))
  4695. }
  4696. code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
  4697. return nil, nil
  4698. }
  4699. var ineffectiveRandIntQ = pattern.MustParse(`
  4700. (CallExpr
  4701. (Function
  4702. name@(Or
  4703. "math/rand.Int31n"
  4704. "math/rand.Int63n"
  4705. "math/rand.Intn"
  4706. "(*math/rand.Rand).Int31n"
  4707. "(*math/rand.Rand).Int63n"
  4708. "(*math/rand.Rand).Intn"))
  4709. [(IntegerLiteral "1")])`)
  4710. func CheckIneffectiveRandInt(pass *analysis.Pass) (interface{}, error) {
  4711. fn := func(node ast.Node) {
  4712. m, ok := code.Match(pass, ineffectiveRandIntQ, node)
  4713. if !ok {
  4714. return
  4715. }
  4716. report.Report(pass, node,
  4717. fmt.Sprintf("%s(n) generates a random value 0 <= x < n; that is, the generated values don't include n; %s therefore always returns 0",
  4718. m.State["name"], report.Render(pass, node)))
  4719. }
  4720. code.Preorder(pass, fn, (*ast.CallExpr)(nil))
  4721. return nil, nil
  4722. }
  4723. var allocationNilCheckQ = pattern.MustParse(`(IfStmt _ cond@(BinaryExpr lhs op@(Or "==" "!=") (Builtin "nil")) _ _)`)
  4724. func CheckAllocationNilCheck(pass *analysis.Pass) (interface{}, error) {
  4725. irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
  4726. fn := func(node ast.Node) {
  4727. m, ok := code.Match(pass, allocationNilCheckQ, node)
  4728. if !ok {
  4729. return
  4730. }
  4731. cond := m.State["cond"].(ast.Node)
  4732. if _, ok := code.Match(pass, checkAddressIsNilQ, cond); ok {
  4733. // Don't duplicate diagnostics reported by SA4022
  4734. return
  4735. }
  4736. lhs := m.State["lhs"].(ast.Expr)
  4737. path, exact := astutil.PathEnclosingInterval(code.File(pass, lhs), lhs.Pos(), lhs.Pos())
  4738. if !exact {
  4739. // TODO(dh): when can this happen?
  4740. return
  4741. }
  4742. irfn := ir.EnclosingFunction(irpkg, path)
  4743. v, isAddr := irfn.ValueForExpr(lhs)
  4744. if isAddr {
  4745. return
  4746. }
  4747. seen := map[ir.Value]struct{}{}
  4748. var values []ir.Value
  4749. var neverNil func(v ir.Value, track bool) bool
  4750. neverNil = func(v ir.Value, track bool) bool {
  4751. if _, ok := seen[v]; ok {
  4752. return true
  4753. }
  4754. seen[v] = struct{}{}
  4755. switch v := v.(type) {
  4756. case *ir.MakeClosure, *ir.Function:
  4757. if track {
  4758. values = append(values, v)
  4759. }
  4760. return true
  4761. case *ir.MakeChan, *ir.MakeMap, *ir.MakeSlice, *ir.Alloc:
  4762. if track {
  4763. values = append(values, v)
  4764. }
  4765. return true
  4766. case *ir.Slice:
  4767. if track {
  4768. values = append(values, v)
  4769. }
  4770. return neverNil(v.X, false)
  4771. case *ir.FieldAddr:
  4772. if track {
  4773. values = append(values, v)
  4774. }
  4775. return neverNil(v.X, false)
  4776. case *ir.Sigma:
  4777. return neverNil(v.X, true)
  4778. case *ir.Phi:
  4779. for _, e := range v.Edges {
  4780. if !neverNil(e, true) {
  4781. return false
  4782. }
  4783. }
  4784. return true
  4785. default:
  4786. return false
  4787. }
  4788. }
  4789. if !neverNil(v, true) {
  4790. return
  4791. }
  4792. var qualifier string
  4793. if op := m.State["op"].(token.Token); op == token.EQL {
  4794. qualifier = "never"
  4795. } else {
  4796. qualifier = "always"
  4797. }
  4798. fallback := fmt.Sprintf("this nil check is %s true", qualifier)
  4799. sort.Slice(values, func(i, j int) bool { return values[i].Pos() < values[j].Pos() })
  4800. if ident, ok := m.State["lhs"].(*ast.Ident); ok {
  4801. if _, ok := pass.TypesInfo.ObjectOf(ident).(*types.Var); ok {
  4802. var opts []report.Option
  4803. if v.Parent() == irfn {
  4804. if len(values) == 1 {
  4805. opts = append(opts, report.Related(values[0], fmt.Sprintf("this is the value of %s", ident.Name)))
  4806. } else {
  4807. for _, vv := range values {
  4808. opts = append(opts, report.Related(vv, fmt.Sprintf("this is one of the value of %s", ident.Name)))
  4809. }
  4810. }
  4811. }
  4812. switch v.(type) {
  4813. case *ir.MakeClosure, *ir.Function:
  4814. report.Report(pass, cond, "the checked variable contains a function and is never nil; did you mean to call it?", opts...)
  4815. default:
  4816. report.Report(pass, cond, fallback, opts...)
  4817. }
  4818. } else {
  4819. if _, ok := v.(*ir.Function); ok {
  4820. report.Report(pass, cond, "functions are never nil; did you mean to call it?")
  4821. } else {
  4822. report.Report(pass, cond, fallback)
  4823. }
  4824. }
  4825. } else {
  4826. if _, ok := v.(*ir.Function); ok {
  4827. report.Report(pass, cond, "functions are never nil; did you mean to call it?")
  4828. } else {
  4829. report.Report(pass, cond, fallback)
  4830. }
  4831. }
  4832. }
  4833. code.Preorder(pass, fn, (*ast.IfStmt)(nil))
  4834. return nil, nil
  4835. }