diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ee50a4c049..1984d44c53 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -33,6 +33,7 @@ Aaron Jacobs Aaron Jensen Aaron Kemp Aaron Patterson +Aaron Sheah Aaron Stein Aaron Torres Aaron Zinman @@ -47,6 +48,7 @@ Adam Harvey Adam Kisala Adam Langley Adam Medzinski +Adam Mitha Adam Shannon Adam Shelton Adam Sindelar @@ -54,6 +56,8 @@ Adam Thomason Adam Williams Adam Woodbeck Adarsh Ravichandran +Adel Rodríguez +Adin Scannell Aditya Harindar Aditya Mukerjee Adrian Hesketh @@ -68,6 +72,7 @@ Afanasev Stanislav Agis Anastasopoulos Agniva De Sarker Ahmed W. Mones +Ahmet Aktürk Ahmet Alp Balkan Ahmet Soormally Ahmy Yulrizka @@ -92,11 +97,13 @@ Alberto Bertogli Alberto Donizetti Alberto García Hierro Alec Benzer +Alejandro García Montoro Aleksa Sarai Aleksandar Dezelin Aleksandr Lukinykh Aleksandr Razumov Alekseev Artem +Aleksei Tirman Alessandro Arzilli Alessandro Baffa Alex A Skinner @@ -165,6 +172,7 @@ Ali Rizvi-Santiago Aliaksandr Valialkin Alice Merrick Alif Rachmawadi +Allan Guwatudde Allan Simon Allen Li Alok Menghrajani @@ -172,6 +180,7 @@ Alwin Doss Aman Gupta Amarjeet Anand Amir Mohammad Saied +Amit Kumar Amr Mohammed Amrut Joshi An Long @@ -185,6 +194,7 @@ André Carvalho André Martins Andre Nathan Andrea Nodari +Andrea Simonini Andrea Spadaccini Andreas Auernhammer Andreas Jellinghaus @@ -244,6 +254,7 @@ Andy Pan Andy Walker Andy Wang Andy Williams +Andy Zhao Andzej Maciusovic Anfernee Yongkun Gui Angelo Bulfone @@ -269,6 +280,7 @@ Anton Kuklin Antonin Amand Antonio Antelo Antonio Bibiano +Antonio Garcia Antonio Huete Jimenez Antonio Murdaca Antonio Troina @@ -292,8 +304,10 @@ Artem Khvastunov Artem Kolin Arthur Fabre Arthur Khashaev +Artur M. Wolff Artyom Pervukhin Arvindh Rajesh Tamilmani +Ashish Bhate Ashish Gandhi Asim Shankar Assel Meher @@ -325,6 +339,7 @@ Baokun Lee Barnaby Keene Bartosz Grzybowski Bartosz Oler +Bassam Ojeil Bastian Ike Ben Burkert Ben Cartwright-Cox @@ -332,6 +347,7 @@ Ben Eitzen Ben Fried Ben Haines Ben Hoyt +Ben Hutchings Ben Kraft Ben Laurie Ben Lubar @@ -430,6 +446,7 @@ Carl Henrik Lunde Carl Jackson Carl Johnson Carl Mastrangelo +Carl Menezes Carl Shapiro Carlisia Campos Carlo Alberto Ferraris @@ -443,6 +460,7 @@ Carlos Iriarte Carlos Souza Carolyn Van Slyck Carrie Bynon +Carson Hoffman Cary Hull Case Nelson Casey Callendrello @@ -462,6 +480,7 @@ Charles Kenney Charles L. Dorian Charles Lee Charles Weill +Charlie Moog Charlotte Brandhorst-Satzkorn Chauncy Cullitan Chen Zhidong @@ -516,6 +535,7 @@ Christopher Nelson Christopher Nielsen Christopher Redden Christopher Swenson +Christopher Thomas <53317512+chrisssthomas@users.noreply.github.com> Christopher Wedgwood Christos Zoulas Christy Perez @@ -541,6 +561,8 @@ Cosmos Nicolaou Costin Chirvasuta Craig Citro Cristian Staretu +Cristo García +cui fliter Cuihtlauac ALVARADO Cuong Manh Le Curtis La Graff @@ -560,6 +582,7 @@ Dan Callahan Dan Harrington Dan Jacques Dan Johnson +Dan McArdle Dan Peterson Dan Pupius Dan Scales @@ -611,6 +634,7 @@ Dave Russell David Anderson David Barnett David Benjamin +David Black David Bond David Brophy David Bürgin <676c7473@gmail.com> @@ -654,6 +678,7 @@ Davor Kapsa Dean Eigenmann <7621705+decanus@users.noreply.github.com> Dean Prichard Deepak Jois +Deepak S Denis Bernard Denis Brandolini Denis Isaev @@ -676,8 +701,10 @@ Dhiru Kholia Dhruvdutt Jadhav Di Xiao Didier Spezia +Diego Medina Diego Siqueira Dieter Plaetinck +Dilyn Corner Dimitri Sokolyuk Dimitri Tcaciuc Dina Garmash @@ -714,6 +741,7 @@ Doug Fawley Douglas Danger Manley Drew Flower Drew Hintz +Drew Richardson Duco van Amstel Duncan Holm Dustin Carlino @@ -735,6 +763,7 @@ Egon Elbre Ehren Kret Eitan Adler Eivind Uggedal +El Mostafa Idrassi Elbert Fliek Eldar Rakhimberdin Elena Grahovac @@ -742,6 +771,7 @@ Eli Bendersky Elias Naur Elliot Morrison-Reed Ellison Leão +Elvina Yakubova Emerson Lin Emil Bektimirov Emil Hessman @@ -767,6 +797,7 @@ Eric Rescorla Eric Roshan-Eisner Eric Rutherford Eric Rykwalder +Eric Wang Erick Tryzelaar Erik Aigner Erik Dubbelboer @@ -778,6 +809,7 @@ Ernest Chiang Erwin Oegema Esko Luontola Ethan Burns +Ethan Hur Ethan Miller Euan Kemp Eugene Formanenko @@ -818,6 +850,7 @@ Felix Cornelius <9767036+fcornelius@users.noreply.github.com> Felix Geisendörfer Felix Kollmann Ferenc Szabo +Fernandez Ludovic Filip Gruszczyński Filip Haglund Filip Stanis @@ -858,6 +891,7 @@ Gabriel Nelle Gabriel Nicolas Avellaneda Gabriel Rosenhouse Gabriel Russell +Gabriel Vasile Gareth Paul Jones Garret Kelly Garrick Evans @@ -891,6 +925,8 @@ Gianguido Sora` Gideon Jan-Wessel Redelinghuys Giles Lean Giovanni Bajo +GitHub User @180909 (70465953) <734461790@qq.com> +GitHub User @6543 (24977596) <6543@obermui.de> GitHub User @aca (50316549) GitHub User @ajnirp (1688456) GitHub User @ajz01 (4744634) @@ -904,10 +940,12 @@ GitHub User @bontequero (2674999) GitHub User @cch123 (384546) GitHub User @chainhelen (7046329) GitHub User @chanxuehong (3416908) +GitHub User @Cluas (10056928) GitHub User @cncal (23520240) GitHub User @DQNEO (188741) GitHub User @Dreamacro (8615343) GitHub User @dupoxy (1143957) +GitHub User @EndlessCheng (7086966) GitHub User @erifan (31343225) GitHub User @esell (9735165) GitHub User @fatedier (7346661) @@ -916,12 +954,15 @@ GitHub User @geedchin (11672310) GitHub User @GrigoriyMikhalkin (3637857) GitHub User @hengwu0 (41297446) <41297446+hengwu0@users.noreply.github.com> GitHub User @hitzhangjie (3725760) +GitHub User @hqpko (13887251) GitHub User @itchyny (375258) GitHub User @jinmiaoluo (39730824) GitHub User @jopbrown (6345470) GitHub User @kazyshr (30496953) GitHub User @kc1212 (1093806) +GitHub User @komisan19 (18901496) GitHub User @Kropekk (13366453) +GitHub User @lhl2617 (33488131) GitHub User @linguohua (3434367) GitHub User @LotusFenn (13775899) GitHub User @ly303550688 (11519839) @@ -936,10 +977,14 @@ GitHub User @OlgaVlPetrova (44112727) GitHub User @pityonline (438222) GitHub User @po3rin (29445112) GitHub User @pokutuna (57545) +GitHub User @povsister (11040951) GitHub User @pytimer (17105586) +GitHub User @qcrao (7698088) GitHub User @ramenjuniti (32011829) GitHub User @saitarunreddy (21041941) +GitHub User @SataQiu (9354727) GitHub User @shogo-ma (9860598) +GitHub User @sivchari (55221074) GitHub User @skanehira (7888591) GitHub User @soolaugust (10558124) GitHub User @surechen (7249331) @@ -947,9 +992,12 @@ GitHub User @tatsumack (4510569) GitHub User @tell-k (26263) GitHub User @tennashi (10219626) GitHub User @uhei (2116845) +GitHub User @uji (49834542) +GitHub User @unbyte (5772358) GitHub User @uropek (39370426) GitHub User @utkarsh-extc (53217283) GitHub User @witchard (4994659) +GitHub User @wolf1996 (5901874) GitHub User @yah01 (12216890) GitHub User @yuanhh (1298735) GitHub User @zikaeroh (48577114) @@ -962,6 +1010,7 @@ Glenn Brown Glenn Lewis Gordon Klaus Gordon Tyler +Grace Han Graham King Graham Miller Grant Griffiths @@ -977,10 +1026,12 @@ Guilherme Caruso Guilherme Garnier Guilherme Goncalves Guilherme Rezende +Guilherme Souza <32180229+gqgs@users.noreply.github.com> Guillaume J. Charmes Guillaume Sottas Günther Noack Guobiao Mei +Guodong Li Guoliang Wang Gustav Paul Gustav Westling @@ -995,6 +1046,7 @@ HAMANO Tsukasa Han-Wen Nienhuys Hang Qian Hanjun Kim +Hanlin He Hanlin Shi Haoran Luo Haosdent Huang @@ -1026,18 +1078,19 @@ Herbie Ong Heschi Kreinick Hidetatsu Yaginuma Hilko Bengen +Himanshu Kishna Srivastava <28himanshu@gmail.com> Hiroaki Nakamura Hiromichi Ema Hironao OTSUBO Hiroshi Ioka Hitoshi Mitake Holden Huang -Songlin Jiang Hong Ruiqi Hongfei Tan Horacio Duran Horst Rutter Hossein Sheikh Attar +Hossein Zolfi Howard Zhang Hsin Tsao Hsin-Ho Yeh @@ -1054,11 +1107,14 @@ Ian Haken Ian Kent Ian Lance Taylor Ian Leue +Ian Mckay Ian Tay +Ian Woolf Ian Zapolsky Ibrahim AshShohail Icarus Sparry Iccha Sethi +Ichinose Shogo Idora Shinatose Ignacio Hagopian Igor Bernstein @@ -1068,6 +1124,7 @@ Igor Vashyst Igor Zhilianin Ikko Ashimine Illya Yalovyy +Ilya Chukov <56119080+Elias506@users.noreply.github.com> Ilya Sinelnikov Ilya Tocar INADA Naoki @@ -1122,6 +1179,7 @@ James Cowgill James Craig Burley James David Chalfant James Eady +James Fennell James Fysh James Gray James Hartig @@ -1178,6 +1236,7 @@ Jason Wangsadinata Javier Kohen Javier Revillas Javier Segura +Jay Chen Jay Conrod Jay Lee Jay Taylor @@ -1200,6 +1259,7 @@ Jeff Johnson Jeff R. Allen Jeff Sickel Jeff Wendling +Jeff Widman Jeffrey H Jelte Fennema Jens Frederich @@ -1210,6 +1270,7 @@ Jeremy Faller Jeremy Jackins Jeremy Jay Jeremy Schlatter +Jero Bado Jeroen Bobbeldijk Jeroen Simonetti Jérôme Doucet @@ -1251,6 +1312,8 @@ Joe Richey Joe Shaw Joe Sylve Joe Tsai +Joel Courtney +Joel Ferrier Joel Sing Joël Stemmer Joel Stemmer @@ -1260,7 +1323,9 @@ Johan Euphrosine Johan Jansson Johan Knutzen Johan Sageryd +Johannes Huning John Asmuth +John Bampton John Beisley John C Barstow John DeNero @@ -1269,6 +1334,7 @@ John Gibb John Gilik John Graham-Cumming John Howard Palevich +John Jago John Jeffery John Jenkins John Leidegren @@ -1320,6 +1386,7 @@ Josa Gesell Jose Luis Vázquez González Joseph Bonneau Joseph Holsten +Joseph Morag Josh Baum Josh Bleecher Snyder Josh Chorlton @@ -1327,12 +1394,14 @@ Josh Deprez Josh Goebel Josh Hoak Josh Holland +Josh Rickmar Josh Roppo Josh Varga Joshua Bezaleel Abednego Joshua Boelter Joshua Chase Joshua Crowgey +Joshua Harshman Joshua M. Clulow Joshua Rubin Josselin Costanzi @@ -1353,6 +1422,7 @@ Julie Qiu Julien Kauffmann Julien Salleyron Julien Schmidt +Julien Tant Julio Montes Jun Zhang Junchen Li @@ -1419,10 +1489,12 @@ Kenta Mori Kerollos Magdy Ketan Parmar Kevan Swanberg +Kevin Albertson Kevin Ballard Kevin Burke Kévin Dunglas Kevin Gillette +Kevin Herro Kevin Kirsche Kevin Klues Kevin Malachowski @@ -1457,6 +1529,7 @@ Koya IWAMURA Kris Kwiatkowski Kris Nova Kris Rousey +Krishna Birla Kristopher Watts Krzysztof Dąbrowski Kshitij Saraogi @@ -1480,6 +1553,7 @@ Lajos Papp Lakshay Garg Lann Martin Lanre Adelowo +Lapo Luchini Larry Clapp Larry Hosken Lars Jeppesen @@ -1496,6 +1570,7 @@ Leigh McCulloch Leo Antunes Leo Rudberg Leon Klingele +Leonard Wang Leonardo Comelli Leonel Quinteros Lev Shamardin @@ -1506,7 +1581,9 @@ Lily Chung Lingchao Xin Lion Yang Liz Rice +Lize Cai Lloyd Dewolf +Lluís Batlle i Rossell Lorenz Bauer Lorenz Brun Lorenz Nickel @@ -1531,6 +1608,7 @@ Lukasz Milewski Luke Champine Luke Curley Luke Granger-Brown +Luke Shumaker Luke Young Luna Duclos Luuk van Dijk @@ -1550,6 +1628,7 @@ Mal Curtis Manfred Touron Manigandan Dharmalingam Manish Goregaokar +Manlio Perillo Manoj Dayaram Mansour Rahimi Manu Garg @@ -1646,6 +1725,8 @@ Matt Joiner Matt Jones Matt Juran Matt Layher +Matt Masurka +Matt Pearring Matt Reiferson Matt Robenolt Matt Strong @@ -1659,9 +1740,12 @@ Matthew Denton Matthew Holt Matthew Horsnell Matthew Waters +Matthias Frei Matthieu Hauglustaine Matthieu Olivier Matthijs Kooijman +Mattias Appelgren +Mauricio Alvarado Max Drosdo.www Max Riveiro Max Schmitt @@ -1677,9 +1761,11 @@ Máximo Cuadros Ortiz Maxwell Krohn Maya Rashish Mayank Kumar +Mehrad Sadeghi <2012.linkinpark@gmail.com> Meir Fischer Meng Zhuo Mhd Sulhan +Mia Zhu Micah Stetson Michael Anthony Knyszek Michael Brandenburg @@ -1730,8 +1816,10 @@ Michal Franc Michał Łowicki Michal Pristas Michal Rostecki +Michal Stokluska Michalis Kargakis Michel Lespinasse +Michel Levieux Michele Di Pede Mickael Kerjean Mickey Reiss @@ -1790,7 +1878,9 @@ Muir Manders Mukesh Sharma Mura Li Mykhailo Lesyk +Nahum Shalman Naman Aggarwal +Naman Gera Nan Deng Nao Yonashiro Naoki Kanatani @@ -1818,6 +1908,7 @@ Neven Sajko Nevins Bartolomeo Niall Sheridan Nic Day +Nicholas Asimov Nicholas Katsaros Nicholas Maniscalco Nicholas Ng @@ -1847,6 +1938,7 @@ Nik Nyby Nikhil Benesch Nikita Gillmann Nikita Kryuchkov +Nikita Melekhin Nikita Vanyasin Niklas Schnelle Niko Dziemba @@ -1858,6 +1950,7 @@ Niranjan Godbole Nishanth Shanmugham Noah Campbell Noah Goldman +Noah Santschi-Cooney Noble Johnson Nodir Turakulov Noel Georgi @@ -1894,6 +1987,7 @@ Pablo Rozas Larraondo Pablo Santiago Blum de Aguiar Padraig Kitterick Pallat Anchaleechamaikorn +Pan Chenglong <1004907659@qq.com> Panos Georgiadis Pantelis Sampaziotis Paolo Giarrusso @@ -1947,6 +2041,7 @@ Paulo Casaretto Paulo Flabiano Smorigo Paulo Gomes Pavel Paulau +Pavel Watson Pavel Zinovkin Pavlo Sumkin Pawel Knap @@ -1954,6 +2049,8 @@ Pawel Szczur Paweł Szulik Pei Xian Chee Pei-Ming Wu +Pen Tree +Peng Gao Percy Wegmann Perry Abbott Petar Dambovaliev @@ -1992,6 +2089,7 @@ Philip Brown Philip Hofer Philip K. Warren Philip Nelson +Philipp Sauter Philipp Stephani Phillip Campbell <15082+phillc@users.noreply.github.com> Pierre Carru @@ -2007,6 +2105,7 @@ Poh Zi How Polina Osadcha Pontus Leitzler Povilas Versockas +Prajwal Koirala <16564273+Prajwal-Koirala@users.noreply.github.com> Prasanga Siripala Prasanna Swaminathan Prashant Agrawal @@ -2027,11 +2126,13 @@ Quim Muntal Quinn Slack Quinten Yearsley Quoc-Viet Nguyen +Rabin Gaire Radek Simko Radek Sohlich Radu Berinde Rafal Jeczalik Raghavendra Nagaraj +Rahul Bajaj Rahul Chaudhry Rahul Wadhwani Raif S. Naffah @@ -2041,12 +2142,14 @@ Rajender Reddy Kompally Ralph Corderoy Ramazan AYYILDIZ Ramesh Dharan +Randy Reddig Raph Levien Raphael Geronimi Raul Silvera Ravil Bikbulatov RaviTeja Pothana Ray Tung +Ray Wu Raymond Kazlauskas Rebecca Stambler Reilly Watson @@ -2066,6 +2169,7 @@ Richard Eric Gavaletz Richard Gibson Richard Miller Richard Musiol +Richard Pickering Richard Ulmer Richard Wilkes Rick Arnold @@ -2124,6 +2228,7 @@ Rowan Worth Rudi Kramer Rui Ueyama Ruixin Bao +Ruslan Andreev Ruslan Nigmatullin Russ Cox Russell Haering @@ -2141,6 +2246,7 @@ Ryan Seys Ryan Slade Ryan Zhang Ryoichi KATO +Ryoya Sekino Ryuji Iwata Ryuma Yoshida Ryuzo Yamamoto @@ -2176,8 +2282,10 @@ Sardorbek Pulatov Sascha Brawer Sasha Lionheart Sasha Sobol +Satoru Kitaguchi Scott Barron Scott Bell +Scott Cotton Scott Crunkleton Scott Ferguson Scott Lawrence @@ -2191,6 +2299,7 @@ Sean Chittenden Sean Christopherson Sean Dolphin Sean Harger +Sean Harrington Sean Hildebrand Sean Liao Sean Rees @@ -2212,6 +2321,7 @@ Sergey Dobrodey Sergey Frolov Sergey Glushchenko Sergey Ivanov +Sergey Kacheev Sergey Lukjanov Sergey Mishin Sergey Mudrik @@ -2223,6 +2333,7 @@ Serhat Giydiren Serhii Aheienko Seth Hoenig Seth Vargo +Shaba Abhiram Shahar Kohanim Shailesh Suryawanshi Shamil Garatuev @@ -2250,9 +2361,13 @@ Shivakumar GN Shivani Singhal Shivansh Rai Shivashis Padhi +Shoshin Nikita +Shota Sugiura Shubham Sharma +Shuhei Takahashi Shun Fan Silvan Jegen +Simão Gomes Viana Simarpreet Singh Simon Drake Simon Ferquel @@ -2267,13 +2382,16 @@ Sina Siadat Sjoerd Siebinga Sokolov Yura Song Gao +Song Lim Songjiayang +Songlin Jiang Soojin Nam Søren L. Hansen Sparrow Li Spencer Kocot Spencer Nelson Spencer Tung +Spenser Black Spring Mc Srdjan Petrovic Sridhar Venkatakrishnan @@ -2324,6 +2442,7 @@ Suyash Suzy Mueller Sven Almgren Sven Blumenstein +Sven Lee Sven Taute Sylvain Zimmer Syohei YOSHIDA @@ -2406,12 +2525,14 @@ Tiwei Bie Tobias Assarsson Tobias Columbus Tobias Klauser +Tobias Kohlbau Toby Burress Todd Kulesza Todd Neal Todd Wang Tom Anthony Tom Bergan +Tom Freudenberg Tom Heng Tom Lanyon Tom Levy @@ -2440,6 +2561,7 @@ Toshiki Shima Totoro W Travis Bischel Travis Cline +Trevor Dixon Trevor Strohman Trey Lawrence Trey Roessig @@ -2463,6 +2585,7 @@ Tzach Shabtay Tzu-Chiao Yeh Tzu-Jung Lee Udalov Max +Uddeshya Singh Ugorji Nwoke Ulf Holm Nielsen Ulrich Kunitz @@ -2475,6 +2598,7 @@ Vadim Grek Vadim Vygonets Val Polouchkine Valentin Vidic +Vaughn Iverson Vee Zhang Vega Garcia Luis Alfonso Venil Noronha @@ -2491,6 +2615,7 @@ Vincent Batts Vincent Vanackere Vinu Rajashekhar Vish Subramanian +Vishal Dalwadi Vishvananda Ishaya Visweswara R Vitaly Zdanevich @@ -2542,6 +2667,7 @@ Willem van der Schyff William Chan William Chang William Josephson +William Langford William Orr William Poussier Wisdom Omuya @@ -2550,6 +2676,7 @@ Xi Ruoyao Xia Bin Xiangdong Ji Xiaodong Liu +Xing Gao <18340825824@163.com> Xing Xing Xingqang Bai Xu Fei @@ -2571,6 +2698,7 @@ Yasha Bubnov Yasser Abdolmaleki Yasuharu Goto Yasuhiro Matsumoto +Yasutaka Shinzaki Yasuyuki Oka Yazen Shunnar Yestin Sun @@ -2583,14 +2711,18 @@ Yorman Arias Yoshiyuki Kanno Yoshiyuki Mineo Yosuke Akatsuka +Youfu Zhang Yu Heng Zhang Yu Xuan Zhang +Yu, Li-Yu Yuichi Kishimoto Yuichi Nishiwaki Yuji Yaginuma +Yuki Ito Yuki OKUSHI Yuki Yugui Sonoda Yukihiro Nishinaka <6elpinal@gmail.com> +YunQiang Su Yury Smolsky Yusuke Kagiwada Yuusei Kuwana @@ -2599,6 +2731,7 @@ Yves Junqueira Zac Bergquist Zach Bintliff Zach Gershman +Zach Hoffman Zach Jones Zachary Amsden Zachary Gershman @@ -2617,6 +2750,7 @@ Zhou Peng Ziad Hatahet Ziheng Liu Zorion Arrizabalaga +Zvonimir Pavlinovic Zyad A. Ali Максадбек Ахмедов Максим Федосеев diff --git a/doc/asm.html b/doc/asm.html index d578800086..51f85eb948 100644 --- a/doc/asm.html +++ b/doc/asm.html @@ -166,7 +166,7 @@ jumps and branches.
  • -SP: Stack pointer: top of stack. +SP: Stack pointer: the highest address within the local stack frame.
  • @@ -216,7 +216,7 @@ If a Go prototype does not name its result, the expected assembly name is The SP pseudo-register is a virtual stack pointer used to refer to frame-local variables and the arguments being prepared for function calls. -It points to the top of the local stack frame, so references should use negative offsets +It points to the highest address within the local stack frame, so references should use negative offsets in the range [−framesize, 0): x-8(SP), y-4(SP), and so on.

    @@ -409,7 +409,7 @@ The linker will choose one of the duplicates to use. (For TEXT items.) Don't insert the preamble to check if the stack must be split. The frame for the routine, plus anything it calls, must fit in the -spare space at the top of the stack segment. +spare space remaining in the current stack segment. Used to protect routines such as the stack splitting code itself.
  • @@ -460,7 +460,7 @@ Only valid on functions that declare a frame size of 0. TOPFRAME = 2048
    (For TEXT items.) -Function is the top of the call stack. Traceback should stop at this function. +Function is the outermost frame of the call stack. Traceback should stop at this function.
  • diff --git a/doc/go1.17.html b/doc/go1.17.html index 48811e6b67..b65d13a040 100644 --- a/doc/go1.17.html +++ b/doc/go1.17.html @@ -14,13 +14,13 @@ Do not send CLs removing the interior tags from such phrases. main ul li { margin: 0.5em 0; } -

    DRAFT RELEASE NOTES — Introduction to Go 1.17

    +

    Introduction to Go 1.17

    - - Go 1.17 is not yet released. These are work-in-progress - release notes. Go 1.17 is expected to be released in August 2021. - + The latest Go release, version 1.17, arrives six months after Go 1.16. + Most of its changes are in the implementation of the toolchain, runtime, and libraries. + As always, the release maintains the Go 1 promise of compatibility. + We expect almost all Go programs to continue to compile and run as before.

    Changes to the language

    @@ -134,35 +134,54 @@ Do not send CLs removing the interior tags from such phrases.

    Go command

    -

    Lazy module loading

    + +

    Pruned module graphs in go 1.17 modules

    + If a module specifies go 1.17 or higher, the module + graph includes only the immediate dependencies of + other go 1.17 modules, not their full transitive + dependencies. (See Module graph pruning + for more detail.) +

    + +

    + For the go command to correctly resolve transitive imports using + the pruned module graph, the go.mod file for each module needs to + include more detail about the transitive dependencies relevant to that module. If a module specifies go 1.17 or higher in its - go.mod file, its transitive requirements are now loaded lazily, - avoiding the need to download or read go.mod files for - otherwise-irrelevant dependencies. To support lazy loading, in Go 1.17 modules - the go command maintains explicit requirements in - the go.mod file for every dependency that provides any package - transitively imported by any package or test within the module. - See the design - document for more detail. - + go.mod file, its go.mod file now contains an + explicit require + directive for every module that provides a transitively-imported package. + (In previous versions, the go.mod file typically only included + explicit requirements for directly-imported packages.) +

    + +

    + Since the expanded go.mod file needed for module graph pruning + includes all of the dependencies needed to load the imports of any package in + the main module, if the main module specifies + go 1.17 or higher the go tool no longer + reads (or even downloads) go.mod files for dependencies if they + are not needed in order to complete the requested command. + (See Lazy loading.)

    - Because the number of additional explicit requirements in the go.mod file may - be substantial, in a Go 1.17 module the newly-added requirements - on indirect dependencies are maintained in a - separate require block from the block containing direct - dependencies. + Because the number of explicit requirements may be substantially larger in an + expanded Go 1.17 go.mod file, the newly-added requirements + on indirect dependencies in a go 1.17 + module are maintained in a separate require block from the block + containing direct dependencies.

    - To facilitate the upgrade to lazy loading, the - go mod tidy subcommand now supports - a -go flag to set or change the go version in - the go.mod file. To enable lazy loading for an existing module - without changing the selected versions of its dependencies, run: + To facilitate the upgrade to Go 1.17 pruned module graphs, the + go mod tidy + subcommand now supports a -go flag to set or change + the go version in the go.mod file. To convert + the go.mod file for an existing module to Go 1.17 without + changing the selected versions of its dependencies, run:

    @@ -199,10 +218,10 @@ Do not send CLs removing the interior tags from such phrases.
     

    - The go mod graph subcommand also - supports the -go flag, which causes it to report the graph as - seen by the indicated Go version, showing dependencies that may otherwise be - pruned out by lazy loading. + The go mod graph + subcommand also supports the -go flag, which causes it to report + the graph as seen by the indicated Go version, showing dependencies that may + otherwise be pruned out.

    Module deprecation comments

    @@ -270,7 +289,8 @@ Do not send CLs removing the interior tags from such phrases.

    If the main module specifies go 1.17 or higher, - go mod vendor now annotates + go mod vendor + now annotates vendor/modules.txt with the go version indicated by each vendored module in its own go.mod file. The annotated version is used when building the module's packages from vendored source code. @@ -468,6 +488,15 @@ func Foo() bool { and compare functions by code pointer.

    + + +

    + When the linker uses external linking mode, which is the default + when linking a program that uses cgo, and the linker is invoked + with a -I option, the option will now be passed to the + external linker as a -Wl,--dynamic-linker option. +

    +

    Core library

    Cgo

    diff --git a/doc/go_spec.html b/doc/go_spec.html index 0e14a1f3b6..fd5fee46eb 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -4329,6 +4329,7 @@ a run-time panic occurs.
     s := make([]byte, 2, 4)
     s0 := (*[0]byte)(s)      // s0 != nil
    +s1 := (*[1]byte)(s[1:])  // &s1[0] == &s[1]
     s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
     s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)
     
    diff --git a/misc/cgo/testsanitizers/msan_test.go b/misc/cgo/testsanitizers/msan_test.go
    index 2a3494fbfc..5ee9947a58 100644
    --- a/misc/cgo/testsanitizers/msan_test.go
    +++ b/misc/cgo/testsanitizers/msan_test.go
    @@ -42,6 +42,7 @@ func TestMSAN(t *testing.T) {
     		{src: "msan5.go"},
     		{src: "msan6.go"},
     		{src: "msan7.go"},
    +		{src: "msan8.go"},
     		{src: "msan_fail.go", wantErr: true},
     	}
     	for _, tc := range cases {
    diff --git a/misc/cgo/testsanitizers/testdata/msan8.go b/misc/cgo/testsanitizers/testdata/msan8.go
    new file mode 100644
    index 0000000000..1cb5c5677f
    --- /dev/null
    +++ b/misc/cgo/testsanitizers/testdata/msan8.go
    @@ -0,0 +1,109 @@
    +// Copyright 2021 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
    +package main
    +
    +/*
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +// cgoTracebackArg is the type of the argument passed to msanGoTraceback.
    +struct cgoTracebackArg {
    +	uintptr_t context;
    +	uintptr_t sigContext;
    +	uintptr_t* buf;
    +	uintptr_t max;
    +};
    +
    +// msanGoTraceback is registered as the cgo traceback function.
    +// This will be called when a signal occurs.
    +void msanGoTraceback(void* parg) {
    +	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
    +        arg->buf[0] = 0;
    +}
    +
    +// msanGoWait will be called with all registers undefined as far as
    +// msan is concerned. It just waits for a signal.
    +// Because the registers are msan-undefined, the signal handler will
    +// be invoked with all registers msan-undefined.
    +__attribute__((noinline))
    +void msanGoWait(unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6) {
    +	sigset_t mask;
    +
    +	sigemptyset(&mask);
    +        sigsuspend(&mask);
    +}
    +
    +// msanGoSignalThread is the thread ID of the msanGoLoop thread.
    +static pthread_t msanGoSignalThread;
    +
    +// msanGoSignalThreadSet is used to record that msanGoSignalThread
    +// has been initialized. This is accessed atomically.
    +static int32_t msanGoSignalThreadSet;
    +
    +// uninit is explicitly poisoned, so that we can make all registers
    +// undefined by calling msanGoWait.
    +static unsigned long uninit;
    +
    +// msanGoLoop loops calling msanGoWait, with the arguments passed
    +// such that msan thinks that they are undefined. msan permits
    +// undefined values to be used as long as they are not used to
    +// for conditionals or for memory access.
    +void msanGoLoop() {
    +	int i;
    +
    +	msanGoSignalThread = pthread_self();
    +        __atomic_store_n(&msanGoSignalThreadSet, 1, __ATOMIC_SEQ_CST);
    +
    +	// Force uninit to be undefined for msan.
    +	__msan_poison(&uninit, sizeof uninit);
    +	for (i = 0; i < 100; i++) {
    +		msanGoWait(uninit, uninit, uninit, uninit, uninit, uninit);
    +        }
    +}
    +
    +// msanGoReady returns whether msanGoSignalThread is set.
    +int msanGoReady() {
    +	return __atomic_load_n(&msanGoSignalThreadSet, __ATOMIC_SEQ_CST) != 0;
    +}
    +
    +// msanGoSendSignal sends a signal to the msanGoLoop thread.
    +void msanGoSendSignal() {
    +	pthread_kill(msanGoSignalThread, SIGWINCH);
    +}
    +*/
    +import "C"
    +
    +import (
    +	"runtime"
    +	"time"
    +)
    +
    +func main() {
    +	runtime.SetCgoTraceback(0, C.msanGoTraceback, nil, nil)
    +
    +	c := make(chan bool)
    +	go func() {
    +		defer func() { c <- true }()
    +		C.msanGoLoop()
    +	}()
    +
    +	for C.msanGoReady() == 0 {
    +		time.Sleep(time.Microsecond)
    +	}
    +
    +loop:
    +	for {
    +		select {
    +		case <-c:
    +			break loop
    +		default:
    +			C.msanGoSendSignal()
    +			time.Sleep(time.Microsecond)
    +		}
    +	}
    +}
    diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
    index 1abb03bcc5..bec17696f3 100644
    --- a/src/cmd/dist/build.go
    +++ b/src/cmd/dist/build.go
    @@ -1263,14 +1263,19 @@ func cmdbootstrap() {
     	timelog("start", "dist bootstrap")
     	defer timelog("end", "dist bootstrap")
     
    -	var noBanner bool
    +	var noBanner, noClean bool
     	var debug bool
     	flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
     	flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process")
     	flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner")
    +	flag.BoolVar(&noClean, "no-clean", noClean, "print deprecation warning")
     
     	xflagparse(0)
     
    +	if noClean {
    +		xprintf("warning: --no-clean is deprecated and has no effect; use 'go install std cmd' instead\n")
    +	}
    +
     	// Set GOPATH to an internal directory. We shouldn't actually
     	// need to store files here, since the toolchain won't
     	// depend on modules outside of vendor directories, but if
    diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
    index 954caae9fb..7f88d3216c 100644
    --- a/src/cmd/go/alldocs.go
    +++ b/src/cmd/go/alldocs.go
    @@ -1078,7 +1078,7 @@
     //
     // Usage:
     //
    -// 	go mod edit [editing flags] [go.mod]
    +// 	go mod edit [editing flags] [-fmt|-print|-json] [go.mod]
     //
     // Edit provides a command-line interface for editing go.mod,
     // for use primarily by tools or scripts. It reads only go.mod;
    @@ -1204,7 +1204,7 @@
     //
     // Usage:
     //
    -// 	go mod init [module]
    +// 	go mod init [module-path]
     //
     // Init initializes and writes a new go.mod file in the current directory, in
     // effect creating a new module rooted at the current directory. The go.mod file
    diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go
    index e856e7c630..bb3d521092 100644
    --- a/src/cmd/go/internal/modcmd/edit.go
    +++ b/src/cmd/go/internal/modcmd/edit.go
    @@ -25,7 +25,7 @@ import (
     )
     
     var cmdEdit = &base.Command{
    -	UsageLine: "go mod edit [editing flags] [go.mod]",
    +	UsageLine: "go mod edit [editing flags] [-fmt|-print|-json] [go.mod]",
     	Short:     "edit go.mod from tools or scripts",
     	Long: `
     Edit provides a command-line interface for editing go.mod,
    diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
    index 73cc282d81..958c3066ac 100644
    --- a/src/cmd/go/internal/modcmd/init.go
    +++ b/src/cmd/go/internal/modcmd/init.go
    @@ -13,7 +13,7 @@ import (
     )
     
     var cmdInit = &base.Command{
    -	UsageLine: "go mod init [module]",
    +	UsageLine: "go mod init [module-path]",
     	Short:     "initialize new module in current directory",
     	Long: `
     Init initializes and writes a new go.mod file in the current directory, in
    diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
    index f817a04583..dfef9f73c2 100644
    --- a/src/cmd/go/internal/modfetch/coderepo.go
    +++ b/src/cmd/go/internal/modfetch/coderepo.go
    @@ -864,22 +864,25 @@ func (r *codeRepo) GoMod(version string) (data []byte, err error) {
     	data, err = r.code.ReadFile(rev, path.Join(dir, "go.mod"), codehost.MaxGoMod)
     	if err != nil {
     		if os.IsNotExist(err) {
    -			return r.legacyGoMod(rev, dir), nil
    +			return LegacyGoMod(r.modPath), nil
     		}
     		return nil, err
     	}
     	return data, nil
     }
     
    -func (r *codeRepo) legacyGoMod(rev, dir string) []byte {
    -	// We used to try to build a go.mod reflecting pre-existing
    -	// package management metadata files, but the conversion
    -	// was inherently imperfect (because those files don't have
    -	// exactly the same semantics as go.mod) and, when done
    -	// for dependencies in the middle of a build, impossible to
    -	// correct. So we stopped.
    -	// Return a fake go.mod that simply declares the module path.
    -	return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(r.modPath)))
    +// LegacyGoMod generates a fake go.mod file for a module that doesn't have one.
    +// The go.mod file contains a module directive and nothing else: no go version,
    +// no requirements.
    +//
    +// We used to try to build a go.mod reflecting pre-existing
    +// package management metadata files, but the conversion
    +// was inherently imperfect (because those files don't have
    +// exactly the same semantics as go.mod) and, when done
    +// for dependencies in the middle of a build, impossible to
    +// correct. So we stopped.
    +func LegacyGoMod(modPath string) []byte {
    +	return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath)))
     }
     
     func (r *codeRepo) modPrefix(rev string) string {
    diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
    index 604a57b437..bf69567316 100644
    --- a/src/cmd/go/internal/modload/buildlist.go
    +++ b/src/cmd/go/internal/modload/buildlist.go
    @@ -191,6 +191,19 @@ func (rs *Requirements) rootSelected(path string) (version string, ok bool) {
     	return "", false
     }
     
    +// hasRedundantRoot returns true if the root list contains multiple requirements
    +// of the same module or a requirement on any version of the main module.
    +// Redundant requirements should be pruned, but they may influence version
    +// selection.
    +func (rs *Requirements) hasRedundantRoot() bool {
    +	for i, m := range rs.rootModules {
    +		if m.Path == Target.Path || (i > 0 && m.Path == rs.rootModules[i-1].Path) {
    +			return true
    +		}
    +	}
    +	return false
    +}
    +
     // Graph returns the graph of module requirements loaded from the current
     // root modules (as reported by RootModules).
     //
    @@ -882,6 +895,12 @@ func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requiremen
     		// and (trivially) version.
     
     		if !rootsUpgraded {
    +			if cfg.BuildMod != "mod" {
    +				// The only changes to the root set (if any) were to remove duplicates.
    +				// The requirements are consistent (if perhaps redundant), so keep the
    +				// original rs to preserve its ModuleGraph.
    +				return rs, nil
    +			}
     			// The root set has converged: every root going into this iteration was
     			// already at its selected version, although we have have removed other
     			// (redundant) roots for the same path.
    diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
    index a8cbd9fe16..45f724d5e3 100644
    --- a/src/cmd/go/internal/modload/init.go
    +++ b/src/cmd/go/internal/modload/init.go
    @@ -449,13 +449,22 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
     	}
     
     	setDefaultBuildMod() // possibly enable automatic vendoring
    -	rs = requirementsFromModFile(ctx)
    -
    +	rs = requirementsFromModFile()
     	if cfg.BuildMod == "vendor" {
     		readVendorList()
     		checkVendorConsistency()
     		rs.initVendor(vendorList)
     	}
    +	if rs.hasRedundantRoot() {
    +		// If any module path appears more than once in the roots, we know that the
    +		// go.mod file needs to be updated even though we have not yet loaded any
    +		// transitive dependencies.
    +		rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
    +		if err != nil {
    +			base.Fatalf("go: %v", err)
    +		}
    +	}
    +
     	if index.goVersionV == "" {
     		// TODO(#45551): Do something more principled instead of checking
     		// cfg.CmdName directly here.
    @@ -530,7 +539,12 @@ func CreateModFile(ctx context.Context, modPath string) {
     		base.Fatalf("go: %v", err)
     	}
     
    -	commitRequirements(ctx, modFileGoVersion(), requirementsFromModFile(ctx))
    +	rs := requirementsFromModFile()
    +	rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
    +	if err != nil {
    +		base.Fatalf("go: %v", err)
    +	}
    +	commitRequirements(ctx, modFileGoVersion(), rs)
     
     	// Suggest running 'go mod tidy' unless the project is empty. Even if we
     	// imported all the correct requirements above, we're probably missing
    @@ -641,9 +655,8 @@ func initTarget(m module.Version) {
     
     // requirementsFromModFile returns the set of non-excluded requirements from
     // the global modFile.
    -func requirementsFromModFile(ctx context.Context) *Requirements {
    +func requirementsFromModFile() *Requirements {
     	roots := make([]module.Version, 0, len(modFile.Require))
    -	mPathCount := map[string]int{Target.Path: 1}
     	direct := map[string]bool{}
     	for _, r := range modFile.Require {
     		if index != nil && index.exclude[r.Mod] {
    @@ -656,28 +669,12 @@ func requirementsFromModFile(ctx context.Context) *Requirements {
     		}
     
     		roots = append(roots, r.Mod)
    -		mPathCount[r.Mod.Path]++
     		if !r.Indirect {
     			direct[r.Mod.Path] = true
     		}
     	}
     	module.Sort(roots)
     	rs := newRequirements(modDepthFromGoVersion(modFileGoVersion()), roots, direct)
    -
    -	// If any module path appears more than once in the roots, we know that the
    -	// go.mod file needs to be updated even though we have not yet loaded any
    -	// transitive dependencies.
    -	for _, n := range mPathCount {
    -		if n > 1 {
    -			var err error
    -			rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
    -			if err != nil {
    -				base.Fatalf("go: %v", err)
    -			}
    -			break
    -		}
    -	}
    -
     	return rs
     }
     
    diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
    index d280945ea6..03e02e73b6 100644
    --- a/src/cmd/go/internal/modload/modfile.go
    +++ b/src/cmd/go/internal/modload/modfile.go
    @@ -595,47 +595,14 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
     	}
     	c := rawGoModSummaryCache.Do(m, func() interface{} {
     		summary := new(modFileSummary)
    -		var f *modfile.File
    -		if m.Version == "" {
    -			// m is a replacement module with only a file path.
    -			dir := m.Path
    -			if !filepath.IsAbs(dir) {
    -				dir = filepath.Join(ModRoot(), dir)
    -			}
    -			gomod := filepath.Join(dir, "go.mod")
    -			var data []byte
    -			var err error
    -			if gomodActual, ok := fsys.OverlayPath(gomod); ok {
    -				// Don't lock go.mod if it's part of the overlay.
    -				// On Plan 9, locking requires chmod, and we don't want to modify any file
    -				// in the overlay. See #44700.
    -				data, err = os.ReadFile(gomodActual)
    -			} else {
    -				data, err = lockedfile.Read(gomodActual)
    -			}
    -			if err != nil {
    -				return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
    -			}
    -			f, err = modfile.ParseLax(gomod, data, nil)
    -			if err != nil {
    -				return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))}
    -			}
    -		} else {
    -			if !semver.IsValid(m.Version) {
    -				// Disallow the broader queries supported by fetch.Lookup.
    -				base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
    -			}
    -
    -			data, err := modfetch.GoMod(m.Path, m.Version)
    -			if err != nil {
    -				return cached{nil, err}
    -			}
    -			f, err = modfile.ParseLax("go.mod", data, nil)
    -			if err != nil {
    -				return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))}
    -			}
    +		name, data, err := rawGoModData(m)
    +		if err != nil {
    +			return cached{nil, err}
    +		}
    +		f, err := modfile.ParseLax(name, data, nil)
    +		if err != nil {
    +			return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(name), err))}
     		}
    -
     		if f.Module != nil {
     			summary.module = f.Module.Mod
     			summary.deprecated = f.Module.Deprecated
    @@ -671,6 +638,43 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
     
     var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result
     
    +// rawGoModData returns the content of the go.mod file for module m, ignoring
    +// all replacements that may apply to m.
    +//
    +// rawGoModData cannot be used on the Target module.
    +//
    +// Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
    +// Use rawGoModSummary instead unless you specifically need these bytes.
    +func rawGoModData(m module.Version) (name string, data []byte, err error) {
    +	if m.Version == "" {
    +		// m is a replacement module with only a file path.
    +		dir := m.Path
    +		if !filepath.IsAbs(dir) {
    +			dir = filepath.Join(ModRoot(), dir)
    +		}
    +		name = filepath.Join(dir, "go.mod")
    +		if gomodActual, ok := fsys.OverlayPath(name); ok {
    +			// Don't lock go.mod if it's part of the overlay.
    +			// On Plan 9, locking requires chmod, and we don't want to modify any file
    +			// in the overlay. See #44700.
    +			data, err = os.ReadFile(gomodActual)
    +		} else {
    +			data, err = lockedfile.Read(gomodActual)
    +		}
    +		if err != nil {
    +			return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err))
    +		}
    +	} else {
    +		if !semver.IsValid(m.Version) {
    +			// Disallow the broader queries supported by fetch.Lookup.
    +			base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
    +		}
    +		name = "go.mod"
    +		data, err = modfetch.GoMod(m.Path, m.Version)
    +	}
    +	return name, data, err
    +}
    +
     // queryLatestVersionIgnoringRetractions looks up the latest version of the
     // module with the given path without considering retracted or excluded
     // versions.
    diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
    index dda9004a9f..e737ca90fc 100644
    --- a/src/cmd/go/internal/modload/query.go
    +++ b/src/cmd/go/internal/modload/query.go
    @@ -5,13 +5,13 @@
     package modload
     
     import (
    +	"bytes"
     	"context"
     	"errors"
     	"fmt"
     	"io/fs"
     	"os"
     	pathpkg "path"
    -	"path/filepath"
     	"sort"
     	"strings"
     	"sync"
    @@ -931,14 +931,32 @@ func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
     	return ok, err
     }
     
    -func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) {
    -	needSum := false
    -	root, _, err := fetch(ctx, m, needSum)
    +// versionHasGoMod returns whether a version has a go.mod file.
    +//
    +// versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
    +// contains anything other than a module directive with the same path. When a
    +// module does not have a real go.mod file, the go command acts as if it had one
    +// that only contained a module directive. Normal go.mod files created after
    +// 1.12 at least have a go directive.
    +//
    +// This function is a heuristic, since it's possible to commit a file that would
    +// pass this test. However, we only need a heurstic for determining whether
    +// +incompatible versions may be "latest", which is what this function is used
    +// for.
    +//
    +// This heuristic is useful for two reasons: first, when using a proxy,
    +// this lets us fetch from the .mod endpoint which is much faster than the .zip
    +// endpoint. The .mod file is used anyway, even if the .zip file contains a
    +// go.mod with different content. Second, if we don't fetch the .zip, then
    +// we don't need to verify it in go.sum. This makes 'go list -m -u' faster
    +// and simpler.
    +func versionHasGoMod(_ context.Context, m module.Version) (bool, error) {
    +	_, data, err := rawGoModData(m)
     	if err != nil {
     		return false, err
     	}
    -	fi, err := os.Stat(filepath.Join(root, "go.mod"))
    -	return err == nil && !fi.IsDir(), nil
    +	isFake := bytes.Equal(data, modfetch.LegacyGoMod(m.Path))
    +	return !isFake, nil
     }
     
     // A versionRepo is a subset of modfetch.Repo that can report information about
    diff --git a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
    index ffcea18603..9abbabd2eb 100644
    --- a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
    +++ b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
    @@ -2,18 +2,13 @@
     # 'go mod tidy' should not panic if the main module initially
     # requires an older version of itself.
     
    +# A module may require an older version of itself without error. This is
    +# inconsistent (the required version is never selected), but we still get
    +# a reproducible build list.
    +go list -m all
    +stdout '^golang.org/issue/46078$'
     
    -# A module that explicitly requires an older version of itself should be
    -# rejected as inconsistent: we enforce that every explicit requirement is the
    -# selected version of its module path, but the selected version of the main
    -# module is always itself — not some explicit version.
    -
    -! go list -m all
    -stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
    -
    -
    -# The suggested 'go mod tidy' command should succeed (not crash).
    -
    +# 'go mod tidy' should fix this (and not crash).
     go mod tidy
     
     
    diff --git a/src/cmd/go/testdata/script/mod_update_sum_readonly.txt b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
    new file mode 100644
    index 0000000000..41f12e4084
    --- /dev/null
    +++ b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
    @@ -0,0 +1,34 @@
    +# When finding the latest version of a module, we should not download version
    +# contents. Previously, we downloaded .zip files to determine whether a real
    +# .mod file was present in order to decide whether +incompatible versions
    +# could be "latest".
    +#
    +# Verifies #47377.
    +
    +# rsc.io/breaker has two versions, neither of which has a .mod file.
    +go list -m -versions rsc.io/breaker
    +stdout '^rsc.io/breaker v1.0.0 v2.0.0\+incompatible$'
    +go mod download rsc.io/breaker@v1.0.0
    +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.mod
    +go mod download rsc.io/breaker@v2.0.0+incompatible
    +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.mod
    +
    +# Delete downloaded .zip files.
    +go clean -modcache
    +
    +# Check for updates.
    +go list -m -u rsc.io/breaker
    +stdout '^rsc.io/breaker v1.0.0 \[v2.0.0\+incompatible\]$'
    +
    +# We should not have downloaded zips.
    +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.zip
    +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.zip
    +
    +-- go.mod --
    +module m
    +
    +go 1.16
    +
    +require rsc.io/breaker v1.0.0
    +-- go.sum --
    +rsc.io/breaker v1.0.0/go.mod h1:s5yxDXvD88U1/ESC23I2FK3Lkv4YIKaB1ij/Hbm805g=
    diff --git a/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
    new file mode 100644
    index 0000000000..3f6f5c5276
    --- /dev/null
    +++ b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
    @@ -0,0 +1,29 @@
    +# 'go list -mod=vendor' should succeed even when go.mod contains redundant
    +# requirements. Verifies #47565.
    +go list -mod=vendor
    +
    +-- go.mod --
    +module m
    +
    +go 1.17
    +
    +require example.com/m v0.0.0
    +require example.com/m v0.0.0
    +
    +replace example.com/m v0.0.0 => ./m
    +-- m/go.mod --
    +module example.com/m
    +
    +go 1.17
    +-- m/m.go --
    +package m
    +-- use.go --
    +package use
    +
    +import _ "example.com/m"
    +-- vendor/example.com/m/m.go --
    +package m
    +-- vendor/modules.txt --
    +# example.com/m v0.0.0 => ./m
    +## explicit; go 1.17
    +example.com/m
    diff --git a/src/cmd/internal/obj/textflag.go b/src/cmd/internal/obj/textflag.go
    index 881e192203..5ae75027c2 100644
    --- a/src/cmd/internal/obj/textflag.go
    +++ b/src/cmd/internal/obj/textflag.go
    @@ -49,8 +49,8 @@ const (
     	// Function can call reflect.Type.Method or reflect.Type.MethodByName.
     	REFLECTMETHOD = 1024
     
    -	// Function is the top of the call stack. Call stack unwinders should stop
    -	// at this function.
    +	// Function is the outermost frame of the call stack. Call stack unwinders
    +	// should stop at this function.
     	TOPFRAME = 2048
     
     	// Function is an ABI wrapper.
    diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
    index a33bba2466..7da8606ece 100644
    --- a/src/cmd/vet/main.go
    +++ b/src/cmd/vet/main.go
    @@ -1,3 +1,7 @@
    +// Copyright 2012 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
     package main
     
     import (
    diff --git a/src/cmd/vet/testdata/copylock/copylock.go b/src/cmd/vet/testdata/copylock/copylock.go
    index 8079cf3248..7cfafe6408 100644
    --- a/src/cmd/vet/testdata/copylock/copylock.go
    +++ b/src/cmd/vet/testdata/copylock/copylock.go
    @@ -1,3 +1,7 @@
    +// Copyright 2018 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
     package copylock
     
     import "sync"
    diff --git a/src/cmd/vet/testdata/httpresponse/httpresponse.go b/src/cmd/vet/testdata/httpresponse/httpresponse.go
    index 6141f6e06d..98e394a271 100644
    --- a/src/cmd/vet/testdata/httpresponse/httpresponse.go
    +++ b/src/cmd/vet/testdata/httpresponse/httpresponse.go
    @@ -1,3 +1,7 @@
    +// Copyright 2018 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
     package httpresponse
     
     import (
    diff --git a/src/cmd/vet/testdata/testingpkg/tests.go b/src/cmd/vet/testdata/testingpkg/tests.go
    index 69d29d3c6c..8f4674d33c 100644
    --- a/src/cmd/vet/testdata/testingpkg/tests.go
    +++ b/src/cmd/vet/testdata/testingpkg/tests.go
    @@ -1 +1,5 @@
    +// Copyright 2018 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
     package testdata
    diff --git a/src/cmd/vet/testdata/testingpkg/tests_test.go b/src/cmd/vet/testdata/testingpkg/tests_test.go
    index 09bb98d980..815dcc8a95 100644
    --- a/src/cmd/vet/testdata/testingpkg/tests_test.go
    +++ b/src/cmd/vet/testdata/testingpkg/tests_test.go
    @@ -1,3 +1,7 @@
    +// Copyright 2018 The Go Authors. All rights reserved.
    +// Use of this source code is governed by a BSD-style
    +// license that can be found in the LICENSE file.
    +
     package testdata
     
     func Example_BadSuffix() {} // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix"
    diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
    index 44dc8e8caf..8fe583939f 100644
    --- a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
    +++ b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
    @@ -1,5 +1,6 @@
     // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
     
    +//go:build amd64 && gc && !purego
     // +build amd64,gc,!purego
     
     package field
    diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
    index b2d532c4c8..f138af5fbf 100644
    --- a/src/go/types/api_test.go
    +++ b/src/go/types/api_test.go
    @@ -322,6 +322,18 @@ func TestTypesInfo(t *testing.T) {
     			`[][]struct{}`,
     		},
     
    +		// issue 47243
    +		{`package issue47243_a; var x int32; var _ = x << 3`, `3`, `untyped int`},
    +		{`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `uint`}, // issue 47410: should be untyped float
    +		{`package issue47243_c; var x int32; var _ = 1 << x`, `1 << x`, `int`},
    +		{`package issue47243_d; var x int32; var _ = 1 << x`, `1`, `int`},
    +		{`package issue47243_e; var x int32; var _ = 1 << 2`, `1`, `untyped int`},
    +		{`package issue47243_f; var x int32; var _ = 1 << 2`, `2`, `untyped int`},
    +		{`package issue47243_g; var x int32; var _ = int(1) << 2`, `2`, `untyped int`},
    +		{`package issue47243_h; var x int32; var _ = 1 << (2 << x)`, `1`, `int`},
    +		{`package issue47243_i; var x int32; var _ = 1 << (2 << x)`, `(2 << x)`, `untyped int`},
    +		{`package issue47243_j; var x int32; var _ = 1 << (2 << x)`, `2`, `untyped int`},
    +
     		// tests for broken code that doesn't parse or type-check
     		{broken + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
     		{broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
    diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
    index 692004facf..8c8452c9c6 100644
    --- a/src/go/types/check_test.go
    +++ b/src/go/types/check_test.go
    @@ -354,6 +354,13 @@ func TestIndexRepresentability(t *testing.T) {
     	testFiles(t, &StdSizes{4, 4}, []string{"index.go"}, [][]byte{[]byte(src)}, false, nil)
     }
     
    +func TestIssue47243_TypedRHS(t *testing.T) {
    +	// The RHS of the shift expression below overflows uint on 32bit platforms,
    +	// but this is OK as it is explicitly typed.
    +	const src = "package issue47243\n\nvar a uint64; var _ = a << uint64(4294967296)" // uint64(1<<32)
    +	testFiles(t, &StdSizes{4, 4}, []string{"p.go"}, [][]byte{[]byte(src)}, false, nil)
    +}
    +
     func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", false) }
     func TestExamples(t *testing.T)  { testDirFiles(t, "testdata/examples", false) }
     func TestFixedbugs(t *testing.T) { testDirFiles(t, "testdata/fixedbugs", false) }
    diff --git a/src/go/types/expr.go b/src/go/types/expr.go
    index b55f51185f..c9a55aa871 100644
    --- a/src/go/types/expr.go
    +++ b/src/go/types/expr.go
    @@ -795,32 +795,48 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
     	// spec: "The right operand in a shift expression must have integer type
     	// or be an untyped constant representable by a value of type uint."
     
    -	// Provide a good error message for negative shift counts.
    +	// Check that constants are representable by uint, but do not convert them
    +	// (see also issue #47243).
     	if y.mode == constant_ {
    +		// Provide a good error message for negative shift counts.
     		yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
     		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
     			check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y)
     			x.mode = invalid
     			return
     		}
    +
    +		if isUntyped(y.typ) {
    +			// Caution: Check for representability here, rather than in the switch
    +			// below, because isInteger includes untyped integers (was bug #43697).
    +			check.representable(y, Typ[Uint])
    +			if y.mode == invalid {
    +				x.mode = invalid
    +				return
    +			}
    +		}
     	}
     
    -	// Caution: Check for isUntyped first because isInteger includes untyped
    -	//          integers (was bug #43697).
    -	if isUntyped(y.typ) {
    +	// Check that RHS is otherwise at least of integer type.
    +	switch {
    +	case isInteger(y.typ):
    +		if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
    +			check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
    +			x.mode = invalid
    +			return
    +		}
    +	case isUntyped(y.typ):
    +		// This is incorrect, but preserves pre-existing behavior.
    +		// See also bug #47410.
     		check.convertUntyped(y, Typ[Uint])
     		if y.mode == invalid {
     			x.mode = invalid
     			return
     		}
    -	} else if !isInteger(y.typ) {
    +	default:
     		check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
     		x.mode = invalid
     		return
    -	} else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
    -		check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
    -		x.mode = invalid
    -		return
     	}
     
     	if x.mode == constant_ {
    diff --git a/src/io/fs/fs.go b/src/io/fs/fs.go
    index e1be32478e..e603afadb0 100644
    --- a/src/io/fs/fs.go
    +++ b/src/io/fs/fs.go
    @@ -86,7 +86,7 @@ type File interface {
     type DirEntry interface {
     	// Name returns the name of the file (or subdirectory) described by the entry.
     	// This name is only the final element of the path (the base name), not the entire path.
    -	// For example, Name would return "hello.go" not "/home/gopher/hello.go".
    +	// For example, Name would return "hello.go" not "home/gopher/hello.go".
     	Name() string
     
     	// IsDir reports whether the entry describes a directory.
    diff --git a/src/make.bash b/src/make.bash
    index 4fb13f6275..7986125a06 100755
    --- a/src/make.bash
    +++ b/src/make.bash
    @@ -130,8 +130,8 @@ if [ "$(uname -s)" = "GNU/kFreeBSD" ]; then
     	export CGO_ENABLED=0
     fi
     
    -# Test which linker/loader our system is using
    -if type readelf >/dev/null 2>&1; then
    +# Test which linker/loader our system is using, if GO_LDSO is not set.
    +if [ -z "$GO_LDSO" ] && type readelf >/dev/null 2>&1; then
     	if echo "int main() { return 0; }" | ${CC:-cc} -o ./test-musl-ldso -x c - >/dev/null 2>&1; then
     		LDSO=$(readelf -l ./test-musl-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/') >/dev/null 2>&1
     		[ -z "$LDSO" ] || export GO_LDSO="$LDSO"
    @@ -203,16 +203,10 @@ if [ "$1" = "--dist-tool" ]; then
     	exit 0
     fi
     
    -buildall="-a"
    -if [ "$1" = "--no-clean" ]; then
    -	buildall=""
    -	shift
    -fi
    -
     # Run dist bootstrap to complete make.bash.
     # Bootstrap installs a proper cmd/dist, built with the new toolchain.
     # Throw ours, built with Go 1.4, away after bootstrap.
    -./cmd/dist/dist bootstrap $buildall $vflag $GO_DISTFLAGS "$@"
    +./cmd/dist/dist bootstrap -a $vflag $GO_DISTFLAGS "$@"
     rm -f ./cmd/dist/dist
     
     # DO NOT ADD ANY NEW CODE HERE.
    diff --git a/src/make.bat b/src/make.bat
    index b4a8e70849..8f2825b09a 100644
    --- a/src/make.bat
    +++ b/src/make.bat
    @@ -112,20 +112,20 @@ if x%2==x--dist-tool goto copydist
     if x%3==x--dist-tool goto copydist
     if x%4==x--dist-tool goto copydist
     
    -set buildall=-a
    -if x%1==x--no-clean set buildall=
    -if x%2==x--no-clean set buildall=
    -if x%3==x--no-clean set buildall=
    -if x%4==x--no-clean set buildall=
    -if x%1==x--no-banner set buildall=%buildall% --no-banner
    -if x%2==x--no-banner set buildall=%buildall% --no-banner
    -if x%3==x--no-banner set buildall=%buildall% --no-banner
    -if x%4==x--no-banner set buildall=%buildall% --no-banner
    +set bootstrapflags=
    +if x%1==x--no-clean set bootstrapflags=--no-clean
    +if x%2==x--no-clean set bootstrapflags=--no-clean
    +if x%3==x--no-clean set bootstrapflags=--no-clean
    +if x%4==x--no-clean set bootstrapflags=--no-clean
    +if x%1==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
    +if x%2==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
    +if x%3==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
    +if x%4==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
     
     :: Run dist bootstrap to complete make.bash.
     :: Bootstrap installs a proper cmd/dist, built with the new toolchain.
     :: Throw ours, built with Go 1.4, away after bootstrap.
    -.\cmd\dist\dist.exe bootstrap %vflag% %buildall%
    +.\cmd\dist\dist.exe bootstrap -a %vflag% %bootstrapflags%
     if errorlevel 1 goto fail
     del .\cmd\dist\dist.exe
     goto end
    diff --git a/src/make.rc b/src/make.rc
    index f5e57e9755..7bdc7dea1c 100755
    --- a/src/make.rc
    +++ b/src/make.rc
    @@ -92,15 +92,10 @@ if(~ $1 --dist-tool){
     	exit
     }
     
    -buildall = -a
    -if(~ $1 --no-clean) {
    -	buildall = ()
    -	shift
    -}
     # Run dist bootstrap to complete make.bash.
     # Bootstrap installs a proper cmd/dist, built with the new toolchain.
     # Throw ours, built with Go 1.4, away after bootstrap.
    -./cmd/dist/dist bootstrap $vflag $buildall $*
    +./cmd/dist/dist bootstrap -a $vflag $*
     rm -f ./cmd/dist/dist
     
     # DO NOT ADD ANY NEW CODE HERE.
    diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
    index 5d39955d62..8b63368386 100644
    --- a/src/net/http/httputil/reverseproxy.go
    +++ b/src/net/http/httputil/reverseproxy.go
    @@ -235,6 +235,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
     	if req.ContentLength == 0 {
     		outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
     	}
    +	if outreq.Body != nil {
    +		// Reading from the request body after returning from a handler is not
    +		// allowed, and the RoundTrip goroutine that reads the Body can outlive
    +		// this handler. This can lead to a crash if the handler panics (see
    +		// Issue 46866). Although calling Close doesn't guarantee there isn't
    +		// any Read in flight after the handle returns, in practice it's safe to
    +		// read after closing it.
    +		defer outreq.Body.Close()
    +	}
     	if outreq.Header == nil {
     		outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
     	}
    diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
    index 1898ed8b8a..4b6ad77a29 100644
    --- a/src/net/http/httputil/reverseproxy_test.go
    +++ b/src/net/http/httputil/reverseproxy_test.go
    @@ -1122,6 +1122,45 @@ func TestReverseProxy_PanicBodyError(t *testing.T) {
     	rproxy.ServeHTTP(httptest.NewRecorder(), req)
     }
     
    +// Issue #46866: panic without closing incoming request body causes a panic
    +func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
    +	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    +		out := "this call was relayed by the reverse proxy"
    +		// Coerce a wrong content length to induce io.ErrUnexpectedEOF
    +		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
    +		fmt.Fprintln(w, out)
    +	}))
    +	defer backend.Close()
    +	backendURL, err := url.Parse(backend.URL)
    +	if err != nil {
    +		t.Fatal(err)
    +	}
    +	proxyHandler := NewSingleHostReverseProxy(backendURL)
    +	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
    +	frontend := httptest.NewServer(proxyHandler)
    +	defer frontend.Close()
    +	frontendClient := frontend.Client()
    +
    +	var wg sync.WaitGroup
    +	for i := 0; i < 2; i++ {
    +		wg.Add(1)
    +		go func() {
    +			defer wg.Done()
    +			for j := 0; j < 10; j++ {
    +				const reqLen = 6 * 1024 * 1024
    +				req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
    +				req.ContentLength = reqLen
    +				resp, _ := frontendClient.Transport.RoundTrip(req)
    +				if resp != nil {
    +					io.Copy(io.Discard, resp.Body)
    +					resp.Body.Close()
    +				}
    +			}
    +		}()
    +	}
    +	wg.Wait()
    +}
    +
     func TestSelectFlushInterval(t *testing.T) {
     	tests := []struct {
     		name string
    diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
    index 690e0c299d..eeaa492644 100644
    --- a/src/net/http/transport_test.go
    +++ b/src/net/http/transport_test.go
    @@ -6441,10 +6441,11 @@ func TestErrorWriteLoopRace(t *testing.T) {
     // Test that a new request which uses the connection of an active request
     // cannot cause it to be canceled as well.
     func TestCancelRequestWhenSharingConnection(t *testing.T) {
    -	if testing.Short() {
    -		t.Skip("skipping in short mode")
    -	}
    +	reqc := make(chan chan struct{}, 2)
     	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
    +		ch := make(chan struct{}, 1)
    +		reqc <- ch
    +		<-ch
     		w.Header().Add("Content-Length", "0")
     	}))
     	defer ts.Close()
    @@ -6456,34 +6457,58 @@ func TestCancelRequestWhenSharingConnection(t *testing.T) {
     
     	var wg sync.WaitGroup
     
    -	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    -
    -	for i := 0; i < 10; i++ {
    -		wg.Add(1)
    -		go func() {
    -			defer wg.Done()
    -			for ctx.Err() == nil {
    -				reqctx, reqcancel := context.WithCancel(ctx)
    -				go reqcancel()
    -				req, _ := NewRequestWithContext(reqctx, "GET", ts.URL, nil)
    -				res, err := client.Do(req)
    -				if err == nil {
    -					res.Body.Close()
    -				}
    -			}
    -		}()
    -	}
    -
    -	for ctx.Err() == nil {
    -		req, _ := NewRequest("GET", ts.URL, nil)
    -		if res, err := client.Do(req); err != nil {
    -			t.Errorf("unexpected: %p %v", req, err)
    -			break
    -		} else {
    +	wg.Add(1)
    +	putidlec := make(chan chan struct{})
    +	go func() {
    +		defer wg.Done()
    +		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
    +			PutIdleConn: func(error) {
    +				// Signal that the idle conn has been returned to the pool,
    +				// and wait for the order to proceed.
    +				ch := make(chan struct{})
    +				putidlec <- ch
    +				<-ch
    +			},
    +		})
    +		req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
    +		res, err := client.Do(req)
    +		if err == nil {
     			res.Body.Close()
     		}
    -	}
    +		if err != nil {
    +			t.Errorf("request 1: got err %v, want nil", err)
    +		}
    +	}()
     
    +	// Wait for the first request to receive a response and return the
    +	// connection to the idle pool.
    +	r1c := <-reqc
    +	close(r1c)
    +	idlec := <-putidlec
    +
    +	wg.Add(1)
    +	cancelctx, cancel := context.WithCancel(context.Background())
    +	go func() {
    +		defer wg.Done()
    +		req, _ := NewRequestWithContext(cancelctx, "GET", ts.URL, nil)
    +		res, err := client.Do(req)
    +		if err == nil {
    +			res.Body.Close()
    +		}
    +		if !errors.Is(err, context.Canceled) {
    +			t.Errorf("request 2: got err %v, want Canceled", err)
    +		}
    +	}()
    +
    +	// Wait for the second request to arrive at the server, and then cancel
    +	// the request context.
    +	r2c := <-reqc
     	cancel()
    +
    +	// Give the cancelation a moment to take effect, and then unblock the first request.
    +	time.Sleep(1 * time.Millisecond)
    +	close(idlec)
    +
    +	close(r2c)
     	wg.Wait()
     }
    diff --git a/src/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
    index f834ffede0..bbf6a9b7f1 100644
    --- a/src/os/exec/lp_windows_test.go
    +++ b/src/os/exec/lp_windows_test.go
    @@ -312,9 +312,6 @@ func TestLookPath(t *testing.T) {
     	// Run all tests.
     	for i, test := range lookPathTests {
     		t.Run(fmt.Sprint(i), func(t *testing.T) {
    -			if i == 16 {
    -				t.Skip("golang.org/issue/44379")
    -			}
     			dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
     			err := os.Mkdir(dir, 0700)
     			if err != nil {
    diff --git a/src/runtime/cgo/gcc_traceback.c b/src/runtime/cgo/gcc_traceback.c
    index d86331c583..6e9470c43c 100644
    --- a/src/runtime/cgo/gcc_traceback.c
    +++ b/src/runtime/cgo/gcc_traceback.c
    @@ -7,6 +7,14 @@
     #include 
     #include "libcgo.h"
     
    +#ifndef __has_feature
    +#define __has_feature(x) 0
    +#endif
    +
    +#if __has_feature(memory_sanitizer)
    +#include 
    +#endif
    +
     // Call the user's traceback function and then call sigtramp.
     // The runtime signal handler will jump to this code.
     // We do it this way so that the user's traceback function will be called
    @@ -19,6 +27,18 @@ x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(str
     	arg.SigContext = (uintptr_t)(context);
     	arg.Buf = cgoCallers;
     	arg.Max = 32; // must match len(runtime.cgoCallers)
    +
    +#if __has_feature(memory_sanitizer)
    +        // This function is called directly from the signal handler.
    +        // The arguments are passed in registers, so whether msan
    +        // considers cgoCallers to be initialized depends on whether
    +        // it considers the appropriate register to be initialized.
    +        // That can cause false reports in rare cases.
    +        // Explicitly unpoison the memory to avoid that.
    +        // See issue #47543 for more details.
    +        __msan_unpoison(&arg, sizeof arg);
    +#endif
    +
     	(*cgoTraceback)(&arg);
     	sigtramp(sig, info, context);
     }
    diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
    index 479878e6d2..2f3c609907 100644
    --- a/src/runtime/cgocall.go
    +++ b/src/runtime/cgocall.go
    @@ -213,6 +213,8 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
     	// a different M. The call to unlockOSThread is in unwindm.
     	lockOSThread()
     
    +	checkm := gp.m
    +
     	// Save current syscall parameters, so m.syscall can be
     	// used again if callback decide to make syscall.
     	syscall := gp.m.syscall
    @@ -228,15 +230,20 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
     
     	osPreemptExtExit(gp.m)
     
    -	cgocallbackg1(fn, frame, ctxt)
    +	cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
     
     	// At this point unlockOSThread has been called.
     	// The following code must not change to a different m.
     	// This is enforced by checking incgo in the schedule function.
     
    +	gp.m.incgo = true
    +
    +	if gp.m != checkm {
    +		throw("m changed unexpectedly in cgocallbackg")
    +	}
    +
     	osPreemptExtEnter(gp.m)
     
    -	gp.m.incgo = true
     	// going back to cgo call
     	reentersyscall(savedpc, uintptr(savedsp))
     
    @@ -245,6 +252,11 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
     
     func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
     	gp := getg()
    +
    +	// When we return, undo the call to lockOSThread in cgocallbackg.
    +	// We must still stay on the same m.
    +	defer unlockOSThread()
    +
     	if gp.m.needextram || atomic.Load(&extraMWaiters) > 0 {
     		gp.m.needextram = false
     		systemstack(newextram)
    @@ -324,10 +336,6 @@ func unwindm(restore *bool) {
     
     		releasem(mp)
     	}
    -
    -	// Undo the call to lockOSThread in cgocallbackg.
    -	// We must still stay on the same m.
    -	unlockOSThread()
     }
     
     // called from assembly
    diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go
    index d42950844b..2d4afd5cf6 100644
    --- a/src/runtime/checkptr.go
    +++ b/src/runtime/checkptr.go
    @@ -7,6 +7,11 @@ package runtime
     import "unsafe"
     
     func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
    +	// nil pointer is always suitably aligned (#47430).
    +	if p == nil {
    +		return
    +	}
    +
     	// Check that (*[n]elem)(p) is appropriately aligned.
     	// Note that we allow unaligned pointers if the types they point to contain
     	// no pointers themselves. See issue 37298.
    @@ -29,10 +34,12 @@ func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
     		return false
     	}
     
    -	end := add(ptr, size-1)
    -	if uintptr(end) < uintptr(ptr) {
    +	// Check that add(ptr, size-1) won't overflow. This avoids the risk
    +	// of producing an illegal pointer value (assuming ptr is legal).
    +	if uintptr(ptr) >= -(size - 1) {
     		return true
     	}
    +	end := add(ptr, size-1)
     
     	// TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
     	// but neither ptr nor end point into one themselves.
    diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
    index 2a5c364e97..d5dd101adb 100644
    --- a/src/runtime/checkptr_test.go
    +++ b/src/runtime/checkptr_test.go
    @@ -26,6 +26,7 @@ func TestCheckPtr(t *testing.T) {
     	}{
     		{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
     		{"CheckPtrAlignmentNoPtr", ""},
    +		{"CheckPtrAlignmentNilPtr", ""},
     		{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
     		{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
     		{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
    diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
    index 7d25c51aa2..5729942cee 100644
    --- a/src/runtime/crash_cgo_test.go
    +++ b/src/runtime/crash_cgo_test.go
    @@ -282,6 +282,15 @@ func TestCgoTracebackContext(t *testing.T) {
     	}
     }
     
    +func TestCgoTracebackContextPreemption(t *testing.T) {
    +	t.Parallel()
    +	got := runTestProg(t, "testprogcgo", "TracebackContextPreemption")
    +	want := "OK\n"
    +	if got != want {
    +		t.Errorf("expected %q got %v", want, got)
    +	}
    +}
    +
     func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) {
     	t.Parallel()
     	if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
    diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
    index c07ea5e375..3cdb81e2fb 100644
    --- a/src/runtime/mfinal.go
    +++ b/src/runtime/mfinal.go
    @@ -466,6 +466,10 @@ okarg:
     // Without the KeepAlive call, the finalizer could run at the start of
     // syscall.Read, closing the file descriptor before syscall.Read makes
     // the actual system call.
    +//
    +// Note: KeepAlive should only be used to prevent finalizers from
    +// running prematurely. In particular, when used with unsafe.Pointer,
    +// the rules for valid uses of unsafe.Pointer still apply.
     func KeepAlive(x interface{}) {
     	// Introduce a use of x that the compiler can't eliminate.
     	// This makes sure x is alive on entry. We need x to be alive
    diff --git a/src/runtime/proc.go b/src/runtime/proc.go
    index 4dc1811fc6..ec4be31db3 100644
    --- a/src/runtime/proc.go
    +++ b/src/runtime/proc.go
    @@ -4850,7 +4850,6 @@ func (pp *p) destroy() {
     		moveTimers(plocal, pp.timers)
     		pp.timers = nil
     		pp.numTimers = 0
    -		pp.adjustTimers = 0
     		pp.deletedTimers = 0
     		atomic.Store64(&pp.timer0When, 0)
     		unlock(&pp.timersLock)
    diff --git a/src/runtime/race.go b/src/runtime/race.go
    index f1c3c3098d..7eaa9d2b72 100644
    --- a/src/runtime/race.go
    +++ b/src/runtime/race.go
    @@ -344,7 +344,7 @@ func racereadrangepc1(addr, size, pc uintptr)
     func racewriterangepc1(addr, size, pc uintptr)
     func racecallbackthunk(uintptr)
     
    -// racecall allows calling an arbitrary function f from C race runtime
    +// racecall allows calling an arbitrary function fn from C race runtime
     // with up to 4 uintptr arguments.
     func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
     
    diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
    index c5e2501991..e4e9ee50b8 100644
    --- a/src/runtime/runtime2.go
    +++ b/src/runtime/runtime2.go
    @@ -727,12 +727,6 @@ type p struct {
     	// Modified using atomic instructions.
     	numTimers uint32
     
    -	// Number of timerModifiedEarlier timers on P's heap.
    -	// This should only be modified while holding timersLock,
    -	// or while the timer status is in a transient state
    -	// such as timerModifying.
    -	adjustTimers uint32
    -
     	// Number of timerDeleted timers in P's heap.
     	// Modified using atomic instructions.
     	deletedTimers uint32
    diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
    index af15709a4a..3fe352ef57 100644
    --- a/src/runtime/signal_windows.go
    +++ b/src/runtime/signal_windows.go
    @@ -184,6 +184,17 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
     		return _EXCEPTION_CONTINUE_SEARCH
     	}
     
    +	// VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
    +	// illegal instructions during runtime initialization to determine
    +	// CPU features, so if we make it to the last handler and we're
    +	// arm64 and it's an illegal instruction and this is coming from
    +	// non-Go code, then assume it's this runtime probing happen, and
    +	// pass that onward to SEH.
    +	if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
    +		(r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
    +		return _EXCEPTION_CONTINUE_SEARCH
    +	}
    +
     	winthrow(info, r, gp)
     	return 0 // not reached
     }
    diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
    index f76b64ad96..9c5561396e 100644
    --- a/src/runtime/testdata/testprog/checkptr.go
    +++ b/src/runtime/testdata/testprog/checkptr.go
    @@ -4,11 +4,16 @@
     
     package main
     
    -import "unsafe"
    +import (
    +	"runtime"
    +	"time"
    +	"unsafe"
    +)
     
     func init() {
     	register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
     	register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
    +	register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr)
     	register("CheckPtrArithmetic", CheckPtrArithmetic)
     	register("CheckPtrArithmetic2", CheckPtrArithmetic2)
     	register("CheckPtrSize", CheckPtrSize)
    @@ -29,6 +34,35 @@ func CheckPtrAlignmentPtr() {
     	sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
     }
     
    +// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash
    +// on nil pointers (#47430).
    +func CheckPtrAlignmentNilPtr() {
    +	var do func(int)
    +	do = func(n int) {
    +		// Inflate the stack so runtime.shrinkstack gets called during GC
    +		if n > 0 {
    +			do(n - 1)
    +		}
    +
    +		var p unsafe.Pointer
    +		_ = (*int)(p)
    +	}
    +
    +	go func() {
    +		for {
    +			runtime.GC()
    +		}
    +	}()
    +
    +	go func() {
    +		for i := 0; ; i++ {
    +			do(i % 1024)
    +		}
    +	}()
    +
    +	time.Sleep(time.Second)
    +}
    +
     func CheckPtrArithmetic() {
     	var x int
     	i := uintptr(unsafe.Pointer(&x))
    diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt.go b/src/runtime/testdata/testprogcgo/tracebackctxt.go
    index 51fa4ad25c..62ff8eccd6 100644
    --- a/src/runtime/testdata/testprogcgo/tracebackctxt.go
    +++ b/src/runtime/testdata/testprogcgo/tracebackctxt.go
    @@ -2,8 +2,6 @@
     // Use of this source code is governed by a BSD-style
     // license that can be found in the LICENSE file.
     
    -// The __attribute__((weak)) used below doesn't seem to work on Windows.
    -
     package main
     
     // Test the context argument to SetCgoTraceback.
    @@ -14,20 +12,24 @@ package main
     extern void C1(void);
     extern void C2(void);
     extern void tcContext(void*);
    +extern void tcContextSimple(void*);
     extern void tcTraceback(void*);
     extern void tcSymbolizer(void*);
     extern int getContextCount(void);
    +extern void TracebackContextPreemptionCallGo(int);
     */
     import "C"
     
     import (
     	"fmt"
     	"runtime"
    +	"sync"
     	"unsafe"
     )
     
     func init() {
     	register("TracebackContext", TracebackContext)
    +	register("TracebackContextPreemption", TracebackContextPreemption)
     }
     
     var tracebackOK bool
    @@ -105,3 +107,30 @@ wantLoop:
     		tracebackOK = false
     	}
     }
    +
    +// Issue 47441.
    +func TracebackContextPreemption() {
    +	runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
    +
    +	const funcs = 10
    +	const calls = 1e5
    +	var wg sync.WaitGroup
    +	for i := 0; i < funcs; i++ {
    +		wg.Add(1)
    +		go func(i int) {
    +			defer wg.Done()
    +			for j := 0; j < calls; j++ {
    +				C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
    +			}
    +		}(i)
    +	}
    +	wg.Wait()
    +
    +	fmt.Println("OK")
    +}
    +
    +//export TracebackContextPreemptionGoFunction
    +func TracebackContextPreemptionGoFunction(i C.int) {
    +	// Do some busy work.
    +	fmt.Sprintf("%d\n", i)
    +}
    diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
    index 900cada0d3..910cb7b899 100644
    --- a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
    +++ b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
    @@ -11,6 +11,7 @@
     // Functions exported from Go.
     extern void G1(void);
     extern void G2(void);
    +extern void TracebackContextPreemptionGoFunction(int);
     
     void C1() {
     	G1();
    @@ -62,10 +63,17 @@ void tcContext(void* parg) {
     	}
     }
     
    +void tcContextSimple(void* parg) {
    +	struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
    +	if (arg->context == 0) {
    +		arg->context = 1;
    +	}
    +}
    +
     void tcTraceback(void* parg) {
     	int base, i;
     	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
    -	if (arg->context == 0) {
    +	if (arg->context == 0 && arg->sigContext == 0) {
     		// This shouldn't happen in this program.
     		abort();
     	}
    @@ -89,3 +97,7 @@ void tcSymbolizer(void *parg) {
     	arg->func = "cFunction";
     	arg->lineno = arg->pc + (arg->more << 16);
     }
    +
    +void TracebackContextPreemptionCallGo(int i) {
    +	TracebackContextPreemptionGoFunction(i);
    +}
    diff --git a/src/runtime/textflag.h b/src/runtime/textflag.h
    index e727208cd0..214075e360 100644
    --- a/src/runtime/textflag.h
    +++ b/src/runtime/textflag.h
    @@ -32,8 +32,8 @@
     #define NOFRAME 512
     // Function can call reflect.Type.Method or reflect.Type.MethodByName.
     #define REFLECTMETHOD 1024
    -// Function is the top of the call stack. Call stack unwinders should stop
    -// at this function.
    +// Function is the outermost frame of the call stack. Call stack unwinders
    +// should stop at this function.
     #define TOPFRAME 2048
     // Function is an ABI wrapper.
     #define ABIWRAPPER 4096
    diff --git a/src/runtime/time.go b/src/runtime/time.go
    index 2f791c4ad8..ad267c3365 100644
    --- a/src/runtime/time.go
    +++ b/src/runtime/time.go
    @@ -334,7 +334,6 @@ func deltimer(t *timer) bool {
     				// Must fetch t.pp before setting status
     				// to timerDeleted.
     				tpp := t.pp.ptr()
    -				atomic.Xadd(&tpp.adjustTimers, -1)
     				if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
     					badTimer()
     				}
    @@ -511,20 +510,9 @@ loop:
     
     		tpp := t.pp.ptr()
     
    -		// Update the adjustTimers field.  Subtract one if we
    -		// are removing a timerModifiedEarlier, add one if we
    -		// are adding a timerModifiedEarlier.
    -		adjust := int32(0)
    -		if status == timerModifiedEarlier {
    -			adjust--
    -		}
     		if newStatus == timerModifiedEarlier {
    -			adjust++
     			updateTimerModifiedEarliest(tpp, when)
     		}
    -		if adjust != 0 {
    -			atomic.Xadd(&tpp.adjustTimers, adjust)
    -		}
     
     		// Set the new status of the timer.
     		if !atomic.Cas(&t.status, timerModifying, newStatus) {
    @@ -592,9 +580,6 @@ func cleantimers(pp *p) {
     			// Move t to the right position.
     			dodeltimer0(pp)
     			doaddtimer(pp, t)
    -			if s == timerModifiedEarlier {
    -				atomic.Xadd(&pp.adjustTimers, -1)
    -			}
     			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
     				badTimer()
     			}
    @@ -665,32 +650,23 @@ func moveTimers(pp *p, timers []*timer) {
     // it also moves timers that have been modified to run later,
     // and removes deleted timers. The caller must have locked the timers for pp.
     func adjusttimers(pp *p, now int64) {
    -	if atomic.Load(&pp.adjustTimers) == 0 {
    +	// If we haven't yet reached the time of the first timerModifiedEarlier
    +	// timer, don't do anything. This speeds up programs that adjust
    +	// a lot of timers back and forth if the timers rarely expire.
    +	// We'll postpone looking through all the adjusted timers until
    +	// one would actually expire.
    +	first := atomic.Load64(&pp.timerModifiedEarliest)
    +	if first == 0 || int64(first) > now {
     		if verifyTimers {
     			verifyTimerHeap(pp)
     		}
     		return
     	}
     
    -	// If we haven't yet reached the time of the first timerModifiedEarlier
    -	// timer, don't do anything. This speeds up programs that adjust
    -	// a lot of timers back and forth if the timers rarely expire.
    -	// We'll postpone looking through all the adjusted timers until
    -	// one would actually expire.
    -	if first := atomic.Load64(&pp.timerModifiedEarliest); first != 0 {
    -		if int64(first) > now {
    -			if verifyTimers {
    -				verifyTimerHeap(pp)
    -			}
    -			return
    -		}
    -
    -		// We are going to clear all timerModifiedEarlier timers.
    -		atomic.Store64(&pp.timerModifiedEarliest, 0)
    -	}
    +	// We are going to clear all timerModifiedEarlier timers.
    +	atomic.Store64(&pp.timerModifiedEarliest, 0)
     
     	var moved []*timer
    -loop:
     	for i := 0; i < len(pp.timers); i++ {
     		t := pp.timers[i]
     		if t.pp.ptr() != pp {
    @@ -717,11 +693,6 @@ loop:
     				// loop to skip some other timer.
     				dodeltimer(pp, i)
     				moved = append(moved, t)
    -				if s == timerModifiedEarlier {
    -					if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 {
    -						break loop
    -					}
    -				}
     				// Look at this heap position again.
     				i--
     			}
    @@ -820,9 +791,6 @@ func runtimer(pp *p, now int64) int64 {
     			t.when = t.nextwhen
     			dodeltimer0(pp)
     			doaddtimer(pp, t)
    -			if s == timerModifiedEarlier {
    -				atomic.Xadd(&pp.adjustTimers, -1)
    -			}
     			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
     				badTimer()
     			}
    @@ -917,7 +885,6 @@ func clearDeletedTimers(pp *p) {
     	atomic.Store64(&pp.timerModifiedEarliest, 0)
     
     	cdel := int32(0)
    -	cearlier := int32(0)
     	to := 0
     	changedHeap := false
     	timers := pp.timers
    @@ -942,9 +909,6 @@ nextTimer:
     					if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
     						badTimer()
     					}
    -					if s == timerModifiedEarlier {
    -						cearlier++
    -					}
     					continue nextTimer
     				}
     			case timerDeleted:
    @@ -981,7 +945,6 @@ nextTimer:
     
     	atomic.Xadd(&pp.deletedTimers, -cdel)
     	atomic.Xadd(&pp.numTimers, -cdel)
    -	atomic.Xadd(&pp.adjustTimers, -cearlier)
     
     	timers = timers[:to]
     	pp.timers = timers
    diff --git a/src/testing/testing.go b/src/testing/testing.go
    index 681f99ef93..a19238d31e 100644
    --- a/src/testing/testing.go
    +++ b/src/testing/testing.go
    @@ -680,7 +680,11 @@ type T struct {
     
     func (c *common) private() {}
     
    -// Name returns the name of the running test or benchmark.
    +// Name returns the name of the running (sub-) test or benchmark.
    +//
    +// The name will include the name of the test along with the names of
    +// any nested sub-tests. If two sibling sub-tests have the same name,
    +// Name will append a suffix to guarantee the returned name is unique.
     func (c *common) Name() string {
     	return c.name
     }