diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ee50a4c049a..1984d44c537 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 d5788000861..51f85eb9482 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 48811e6b679..b65d13a0403 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 0e14a1f3b63..fd5fee46eb2 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 2a3494fbfc1..5ee9947a585 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 00000000000..1cb5c5677fa
    --- /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 1abb03bcc56..bec17696f30 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 954caae9fb1..7f88d3216cf 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 e856e7c6304..bb3d5210926 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 73cc282d814..958c3066ac1 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 f817a045834..dfef9f73c27 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 604a57b4373..bf695673167 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 a8cbd9fe16d..45f724d5e36 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 d280945ea63..03e02e73b63 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 dda9004a9f4..e737ca90fcd 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 ffcea186035..9abbabd2ebe 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 00000000000..41f12e4084d
    --- /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 00000000000..3f6f5c5276b
    --- /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 881e1922031..5ae75027c2f 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 a33bba24666..7da8606eceb 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 8079cf3248b..7cfafe64086 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 6141f6e06dc..98e394a2715 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 69d29d3c6c6..8f4674d33c0 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 09bb98d980e..815dcc8a95f 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 44dc8e8caf9..8fe583939f1 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 b2d532c4c8b..f138af5fbf5 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 692004facf1..8c8452c9c68 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 b55f51185fd..c9a55aa871e 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 e1be32478e0..e603afadb0b 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 4fb13f62758..7986125a06f 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 b4a8e708490..8f2825b09a9 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 f5e57e97556..7bdc7dea1c1 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 5d39955d62d..8b63368386f 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 1898ed8b8af..4b6ad77a294 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 690e0c299d2..eeaa4926445 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 f834ffede03..bbf6a9b7f13 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 d86331c583a..6e9470c43c2 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 479878e6d2f..2f3c6099076 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 d42950844b5..2d4afd5cf68 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 2a5c364e97b..d5dd101adbe 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 7d25c51aa2a..5729942cee3 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 c07ea5e3752..3cdb81e2fb9 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 4dc1811fc6b..ec4be31db35 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 f1c3c3098dd..7eaa9d2b721 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 c5e2501991b..e4e9ee50b80 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 af15709a4aa..3fe352ef575 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 f76b64ad96f..9c5561396e5 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 51fa4ad25c3..62ff8eccd67 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 900cada0d3d..910cb7b8997 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 e727208cd03..214075e360c 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 2f791c4ad87..ad267c33656 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 681f99ef934..a19238d31e2 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
     }