[dev.boringcrypto] all: merge master into dev.boringcrypto

Change-Id: I9246c8228d38559c40e69fa403fa946ac1b31dbe
This commit is contained in:
Filippo Valsorda 2019-02-08 15:36:33 -05:00
commit 4ed8ad4d69
1404 changed files with 82120 additions and 33756 deletions

View file

@ -418,7 +418,7 @@ Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com> Elbert Fliek <efliek@gmail.com>
Eldar Rakhimberdin <ibeono@gmail.com> Eldar Rakhimberdin <ibeono@gmail.com>
Elena Grahovac <elena@grahovac.me> Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com> Elias Naur <mail@eliasnaur.com> <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com> Elliot Morrison-Reed <elliotmr@gmail.com>
Emerson Lin <linyintor@gmail.com> Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se> Emil Hessman <emil@hessman.se>
@ -1304,6 +1304,7 @@ Sven Almgren <sven@tras.se>
Sylvain Zimmer <sylvain@sylvainzimmer.com> Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com> Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net> Szabolcs Nagy <nsz@port70.net>
Taavi Kivisik <taavi.kivisik@gmail.com>
Tad Fisher <tadfisher@gmail.com> Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com> Tad Glines <tad.glines@gmail.com>
Taj Khattra <taj.khattra@gmail.com> Taj Khattra <taj.khattra@gmail.com>

View file

@ -25,6 +25,7 @@
# Please keep the list sorted. # Please keep the list sorted.
Aamir Khan <syst3m.w0rm@gmail.com> Aamir Khan <syst3m.w0rm@gmail.com>
Aaron Cannon <cannona@fireantproductions.com>
Aaron France <aaron.l.france@gmail.com> Aaron France <aaron.l.france@gmail.com>
Aaron Jacobs <jacobsa@google.com> Aaron Jacobs <jacobsa@google.com>
Aaron Kemp <kemp.aaron@gmail.com> Aaron Kemp <kemp.aaron@gmail.com>
@ -32,6 +33,7 @@ Aaron Stein <aaronstein12@gmail.com>
Aaron Torres <tcboox@gmail.com> Aaron Torres <tcboox@gmail.com>
Aaron Zinman <aaron@azinman.com> Aaron Zinman <aaron@azinman.com>
Aarti Parikh <aarti.parikh@gmail.com> Aarti Parikh <aarti.parikh@gmail.com>
Abdullah Al Maruf <mymail.maruf@gmail.com>
Abe Haskins <abeisgreat@abeisgreat.com> Abe Haskins <abeisgreat@abeisgreat.com>
Abhinav Gupta <abhinav.g90@gmail.com> Abhinav Gupta <abhinav.g90@gmail.com>
Adam Azarchs <adam.azarchs@10xgenomics.com> Adam Azarchs <adam.azarchs@10xgenomics.com>
@ -66,6 +68,7 @@ Aishraj Dahal <aishraj@users.noreply.github.com>
Akhil Indurti <contact@akhilindurti.com> Akhil Indurti <contact@akhilindurti.com>
Akihiro Suda <suda.kyoto@gmail.com> Akihiro Suda <suda.kyoto@gmail.com>
Akshat Kumar <seed@mail.nanosouffle.net> Akshat Kumar <seed@mail.nanosouffle.net>
Alan Braithwaite <alan@ipaddr.org>
Alan Donovan <adonovan@google.com> Alan Donovan <adonovan@google.com>
Alan Shreve <alan@inconshreveable.com> Alan Shreve <alan@inconshreveable.com>
Albert Nigmatzianov <albertnigma@gmail.com> Albert Nigmatzianov <albertnigma@gmail.com>
@ -74,8 +77,10 @@ Albert Yu <yukinying@gmail.com>
Alberto Bertogli <albertito@blitiri.com.ar> Alberto Bertogli <albertito@blitiri.com.ar>
Alberto Donizetti <alb.donizetti@gmail.com> Alberto Donizetti <alb.donizetti@gmail.com>
Alberto García Hierro <alberto@garciahierro.com> <alberto.garcia.hierro@gmail.com> Alberto García Hierro <alberto@garciahierro.com> <alberto.garcia.hierro@gmail.com>
Aleksa Sarai <cyphar@cyphar.com>
Aleksandar Dezelin <dezelin@gmail.com> Aleksandar Dezelin <dezelin@gmail.com>
Aleksandr Lukinykh <a.lukinykh@xsolla.com> Aleksandr Lukinykh <a.lukinykh@xsolla.com>
Aleksandr Razumov <ar@cydev.ru>
Alekseev Artem <a.artem060@gmail.com> Alekseev Artem <a.artem060@gmail.com>
Alessandro Arzilli <alessandro.arzilli@gmail.com> Alessandro Arzilli <alessandro.arzilli@gmail.com>
Alessandro Baffa <alessandro.baffa@gmail.com> Alessandro Baffa <alessandro.baffa@gmail.com>
@ -85,6 +90,7 @@ Alex Bramley <abramley@google.com>
Alex Browne <stephenalexbrowne@gmail.com> Alex Browne <stephenalexbrowne@gmail.com>
Alex Carol <alex.carol.c@gmail.com> Alex Carol <alex.carol.c@gmail.com>
Alex Jin <toalexjin@gmail.com> Alex Jin <toalexjin@gmail.com>
Alex Kohler <alexjohnkohler@gmail.com>
Alex Myasoedov <msoedov@gmail.com> Alex Myasoedov <msoedov@gmail.com>
Alex Plugaru <alex@plugaru.org> <alexandru.plugaru@gmail.com> Alex Plugaru <alex@plugaru.org> <alexandru.plugaru@gmail.com>
Alex Schroeder <alex@gnu.org> Alex Schroeder <alex@gnu.org>
@ -106,15 +112,19 @@ Alexander Polcyn <apolcyn@google.com>
Alexander Reece <awreece@gmail.com> Alexander Reece <awreece@gmail.com>
Alexander Surma <surma@surmair.de> Alexander Surma <surma@surmair.de>
Alexander Zhavnerchik <alex.vizor@gmail.com> Alexander Zhavnerchik <alex.vizor@gmail.com>
Alexander Zillion <alex@alexzillion.com>
Alexander Zolotov <goldifit@gmail.com> Alexander Zolotov <goldifit@gmail.com>
Alexandre Cesaro <alexandre.cesaro@gmail.com> Alexandre Cesaro <alexandre.cesaro@gmail.com>
Alexandre Fiori <fiorix@gmail.com> Alexandre Fiori <fiorix@gmail.com>
Alexandre Maari <draeron@gmail.com>
Alexandre Normand <alexandre.normand@gmail.com> Alexandre Normand <alexandre.normand@gmail.com>
Alexandre Parentea <aubonbeurre@gmail.com> Alexandre Parentea <aubonbeurre@gmail.com>
Alexandre Viau <alexandre@alexandreviau.net> Alexandre Viau <alexandre@alexandreviau.net>
Alexandru Moșoi <brtzsnr@gmail.com> Alexandru Moșoi <brtzsnr@gmail.com>
Alexei Sholik <alcosholik@gmail.com> Alexei Sholik <alcosholik@gmail.com>
Alexey Alexandrov <aalexand@google.com>
Alexey Borzenkov <snaury@gmail.com> Alexey Borzenkov <snaury@gmail.com>
Alexey Naidonov <alexey.naidyonov@gmail.com>
Alexey Neganov <neganovalexey@gmail.com> Alexey Neganov <neganovalexey@gmail.com>
Alexey Palazhchenko <alexey.palazhchenko@gmail.com> Alexey Palazhchenko <alexey.palazhchenko@gmail.com>
Alexis Hildebrandt <surryhill@gmail.com> Alexis Hildebrandt <surryhill@gmail.com>
@ -133,14 +143,17 @@ Anand K. Mistry <anand@mistry.ninja>
Anders Pearson <anders@columbia.edu> Anders Pearson <anders@columbia.edu>
André Carvalho <asantostc@gmail.com> André Carvalho <asantostc@gmail.com>
Andre Nathan <andrenth@gmail.com> Andre Nathan <andrenth@gmail.com>
Andrea Nodari <andrea.nodari91@gmail.com>
Andrea Spadaccini <spadaccio@google.com> Andrea Spadaccini <spadaccio@google.com>
Andreas Auernhammer <aead@mail.de> Andreas Auernhammer <aead@mail.de>
Andreas Jellinghaus <andreas@ionisiert.de> <anj@google.com> Andreas Jellinghaus <andreas@ionisiert.de> <anj@google.com>
Andreas Litt <andreas.litt@gmail.com> Andreas Litt <andreas.litt@gmail.com>
Andrei Gherzan <andrei@resin.io>
Andrei Korzhevskii <a.korzhevskiy@gmail.com> Andrei Korzhevskii <a.korzhevskiy@gmail.com>
Andrei Tudor Călin <mail@acln.ro> Andrei Tudor Călin <mail@acln.ro>
Andrei Vieru <euvieru@gmail.com> Andrei Vieru <euvieru@gmail.com>
Andres Erbsen <andreser@google.com> Andres Erbsen <andreser@google.com>
Andres Lowrie <andres.lowrie@gmail.com>
Andrew Austin <andrewaclt@gmail.com> Andrew Austin <andrewaclt@gmail.com>
Andrew Balholm <andybalholm@gmail.com> Andrew Balholm <andybalholm@gmail.com>
Andrew Benton <andrewmbenton@gmail.com> Andrew Benton <andrewmbenton@gmail.com>
@ -155,9 +168,11 @@ Andrew Jackura <ajackura@google.com>
Andrew Lutomirski <andy@luto.us> Andrew Lutomirski <andy@luto.us>
Andrew Pilloud <andrewpilloud@igneoussystems.com> Andrew Pilloud <andrewpilloud@igneoussystems.com>
Andrew Pogrebnoy <absourd.noise@gmail.com> Andrew Pogrebnoy <absourd.noise@gmail.com>
Andrew Poydence <apoydence@pivotal.io>
Andrew Pritchard <awpritchard@gmail.com> Andrew Pritchard <awpritchard@gmail.com>
Andrew Radev <andrey.radev@gmail.com> Andrew Radev <andrey.radev@gmail.com>
Andrew Skiba <skibaa@gmail.com> Andrew Skiba <skibaa@gmail.com>
Andrew Stribblehill <ads@wompom.org>
Andrew Szeto <andrew@jabagawee.com> Andrew Szeto <andrew@jabagawee.com>
Andrew Werner <andrew@upthere.com> <awerner32@gmail.com> Andrew Werner <andrew@upthere.com> <awerner32@gmail.com>
Andrew Wilkins <axwalk@gmail.com> Andrew Wilkins <axwalk@gmail.com>
@ -174,21 +189,26 @@ Andy Finkenstadt <afinkenstadt@zynga.com>
Andy Lindeman <andy@lindeman.io> Andy Lindeman <andy@lindeman.io>
Andy Maloney <asmaloney@gmail.com> Andy Maloney <asmaloney@gmail.com>
Andy Walker <walkeraj@gmail.com> Andy Walker <walkeraj@gmail.com>
Andzej Maciusovic <andzej.maciusovic@gmail.com>
Anfernee Yongkun Gui <anfernee.gui@gmail.com> Anfernee Yongkun Gui <anfernee.gui@gmail.com>
Angelo Bulfone <mbulfone@gmail.com> Angelo Bulfone <mbulfone@gmail.com>
Anh Hai Trinh <anh.hai.trinh@gmail.com> Anh Hai Trinh <anh.hai.trinh@gmail.com>
Anit Gandhi <anitgandhi@gmail.com> Anit Gandhi <anitgandhi@gmail.com>
Ankit Goyal <ankit3goyal@gmail.com>
Anmol Sethi <anmol@aubble.com> Anmol Sethi <anmol@aubble.com>
Anschel Schaffer-Cohen <anschelsc@gmail.com> Anschel Schaffer-Cohen <anschelsc@gmail.com>
Anthony Alves <cvballa3g0@gmail.com> Anthony Alves <cvballa3g0@gmail.com>
Anthony Canino <anthony.canino1@gmail.com> Anthony Canino <anthony.canino1@gmail.com>
Anthony Eufemio <anthony.eufemio@gmail.com> Anthony Eufemio <anthony.eufemio@gmail.com>
Anthony Fok <foka@debian.org>
Anthony Martin <ality@pbrane.org> Anthony Martin <ality@pbrane.org>
Anthony Sottile <asottile@umich.edu> Anthony Sottile <asottile@umich.edu>
Anthony Starks <ajstarks@gmail.com> Anthony Starks <ajstarks@gmail.com>
Anthony Voutas <voutasaurus@gmail.com> Anthony Voutas <voutasaurus@gmail.com>
Anthony Woods <awoods@raintank.io> Anthony Woods <awoods@raintank.io>
Antoine GIRARD <sapk@sapk.fr>
Antoine Martin <antoine97.martin@gmail.com> Antoine Martin <antoine97.martin@gmail.com>
Anton Gyllenberg <anton@iki.fi>
Antonin Amand <antonin.amand@gmail.com> Antonin Amand <antonin.amand@gmail.com>
Antonio Antelo <aantelov87@gmail.com> Antonio Antelo <aantelov87@gmail.com>
Antonio Bibiano <antbbn@gmail.com> Antonio Bibiano <antbbn@gmail.com>
@ -204,6 +224,7 @@ Arnaud Ysmal <arnaud.ysmal@gmail.com>
Arne Hormann <arnehormann@gmail.com> Arne Hormann <arnehormann@gmail.com>
Arnout Engelen <arnout@bzzt.net> Arnout Engelen <arnout@bzzt.net>
Aron Nopanen <aron.nopanen@gmail.com> Aron Nopanen <aron.nopanen@gmail.com>
Arthur Fabre <arthur@arthurfabre.com>
Arthur Khashaev <arthur@khashaev.ru> Arthur Khashaev <arthur@khashaev.ru>
Artyom Pervukhin <artyom.pervukhin@gmail.com> Artyom Pervukhin <artyom.pervukhin@gmail.com>
Arvindh Rajesh Tamilmani <art@a-30.net> Arvindh Rajesh Tamilmani <art@a-30.net>
@ -217,6 +238,7 @@ Augusto Roman <aroman@gmail.com>
Aulus Egnatius Varialus <varialus@gmail.com> Aulus Egnatius Varialus <varialus@gmail.com>
Aurélien Rainone <aurelien.rainone@gmail.com> Aurélien Rainone <aurelien.rainone@gmail.com>
Austin Clements <austin@google.com> <aclements@csail.mit.edu> Austin Clements <austin@google.com> <aclements@csail.mit.edu>
Avi Flax <avi@timehop.com>
awaw fumin <awawfumin@gmail.com> awaw fumin <awawfumin@gmail.com>
Awn Umar <awn@cryptolosophy.io> Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com> Axel Wagner <axel.wagner.hh@googlemail.com>
@ -224,6 +246,7 @@ Ayanamist Yang <ayanamist@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org> Aymerick Jéhanne <aymerick@jehanne.org>
Azat Kaumov <kaumov.a.r@gmail.com> Azat Kaumov <kaumov.a.r@gmail.com>
Baiju Muthukadan <baiju.m.mail@gmail.com> Baiju Muthukadan <baiju.m.mail@gmail.com>
Balaram Makam <bmakam.qdt@qualcommdatacenter.com>
Balazs Lecz <leczb@google.com> Balazs Lecz <leczb@google.com>
Baokun Lee <nototon@gmail.com> Baokun Lee <nototon@gmail.com>
Bartosz Grzybowski <melkorm@gmail.com> Bartosz Grzybowski <melkorm@gmail.com>
@ -233,6 +256,7 @@ Ben Burkert <ben@benburkert.com>
Ben Eitzen <eitzenb@golang.org> Ben Eitzen <eitzenb@golang.org>
Ben Fried <ben.fried@gmail.com> Ben Fried <ben.fried@gmail.com>
Ben Haines <bhainesva@gmail.com> Ben Haines <bhainesva@gmail.com>
Ben Hoyt <benhoyt@gmail.com>
Ben Laurie <ben@links.org> <benl@google.com> Ben Laurie <ben@links.org> <benl@google.com>
Ben Lubar <ben.lubar@gmail.com> Ben Lubar <ben.lubar@gmail.com>
Ben Lynn <benlynn@gmail.com> Ben Lynn <benlynn@gmail.com>
@ -263,6 +287,7 @@ Blake Mizerany <blake.mizerany@gmail.com>
Blixt <me@blixt.nyc> Blixt <me@blixt.nyc>
Bob Briski <rbriski@gmail.com> Bob Briski <rbriski@gmail.com>
Bob Potter <bobby.potter@gmail.com> Bob Potter <bobby.potter@gmail.com>
Bobby DeSimone <bobbydesimone@gmail.com>
Bobby Powers <bobbypowers@gmail.com> Bobby Powers <bobbypowers@gmail.com>
Boris Nagaev <nagaev@google.com> Boris Nagaev <nagaev@google.com>
Borja Clemente <borja.clemente@gmail.com> Borja Clemente <borja.clemente@gmail.com>
@ -313,6 +338,7 @@ Carlo Alberto Ferraris <cafxx@strayorange.com>
Carlos Castillo <cookieo9@gmail.com> Carlos Castillo <cookieo9@gmail.com>
Carlos Cirello <uldericofilho@gmail.com> Carlos Cirello <uldericofilho@gmail.com>
Carlos Eduardo Seo <cseo@linux.vnet.ibm.com> Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Carlos Souza <carloshrsouza@gmail.com>
Carolyn Van Slyck <me@carolynvanslyck.com> Carolyn Van Slyck <me@carolynvanslyck.com>
Cary Hull <chull@google.com> Cary Hull <chull@google.com>
Case Nelson <case.nelson@gmail.com> Case Nelson <case.nelson@gmail.com>
@ -324,7 +350,9 @@ Cedric Staub <cs@squareup.com>
Cezar Sá Espinola <cezarsa@gmail.com> Cezar Sá Espinola <cezarsa@gmail.com>
Chad Rosier <mrosier.qdt@qualcommdatacenter.com> Chad Rosier <mrosier.qdt@qualcommdatacenter.com>
ChaiShushan <chaishushan@gmail.com> ChaiShushan <chaishushan@gmail.com>
Channing Kimble-Brown <channing@golang.org>
Charles Fenwick Elliott <Charles@FenwickElliott.io> Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charles Kenney <charlesc.kenney@gmail.com>
Charles L. Dorian <cldorian@gmail.com> Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com> Charles Lee <zombie.fml@gmail.com>
Charles Weill <weill@google.com> Charles Weill <weill@google.com>
@ -355,6 +383,7 @@ Christian Alexander <christian@linux.com>
Christian Couder <chriscool@tuxfamily.org> Christian Couder <chriscool@tuxfamily.org>
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com> Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
Christian Pellegrin <chri@evolware.org> Christian Pellegrin <chri@evolware.org>
Christian R. Petrin <christianpetrin@gmail.com>
Christine Hansmann <chhansmann@gmail.com> Christine Hansmann <chhansmann@gmail.com>
Christoffer Buchholz <christoffer.buchholz@gmail.com> Christoffer Buchholz <christoffer.buchholz@gmail.com>
Christoph Blecker <admin@toph.ca> Christoph Blecker <admin@toph.ca>
@ -371,12 +400,14 @@ Christopher Wedgwood <cw@f00f.org>
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com> Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
Christy Perez <christy@linux.vnet.ibm.com> Christy Perez <christy@linux.vnet.ibm.com>
CL Sung <clsung@gmail.com> <cl_sung@htc.com> CL Sung <clsung@gmail.com> <cl_sung@htc.com>
Clément Chigot <clement.chigot@atos.net>
Clement Skau <clementskau@gmail.com> Clement Skau <clementskau@gmail.com>
Cody Oss <the.cody.oss@gmail.com> Cody Oss <the.cody.oss@gmail.com>
Colby Ranger <cranger@google.com> Colby Ranger <cranger@google.com>
Colin Cross <ccross@android.com> Colin Cross <ccross@android.com>
Colin Edwards <colin@recursivepenguin.com> Colin Edwards <colin@recursivepenguin.com>
Colin Kennedy <moshen.colin@gmail.com> Colin Kennedy <moshen.colin@gmail.com>
Colin Nelson <colnnelson@google.com>
Colin Rice <clr@google.com> Colin Rice <clr@google.com>
Conrad Irwin <conrad.irwin@gmail.com> Conrad Irwin <conrad.irwin@gmail.com>
Conrad Meyer <cemeyer@cs.washington.edu> Conrad Meyer <cemeyer@cs.washington.edu>
@ -401,10 +432,13 @@ Dan Caddigan <goldcaddy77@gmail.com>
Dan Callahan <dan.callahan@gmail.com> Dan Callahan <dan.callahan@gmail.com>
Dan Harrington <harringtond@google.com> Dan Harrington <harringtond@google.com>
Dan Jacques <dnj@google.com> Dan Jacques <dnj@google.com>
Dan Johnson <computerdruid@google.com>
Dan Peterson <dpiddy@gmail.com> Dan Peterson <dpiddy@gmail.com>
Dan Pupius <dan@medium.com> Dan Pupius <dan@medium.com>
Dan Sinclair <dan.sinclair@gmail.com> Dan Sinclair <dan.sinclair@gmail.com>
Daniël de Kok <me@danieldk.eu>
Daniel Fleischman <danielfleischman@gmail.com> Daniel Fleischman <danielfleischman@gmail.com>
Daniel Ingram <ingramds@appstate.edu>
Daniel Johansson <dajo2002@gmail.com> Daniel Johansson <dajo2002@gmail.com>
Daniel Kerwin <d.kerwin@gini.net> Daniel Kerwin <d.kerwin@gini.net>
Daniel Krech <eikeon@eikeon.com> Daniel Krech <eikeon@eikeon.com>
@ -421,6 +455,7 @@ Daniel Upton <daniel@floppy.co>
Daniela Petruzalek <daniela.petruzalek@gmail.com> Daniela Petruzalek <daniela.petruzalek@gmail.com>
Danny Rosseau <daniel.rosseau@gmail.com> Danny Rosseau <daniel.rosseau@gmail.com>
Daria Kolistratova <daria.kolistratova@intel.com> Daria Kolistratova <daria.kolistratova@intel.com>
Darien Raymond <admin@v2ray.com>
Darren Elwood <darren@textnode.com> Darren Elwood <darren@textnode.com>
Darshan Parajuli <parajulidarshan@gmail.com> Darshan Parajuli <parajulidarshan@gmail.com>
Datong Sun <dndx@idndx.com> Datong Sun <dndx@idndx.com>
@ -445,12 +480,15 @@ David du Colombier <0intro@gmail.com>
David Forsythe <dforsythe@gmail.com> David Forsythe <dforsythe@gmail.com>
David G. Andersen <dave.andersen@gmail.com> David G. Andersen <dave.andersen@gmail.com>
David Glasser <glasser@meteor.com> David Glasser <glasser@meteor.com>
David Heuschmann <heuschmann.d@gmail.com>
David Howden <dhowden@gmail.com> David Howden <dhowden@gmail.com>
David Hubbard <dsp@google.com> David Hubbard <dsp@google.com>
David Jakob Fritz <david.jakob.fritz@gmail.com> David Jakob Fritz <david.jakob.fritz@gmail.com>
David Jones <dxjones@gmail.com>
David Lazar <lazard@golang.org> David Lazar <lazard@golang.org>
David Leon Gil <coruus@gmail.com> David Leon Gil <coruus@gmail.com>
David McLeish <davemc@google.com> David McLeish <davemc@google.com>
David Ndungu <dnjuguna@gmail.com>
David NewHamlet <david@newhamlet.com> David NewHamlet <david@newhamlet.com>
David Presotto <presotto@gmail.com> David Presotto <presotto@gmail.com>
David R. Jenni <david.r.jenni@gmail.com> David R. Jenni <david.r.jenni@gmail.com>
@ -458,7 +496,9 @@ David Sansome <me@davidsansome.com>
David Stainton <dstainton415@gmail.com> David Stainton <dstainton415@gmail.com>
David Symonds <dsymonds@golang.org> David Symonds <dsymonds@golang.org>
David Thomas <davidthomas426@gmail.com> David Thomas <davidthomas426@gmail.com>
David Timm <dtimm@pivotal.io>
David Titarenco <david.titarenco@gmail.com> David Titarenco <david.titarenco@gmail.com>
David Tolpin <david.tolpin@gmail.com>
David Url <david@urld.io> David Url <david@urld.io>
David Volquartz Lebech <david@lebech.info> David Volquartz Lebech <david@lebech.info>
David Wimmer <davidlwimmer@gmail.com> David Wimmer <davidlwimmer@gmail.com>
@ -471,6 +511,7 @@ Denis Brandolini <denis.brandolini@gmail.com>
Denis Nagorny <denis.nagorny@intel.com> Denis Nagorny <denis.nagorny@intel.com>
Dennis Kuhnert <mail.kuhnert@gmail.com> Dennis Kuhnert <mail.kuhnert@gmail.com>
Denys Honsiorovskyi <honsiorovskyi@gmail.com> Denys Honsiorovskyi <honsiorovskyi@gmail.com>
Denys Smirnov <denis.smirnov.91@gmail.com>
Derek Buitenhuis <derek.buitenhuis@gmail.com> Derek Buitenhuis <derek.buitenhuis@gmail.com>
Derek Che <drc@yahoo-inc.com> Derek Che <drc@yahoo-inc.com>
Derek McGowan <derek@mcgstyle.net> Derek McGowan <derek@mcgstyle.net>
@ -485,9 +526,11 @@ Dhiru Kholia <dhiru.kholia@gmail.com>
Dhruvdutt Jadhav <dhruvdutt.jadhav@gmail.com> Dhruvdutt Jadhav <dhruvdutt.jadhav@gmail.com>
Di Xiao <dixiao@google.com> Di Xiao <dixiao@google.com>
Didier Spezia <didier.06@gmail.com> Didier Spezia <didier.06@gmail.com>
Diego Siqueira <diego9889@gmail.com>
Dieter Plaetinck <dieter@raintank.io> Dieter Plaetinck <dieter@raintank.io>
Dimitri Sokolyuk <sokolyuk@gmail.com> Dimitri Sokolyuk <sokolyuk@gmail.com>
Dimitri Tcaciuc <dtcaciuc@gmail.com> Dimitri Tcaciuc <dtcaciuc@gmail.com>
Dina Garmash <dgrmsh@gmail.com>
Diogo Pinela <diogoid7400@gmail.com> Diogo Pinela <diogoid7400@gmail.com>
Dirk Gadsden <dirk@esherido.com> Dirk Gadsden <dirk@esherido.com>
Diwaker Gupta <diwakergupta@gmail.com> Diwaker Gupta <diwakergupta@gmail.com>
@ -499,16 +542,21 @@ Dmitriy Shelenin <deemok@googlemail.com> <deemok@gmail.com>
Dmitriy Vyukov <dvyukov@google.com> Dmitriy Vyukov <dvyukov@google.com>
Dmitry Chestnykh <dchest@gmail.com> Dmitry Chestnykh <dchest@gmail.com>
Dmitry Doroginin <doroginin@gmail.com> Dmitry Doroginin <doroginin@gmail.com>
Dmitry Neverov <dmitry.neverov@gmail.com>
Dmitry Savintsev <dsavints@gmail.com> Dmitry Savintsev <dsavints@gmail.com>
Dmitry Yakunin <nonamezeil@gmail.com> Dmitry Yakunin <nonamezeil@gmail.com>
Domen Ipavec <domen@ipavec.net>
Dominic Green <dominicgreen1@gmail.com> Dominic Green <dominicgreen1@gmail.com>
Dominik Honnef <dominik.honnef@gmail.com> Dominik Honnef <dominik.honnef@gmail.com>
Dominik Vogt <vogt@linux.vnet.ibm.com> Dominik Vogt <vogt@linux.vnet.ibm.com>
Don Byington <don@dbyington.com>
Donald Huang <don.hcd@gmail.com> Donald Huang <don.hcd@gmail.com>
Dong-hee Na <donghee.na92@gmail.com> Dong-hee Na <donghee.na92@gmail.com>
Donovan Hide <donovanhide@gmail.com> Donovan Hide <donovanhide@gmail.com>
Doug Anderson <douga@google.com> Doug Anderson <douga@google.com>
Doug Fawley <dfawley@google.com> Doug Fawley <dfawley@google.com>
Douglas Danger Manley <doug.manley@gmail.com>
Drew Flower <drewvanstone@gmail.com>
Drew Hintz <adhintz@google.com> Drew Hintz <adhintz@google.com>
Duncan Holm <mail@frou.org> Duncan Holm <mail@frou.org>
Dustin Carlino <dcarlino@google.com> Dustin Carlino <dcarlino@google.com>
@ -520,6 +568,7 @@ Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
Dylan Waits <dylan@waits.io> Dylan Waits <dylan@waits.io>
Edan Bedrik <3d4nb3@gmail.com> Edan Bedrik <3d4nb3@gmail.com>
Eden Li <eden.li@gmail.com> Eden Li <eden.li@gmail.com>
Eduard Urbach <e.urbach@gmail.com>
Eduardo Ramalho <eduardo.ramalho@gmail.com> Eduardo Ramalho <eduardo.ramalho@gmail.com>
Edward Muller <edwardam@interlix.com> Edward Muller <edwardam@interlix.com>
Egon Elbre <egonelbre@gmail.com> Egon Elbre <egonelbre@gmail.com>
@ -529,7 +578,7 @@ Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com> Elbert Fliek <efliek@gmail.com>
Eldar Rakhimberdin <ibeono@gmail.com> Eldar Rakhimberdin <ibeono@gmail.com>
Elena Grahovac <elena@grahovac.me> Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com> Elias Naur <mail@eliasnaur.com> <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com> Elliot Morrison-Reed <elliotmr@gmail.com>
Emerson Lin <linyintor@gmail.com> Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se> Emil Hessman <emil@hessman.se>
@ -547,6 +596,7 @@ Eric Koleda <ekoleda+devrel@google.com>
Eric Lagergren <ericscottlagergren@gmail.com> Eric Lagergren <ericscottlagergren@gmail.com>
Eric Milliken <emilliken@gmail.com> Eric Milliken <emilliken@gmail.com>
Eric Pauley <eric@pauley.me> Eric Pauley <eric@pauley.me>
Eric Ponce <tricokun@gmail.com>
Eric Rescorla <ekr@rtfm.com> Eric Rescorla <ekr@rtfm.com>
Eric Roshan-Eisner <eric.d.eisner@gmail.com> Eric Roshan-Eisner <eric.d.eisner@gmail.com>
Eric Rykwalder <e.rykwalder@gmail.com> Eric Rykwalder <e.rykwalder@gmail.com>
@ -555,6 +605,7 @@ Erik Dubbelboer <erik@dubbelboer.com>
Erik St. Martin <alakriti@gmail.com> Erik St. Martin <alakriti@gmail.com>
Erik Staab <estaab@google.com> Erik Staab <estaab@google.com>
Erik Westrup <erik.westrup@gmail.com> Erik Westrup <erik.westrup@gmail.com>
Erin Masatsugu <erin.masatsugu@gmail.com>
Ernest Chiang <ernest_chiang@htc.com> Ernest Chiang <ernest_chiang@htc.com>
Erwin Oegema <blablaechthema@hotmail.com> Erwin Oegema <blablaechthema@hotmail.com>
Esko Luontola <esko.luontola@gmail.com> Esko Luontola <esko.luontola@gmail.com>
@ -566,6 +617,7 @@ Evan Broder <evan@stripe.com>
Evan Brown <evanbrown@google.com> Evan Brown <evanbrown@google.com>
Evan Hicks <evan.hicks2@gmail.com> Evan Hicks <evan.hicks2@gmail.com>
Evan Jones <ej@evanjones.ca> Evan Jones <ej@evanjones.ca>
Evan Klitzke <evan@eklitzke.org>
Evan Kroske <evankroske@google.com> Evan Kroske <evankroske@google.com>
Evan Martin <evan.martin@gmail.com> Evan Martin <evan.martin@gmail.com>
Evan Phoenix <evan@phx.io> Evan Phoenix <evan@phx.io>
@ -584,6 +636,7 @@ Fannie Zhang <fannie.zhang@arm.com>
Fatih Arslan <fatih@arslan.io> Fatih Arslan <fatih@arslan.io>
Fazal Majid <majid@apsalar.com> Fazal Majid <majid@apsalar.com>
Fazlul Shahriar <fshahriar@gmail.com> Fazlul Shahriar <fshahriar@gmail.com>
Federico Bond <federicobond@gmail.com>
Federico Simoncelli <fsimonce@redhat.com> Federico Simoncelli <fsimonce@redhat.com>
Fedor Indutny <fedor@indutny.com> Fedor Indutny <fedor@indutny.com>
Felipe Oliveira <felipeweb.programador@gmail.com> Felipe Oliveira <felipeweb.programador@gmail.com>
@ -591,8 +644,10 @@ Felix Geisendörfer <haimuiba@gmail.com>
Felix Kollmann <fk@konsorten.de> Felix Kollmann <fk@konsorten.de>
Filip Gruszczyński <gruszczy@gmail.com> Filip Gruszczyński <gruszczy@gmail.com>
Filip Haglund <drathier@users.noreply.github.com> Filip Haglund <drathier@users.noreply.github.com>
Filip Stanis <fstanis@google.com>
Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io> Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io>
Firmansyah Adiputra <frm.adiputra@gmail.com> Firmansyah Adiputra <frm.adiputra@gmail.com>
Florian Forster <octo@google.com>
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de> Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
Florian Weimer <fw@deneb.enyo.de> Florian Weimer <fw@deneb.enyo.de>
Florin Patan <florinpatan@gmail.com> Florin Patan <florinpatan@gmail.com>
@ -610,9 +665,11 @@ Frederik Ring <frederik.ring@gmail.com>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com> Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com> Fredrik Forsmo <fredrik.forsmo@gmail.com>
Fredrik Wallgren <fredrik.wallgren@gmail.com> Fredrik Wallgren <fredrik.wallgren@gmail.com>
Frew Schmidt <github@frew.co>
Frithjof Schulze <schulze@math.uni-hannover.de> <sfrithjof@gmail.com> Frithjof Schulze <schulze@math.uni-hannover.de> <sfrithjof@gmail.com>
Frits van Bommel <fvbommel@gmail.com> Frits van Bommel <fvbommel@gmail.com>
Fumitoshi Ukai <ukai@google.com> Fumitoshi Ukai <ukai@google.com>
G. Hussain Chinoy <ghchinoy@gmail.com>
Gaal Yahas <gaal@google.com> Gaal Yahas <gaal@google.com>
Gabríel Arthúr Pétursson <gabriel@system.is> Gabríel Arthúr Pétursson <gabriel@system.is>
Gabriel Aszalos <gabriel.aszalos@gmail.com> Gabriel Aszalos <gabriel.aszalos@gmail.com>
@ -627,6 +684,7 @@ Gaurish Sharma <contact@gaurishsharma.com>
Gautham Thambidorai <gautham.dorai@gmail.com> Gautham Thambidorai <gautham.dorai@gmail.com>
Gauthier Jolly <gauthier.jolly@gmail.com> Gauthier Jolly <gauthier.jolly@gmail.com>
Geert-Johan Riemer <gjr19912@gmail.com> Geert-Johan Riemer <gjr19912@gmail.com>
Genevieve Luyt <genevieve.luyt@gmail.com>
Gengliang Wang <ltnwgl@gmail.com> Gengliang Wang <ltnwgl@gmail.com>
Geoff Berry <gberry.qdt@qualcommdatacenter.com> Geoff Berry <gberry.qdt@qualcommdatacenter.com>
Geoffroy Lorieux <lorieux.g@gmail.com> Geoffroy Lorieux <lorieux.g@gmail.com>
@ -634,24 +692,41 @@ Geon Kim <geon0250@gmail.com>
Georg Reinke <guelfey@gmail.com> Georg Reinke <guelfey@gmail.com>
George Gkirtsou <ggirtsou@gmail.com> George Gkirtsou <ggirtsou@gmail.com>
George Shammas <george@shamm.as> <georgyo@gmail.com> George Shammas <george@shamm.as> <georgyo@gmail.com>
Gerasimos (Makis) Maropoulos <kataras2006@hotmail.com>
Gerasimos Dimitriadis <gedimitr@gmail.com> Gerasimos Dimitriadis <gedimitr@gmail.com>
Gergely Brautigam <skarlso777@gmail.com>
Getulio Sánchez <valentin2507@gmail.com> Getulio Sánchez <valentin2507@gmail.com>
Gianguido Sora` <g.sora4@gmail.com>
Gideon Jan-Wessel Redelinghuys <gjredelinghuys@gmail.com> Gideon Jan-Wessel Redelinghuys <gjredelinghuys@gmail.com>
Giles Lean <giles.lean@pobox.com> Giles Lean <giles.lean@pobox.com>
Giovanni Bajo <rasky@develer.com> Giovanni Bajo <rasky@develer.com>
GitHub User @ajnirp (1688456) <ajnirp@users.noreply.github.com> GitHub User @ajnirp (1688456) <ajnirp@users.noreply.github.com>
GitHub User @andrius4669 (4699695) <andrius4669@gmail.com>
GitHub User @as (8127015) <as.utf8@gmail.com> GitHub User @as (8127015) <as.utf8@gmail.com>
GitHub User @bgadrian (830001) <aditza8@gmail.com> GitHub User @bgadrian (830001) <aditza8@gmail.com>
GitHub User @bontequero (2674999) <bontequero@gmail.com> GitHub User @bontequero (2674999) <bontequero@gmail.com>
GitHub User @cch123 (384546) <buaa.cch@gmail.com> GitHub User @cch123 (384546) <buaa.cch@gmail.com>
GitHub User @chanxuehong (3416908) <chanxuehong@gmail.com> GitHub User @chanxuehong (3416908) <chanxuehong@gmail.com>
GitHub User @dupoxy (1143957) <dupoxy@users.noreply.github.com>
GitHub User @erifan (31343225) <eric.fang@arm.com> GitHub User @erifan (31343225) <eric.fang@arm.com>
GitHub User @esell (9735165) <eujon.sellers@gmail.com>
GitHub User @itchyny (375258) <itchyny@hatena.ne.jp>
GitHub User @kc1212 (1093806) <kc1212@users.noreply.github.com>
GitHub User @Kropekk (13366453) <kamilkropiewnicki@gmail.com> GitHub User @Kropekk (13366453) <kamilkropiewnicki@gmail.com>
GitHub User @LotusFenn (13775899) <fenn.lotus@gmail.com>
GitHub User @madiganz (18340029) <zacharywmadigan@gmail.com> GitHub User @madiganz (18340029) <zacharywmadigan@gmail.com>
GitHub User @mkishere (224617) <224617+mkishere@users.noreply.github.com>
GitHub User @OlgaVlPetrova (44112727) <OVPpetrova@gmail.com>
GitHub User @pityonline (438222) <pityonline@gmail.com> GitHub User @pityonline (438222) <pityonline@gmail.com>
GitHub User @pytimer (17105586) <lixin20101023@gmail.com> GitHub User @pytimer (17105586) <lixin20101023@gmail.com>
GitHub User @saitarunreddy (21041941) <saitarunreddypalla@gmail.com>
GitHub User @shogo-ma (9860598) <Choroma194@gmail.com> GitHub User @shogo-ma (9860598) <Choroma194@gmail.com>
GitHub User @tell-k (26263) <ffk2005@gmail.com>
GitHub User @uhei (2116845) <uhei@users.noreply.github.com>
GitHub User @uropek (39370426) <uropek@gmail.com>
Giulio Iotti <dullgiulio@gmail.com> Giulio Iotti <dullgiulio@gmail.com>
Giulio Micheloni <giulio.micheloni@gmail.com>
Giuseppe Valente <gvalente@arista.com>
Gleb Stepanov <glebstepanov1992@gmail.com> Gleb Stepanov <glebstepanov1992@gmail.com>
Glenn Brown <glennb@google.com> Glenn Brown <glennb@google.com>
Glenn Lewis <gmlewis@google.com> Glenn Lewis <gmlewis@google.com>
@ -660,14 +735,17 @@ Graham King <graham4king@gmail.com>
Graham Miller <graham.miller@gmail.com> Graham Miller <graham.miller@gmail.com>
Grant Griffiths <ggp493@gmail.com> Grant Griffiths <ggp493@gmail.com>
Greg Poirier <greg.istehbest@gmail.com> Greg Poirier <greg.istehbest@gmail.com>
Greg Steuck <gnezdo+github@google.com>
Greg Ward <greg@gerg.ca> Greg Ward <greg@gerg.ca>
Grégoire Delattre <gregoire.delattre@gmail.com> Grégoire Delattre <gregoire.delattre@gmail.com>
Gregory Man <man.gregory@gmail.com> Gregory Man <man.gregory@gmail.com>
Guilherme Caruso <gui.martinscaruso@gmail.com>
Guilherme Garnier <guilherme.garnier@gmail.com> Guilherme Garnier <guilherme.garnier@gmail.com>
Guilherme Goncalves <guilhermeaugustosg@gmail.com> Guilherme Goncalves <guilhermeaugustosg@gmail.com>
Guilherme Rezende <guilhermebr@gmail.com> Guilherme Rezende <guilhermebr@gmail.com>
Guillaume J. Charmes <guillaume@charmes.net> Guillaume J. Charmes <guillaume@charmes.net>
Guobiao Mei <meiguobiao@gmail.com> Guobiao Mei <meiguobiao@gmail.com>
Guoliang Wang <iamwgliang@gmail.com>
Gustav Paul <gustav.paul@gmail.com> Gustav Paul <gustav.paul@gmail.com>
Gustav Westling <gustav@westling.xyz> Gustav Westling <gustav@westling.xyz>
Gustavo Franco <gustavorfranco@gmail.com> Gustavo Franco <gustavorfranco@gmail.com>
@ -702,6 +780,7 @@ Henry Clifford <h.a.clifford@gmail.com>
Herbert Georg Fischer <herbert.fischer@gmail.com> Herbert Georg Fischer <herbert.fischer@gmail.com>
Herbie Ong <herbie@google.com> Herbie Ong <herbie@google.com>
Heschi Kreinick <heschi@google.com> Heschi Kreinick <heschi@google.com>
Hidetatsu Yaginuma <ygnmhdtt@gmail.com>
Hilko Bengen <bengen@hilluzination.de> Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com> Hiroaki Nakamura <hnakamur@gmail.com>
Hironao OTSUBO <motemen@gmail.com> Hironao OTSUBO <motemen@gmail.com>
@ -715,11 +794,16 @@ Hsin Tsao <tsao@google.com>
Hsin-Ho Yeh <yhh92u@gmail.com> Hsin-Ho Yeh <yhh92u@gmail.com>
Hu Keping <hukeping@huawei.com> Hu Keping <hukeping@huawei.com>
Hugues Bruant <hugues.bruant@gmail.com> Hugues Bruant <hugues.bruant@gmail.com>
Huy Le <huy.dinh.le.89@gmail.com>
Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com> Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
Ian Cottrell <iancottrell@google.com> Ian Cottrell <iancottrell@google.com>
Ian Davis <nospam@iandavis.com>
Ian Gudger <ian@loosescre.ws> Ian Gudger <ian@loosescre.ws>
Ian Haken <ihaken@netflix.com>
Ian Kent <iankent85@gmail.com> Ian Kent <iankent85@gmail.com>
Ian Lance Taylor <iant@golang.org> Ian Lance Taylor <iant@golang.org>
Ian Leue <ian@appboy.com>
Ian Zapolsky <ianzapolsky@gmail.com>
Ibrahim AshShohail <ibra.sho@gmail.com> Ibrahim AshShohail <ibra.sho@gmail.com>
Icarus Sparry <golang@icarus.freeuk.com> Icarus Sparry <golang@icarus.freeuk.com>
Iccha Sethi <icchasethi@gmail.com> Iccha Sethi <icchasethi@gmail.com>
@ -727,6 +811,7 @@ Idora Shinatose <idora.shinatose@gmail.com>
Igor Bernstein <igorbernstein@google.com> Igor Bernstein <igorbernstein@google.com>
Igor Dolzhikov <bluesriverz@gmail.com> Igor Dolzhikov <bluesriverz@gmail.com>
Igor Vashyst <ivashyst@gmail.com> Igor Vashyst <ivashyst@gmail.com>
Igor Zhilianin <igor.zhilianin@gmail.com>
Ilya Tocar <ilya.tocar@intel.com> Ilya Tocar <ilya.tocar@intel.com>
INADA Naoki <songofacandy@gmail.com> INADA Naoki <songofacandy@gmail.com>
Inanc Gumus <m@inanc.io> Inanc Gumus <m@inanc.io>
@ -743,9 +828,12 @@ Issac Trotts <issactrotts@google.com>
Ivan Babrou <ivan@cloudflare.com> Ivan Babrou <ivan@cloudflare.com>
Ivan Bertona <ivan.bertona@gmail.com> Ivan Bertona <ivan.bertona@gmail.com>
Ivan Krasin <krasin@golang.org> Ivan Krasin <krasin@golang.org>
Ivan Kutuzov <arbrix@gmail.com>
Ivan Markin <sw@nogoegst.net> Ivan Markin <sw@nogoegst.net>
Ivan Moscoso <moscoso@gmail.com> Ivan Moscoso <moscoso@gmail.com>
Ivan Sharavuev <shpiwan@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com> Ivan Ukhov <ivan.ukhov@gmail.com>
Ivy Evans <ivy@ivyevans.net>
Jaana Burcu Dogan <jbd@google.com> <jbd@golang.org> <burcujdogan@gmail.com> Jaana Burcu Dogan <jbd@google.com> <jbd@golang.org> <burcujdogan@gmail.com>
Jack Britton <jackxbritton@gmail.com> Jack Britton <jackxbritton@gmail.com>
Jack Lindamood <jlindamo@justin.tv> Jack Lindamood <jlindamo@justin.tv>
@ -753,6 +841,7 @@ Jacob Baskin <jbaskin@google.com>
Jacob H. Haven <jacob@cloudflare.com> Jacob H. Haven <jacob@cloudflare.com>
Jacob Hoffman-Andrews <github@hoffman-andrews.com> Jacob Hoffman-Andrews <github@hoffman-andrews.com>
Jae Kwon <jae@tendermint.com> Jae Kwon <jae@tendermint.com>
Jake B <doogie1012@gmail.com>
Jakob Borg <jakob@nym.se> Jakob Borg <jakob@nym.se>
Jakob Weisblat <jakobw@mit.edu> Jakob Weisblat <jakobw@mit.edu>
Jakub Čajka <jcajka@redhat.com> Jakub Čajka <jcajka@redhat.com>
@ -762,6 +851,7 @@ James Bardin <j.bardin@gmail.com>
James Chacon <jchacon@google.com> James Chacon <jchacon@google.com>
James Clarke <jrtc27@jrtc27.com> James Clarke <jrtc27@jrtc27.com>
James Cowgill <James.Cowgill@imgtec.com> James Cowgill <James.Cowgill@imgtec.com>
James Craig Burley <james-github@burleyarch.com>
James David Chalfant <james.chalfant@gmail.com> James David Chalfant <james.chalfant@gmail.com>
James Fysh <james.fysh@gmail.com> James Fysh <james.fysh@gmail.com>
James Gray <james@james4k.com> James Gray <james@james4k.com>
@ -804,12 +894,15 @@ Jason Buberel <jbuberel@google.com>
Jason Chu <jasonchujc@gmail.com> Jason Chu <jasonchujc@gmail.com>
Jason Del Ponte <delpontej@gmail.com> Jason Del Ponte <delpontej@gmail.com>
Jason Hall <jasonhall@google.com> Jason Hall <jasonhall@google.com>
Jason Keene <jasonkeene@gmail.com>
Jason LeBrun <jblebrun@gmail.com>
Jason Smale <jsmale@zendesk.com> Jason Smale <jsmale@zendesk.com>
Jason Travis <infomaniac7@gmail.com> Jason Travis <infomaniac7@gmail.com>
Jason Wangsadinata <jwangsadinata@gmail.com> Jason Wangsadinata <jwangsadinata@gmail.com>
Javier Kohen <jkohen@google.com> Javier Kohen <jkohen@google.com>
Javier Segura <javism@gmail.com> Javier Segura <javism@gmail.com>
Jay Conrod <jayconrod@google.com> Jay Conrod <jayconrod@google.com>
Jay Taylor <outtatime@gmail.com>
Jay Weisskopf <jay@jayschwa.net> Jay Weisskopf <jay@jayschwa.net>
Jean de Klerk <deklerk@google.com> Jean de Klerk <deklerk@google.com>
Jean-André Santoni <jean.andre.santoni@gmail.com> Jean-André Santoni <jean.andre.santoni@gmail.com>
@ -831,6 +924,8 @@ Jeffrey H <jeffreyh192@gmail.com>
Jelte Fennema <github-tech@jeltef.nl> Jelte Fennema <github-tech@jeltef.nl>
Jens Frederich <jfrederich@gmail.com> Jens Frederich <jfrederich@gmail.com>
Jeremiah Harmsen <jeremiah@google.com> Jeremiah Harmsen <jeremiah@google.com>
Jeremy Banks <_@jeremy.ca>
Jeremy Canady <jcanady@gmail.com>
Jeremy Jackins <jeremyjackins@gmail.com> Jeremy Jackins <jeremyjackins@gmail.com>
Jeremy Schlatter <jeremy.schlatter@gmail.com> Jeremy Schlatter <jeremy.schlatter@gmail.com>
Jeroen Bobbeldijk <jerbob92@gmail.com> Jeroen Bobbeldijk <jerbob92@gmail.com>
@ -854,6 +949,7 @@ Jiong Du <londevil@gmail.com>
Jirka Daněk <dnk@mail.muni.cz> Jirka Daněk <dnk@mail.muni.cz>
Jiulong Wang <jiulongw@gmail.com> Jiulong Wang <jiulongw@gmail.com>
Joakim Sernbrant <serbaut@gmail.com> Joakim Sernbrant <serbaut@gmail.com>
Joe Bowbeer <joe.bowbeer@gmail.com>
Joe Cortopassi <joe@joecortopassi.com> Joe Cortopassi <joe@joecortopassi.com>
Joe Farrell <joe2farrell@gmail.com> Joe Farrell <joe2farrell@gmail.com>
Joe Harrison <joehazzers@gmail.com> Joe Harrison <joehazzers@gmail.com>
@ -877,6 +973,7 @@ John C Barstow <jbowtie@amathaine.com>
John DeNero <denero@google.com> John DeNero <denero@google.com>
John Dethridge <jcd@golang.org> John Dethridge <jcd@golang.org>
John Gibb <johngibb@gmail.com> John Gibb <johngibb@gmail.com>
John Gilik <john@jgilik.com>
John Graham-Cumming <jgc@jgc.org> <jgrahamc@gmail.com> John Graham-Cumming <jgc@jgc.org> <jgrahamc@gmail.com>
John Howard Palevich <jack.palevich@gmail.com> John Howard Palevich <jack.palevich@gmail.com>
John Jeffery <jjeffery@sp.com.au> John Jeffery <jjeffery@sp.com.au>
@ -910,6 +1007,7 @@ Joonas Kuorilehto <joneskoo@derbian.fi>
Joop Kiefte <ikojba@gmail.com> <joop@kiefte.net> Joop Kiefte <ikojba@gmail.com> <joop@kiefte.net>
Jordan Krage <jmank88@gmail.com> Jordan Krage <jmank88@gmail.com>
Jordan Lewis <jordanthelewis@gmail.com> Jordan Lewis <jordanthelewis@gmail.com>
Jordan Rhee <jordanrh@microsoft.com>
Jos Visser <josv@google.com> Jos Visser <josv@google.com>
Jose Luis Vázquez González <josvazg@gmail.com> Jose Luis Vázquez González <josvazg@gmail.com>
Joseph Bonneau <jcb@google.com> Joseph Bonneau <jcb@google.com>
@ -930,12 +1028,15 @@ Jostein Stuhaug <js@solidsystem.no>
JP Sugarbroad <jpsugar@google.com> JP Sugarbroad <jpsugar@google.com>
JT Olds <jtolds@xnet5.com> JT Olds <jtolds@xnet5.com>
Juan Carlos <juanjcsr@gmail.com> Juan Carlos <juanjcsr@gmail.com>
Juan Pablo Civile <elementohb@gmail.com>
Jude Pereira <judebpereira@gmail.com> Jude Pereira <judebpereira@gmail.com>
Jukka-Pekka Kekkonen <karatepekka@gmail.com> Jukka-Pekka Kekkonen <karatepekka@gmail.com>
Julia Hansbrough <flowerhack@google.com> Julia Hansbrough <flowerhack@google.com>
Julian Kornberger <jk+github@digineo.de> Julian Kornberger <jk+github@digineo.de>
Julian Pastarmov <pastarmovj@google.com> Julian Pastarmov <pastarmovj@google.com>
Julian Phillips <julian@quantumfyre.co.uk> Julian Phillips <julian@quantumfyre.co.uk>
Julie Qiu <julie@golang.org>
Julien Kauffmann <julien.kauffmann@freelan.org>
Julien Salleyron <julien.salleyron@gmail.com> Julien Salleyron <julien.salleyron@gmail.com>
Julien Schmidt <google@julienschmidt.com> Julien Schmidt <google@julienschmidt.com>
Julio Montes <julio.montes@intel.com> Julio Montes <julio.montes@intel.com>
@ -961,10 +1062,12 @@ Karoly Negyesi <chx1975@gmail.com>
Karsten Köhler <karsten.koehler95@gmail.com> Karsten Köhler <karsten.koehler95@gmail.com>
Kashav Madan <kshvmdn@gmail.com> Kashav Madan <kshvmdn@gmail.com>
Kate Manson <kate.manson@izettle.com> Kate Manson <kate.manson@izettle.com>
Katie Hockman <katie@golang.org>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com> Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
Katrina Owen <katrina.owen@gmail.com> Katrina Owen <katrina.owen@gmail.com>
Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com> Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com>
Kay Zhu <kayzhu@google.com> Kay Zhu <kayzhu@google.com>
Kazuhiro Sera <seratch@gmail.com>
KB Sriram <kbsriram@google.com> KB Sriram <kbsriram@google.com>
Keegan Carruthers-Smith <keegan.csmith@gmail.com> Keegan Carruthers-Smith <keegan.csmith@gmail.com>
Kei Son <hey.calmdown@gmail.com> Kei Son <hey.calmdown@gmail.com>
@ -989,6 +1092,7 @@ Kevin Klues <klueska@gmail.com> <klueska@google.com>
Kevin Malachowski <chowski@google.com> Kevin Malachowski <chowski@google.com>
Kevin Ruffin <kruffin@gmail.com> Kevin Ruffin <kruffin@gmail.com>
Kevin Vu <kevin.m.vu@gmail.com> Kevin Vu <kevin.m.vu@gmail.com>
Kevin Zita <bleedgreenandgold@gmail.com>
Kieran Colford <kieran@kcolford.com> Kieran Colford <kieran@kcolford.com>
Kim Shrier <kshrier@racktopsystems.com> Kim Shrier <kshrier@racktopsystems.com>
Kim Yongbin <kybinz@gmail.com> Kim Yongbin <kybinz@gmail.com>
@ -1000,6 +1104,7 @@ Klaus Post <klauspost@gmail.com>
Kodie Goodwin <kodiegoodwin@gmail.com> Kodie Goodwin <kodiegoodwin@gmail.com>
Koichi Shiraishi <zchee.io@gmail.com> Koichi Shiraishi <zchee.io@gmail.com>
Koki Ide <niconegoto@yahoo.co.jp> Koki Ide <niconegoto@yahoo.co.jp>
Komu Wairagu <komuw05@gmail.com>
Konstantin <konstantin8105@gmail.com> Konstantin <konstantin8105@gmail.com>
Konstantin Shaposhnikov <k.shaposhnikov@gmail.com> Konstantin Shaposhnikov <k.shaposhnikov@gmail.com>
Kris Kwiatkowski <kris@cloudflare.com> Kris Kwiatkowski <kris@cloudflare.com>
@ -1015,13 +1120,16 @@ Kyle Jones <kyle@kyledj.com>
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com> Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
Kyle Shannon <kyle@pobox.com> Kyle Shannon <kyle@pobox.com>
Kyle Spiers <eiais@google.com> Kyle Spiers <eiais@google.com>
Kyle Wood <kyle@kylewood.cc>
Kyohei Kadota <lufia@lufia.org> Kyohei Kadota <lufia@lufia.org>
Kyrylo Silin <silin@kyrylo.org> Kyrylo Silin <silin@kyrylo.org>
L Campbell <unpantsu@gmail.com> L Campbell <unpantsu@gmail.com>
Lai Jiangshan <eag0628@gmail.com> Lai Jiangshan <eag0628@gmail.com>
Lajos Papp <lalyos@yahoo.com>
Lakshay Garg <lakshay.garg.1996@gmail.com> Lakshay Garg <lakshay.garg.1996@gmail.com>
Lann Martin <lannm@google.com> Lann Martin <lannm@google.com>
Lanre Adelowo <yo@lanre.wtf> Lanre Adelowo <yo@lanre.wtf>
Larry Clapp <larry@theclapp.org>
Larry Hosken <lahosken@golang.org> Larry Hosken <lahosken@golang.org>
Lars Jeppesen <jeppesen.lars@gmail.com> Lars Jeppesen <jeppesen.lars@gmail.com>
Lars Lehtonen <lars.lehtonen@gmail.com> Lars Lehtonen <lars.lehtonen@gmail.com>
@ -1066,9 +1174,11 @@ Luuk van Dijk <lvd@golang.org> <lvd@google.com>
Lyle Franklin <lylejfranklin@gmail.com> Lyle Franklin <lylejfranklin@gmail.com>
Lynn Boger <laboger@linux.vnet.ibm.com> Lynn Boger <laboger@linux.vnet.ibm.com>
Ma Peiqi <mapeiqi2017@gmail.com> Ma Peiqi <mapeiqi2017@gmail.com>
Maarten Bezemer <maarten.bezemer@gmail.com>
Maciej Dębski <maciejd@google.com> Maciej Dębski <maciejd@google.com>
Magnus Hiie <magnus.hiie@gmail.com> Magnus Hiie <magnus.hiie@gmail.com>
Maicon Costa <maiconscosta@gmail.com> Maicon Costa <maiconscosta@gmail.com>
Mak Kolybabi <mak@kolybabi.com>
Maksym Trykur <maksym.trykur@gmail.com> Maksym Trykur <maksym.trykur@gmail.com>
Mal Curtis <mal@mal.co.nz> Mal Curtis <mal@mal.co.nz>
Manfred Touron <m@42.am> Manfred Touron <m@42.am>
@ -1086,6 +1196,7 @@ Marcel van Lohuizen <mpvl@golang.org>
Marcelo Cantos <marcelo.cantos@gmail.com> Marcelo Cantos <marcelo.cantos@gmail.com>
Marcelo E. Magallon <marcelo.magallon@gmail.com> Marcelo E. Magallon <marcelo.magallon@gmail.com>
Marco Hennings <marco.hennings@freiheit.com> Marco Hennings <marco.hennings@freiheit.com>
Marcus Willock <crazcalm@gmail.com>
Marga Manterola <marga@google.com> Marga Manterola <marga@google.com>
Marin Bašić <marin.basic02@gmail.com> Marin Bašić <marin.basic02@gmail.com>
Mario Arranz <marioarranzr@gmail.com> Mario Arranz <marioarranzr@gmail.com>
@ -1102,12 +1213,14 @@ Mark Theunissen <mark.theunissen@gmail.com>
Mark Wolfe <mark@wolfe.id.au> Mark Wolfe <mark@wolfe.id.au>
Mark Zavislak <zavislak@google.com> Mark Zavislak <zavislak@google.com>
Marko Juhani Silokunnas <marko.silokunnas@gmail.com> Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
Marko Kevac <marko@kevac.org>
Marko Mikulicic <mkm@google.com> Marko Mikulicic <mkm@google.com>
Marko Mudrinic <mudrinic.mare@gmail.com> Marko Mudrinic <mudrinic.mare@gmail.com>
Marko Tiikkaja <marko@joh.to> Marko Tiikkaja <marko@joh.to>
Markus Duft <markus.duft@salomon.at> Markus Duft <markus.duft@salomon.at>
Markus Sonderegger <marraison@gmail.com> Markus Sonderegger <marraison@gmail.com>
Markus Zimmermann <zimmski@gmail.com> Markus Zimmermann <zimmski@gmail.com>
Marten Seemann <martenseemann@gmail.com>
Martin Bertschler <mbertschler@gmail.com> Martin Bertschler <mbertschler@gmail.com>
Martin Garton <garton@gmail.com> Martin Garton <garton@gmail.com>
Martin Habbecke <marhab@google.com> Martin Habbecke <marhab@google.com>
@ -1122,6 +1235,7 @@ Martin Olsen <github.com@martinolsen.net>
Martin Olsson <martin@minimum.se> Martin Olsson <martin@minimum.se>
Martin Probst <martin@probst.io> Martin Probst <martin@probst.io>
Martin Sucha <anty.sk+git@gmail.com> Martin Sucha <anty.sk+git@gmail.com>
Martin Tournoij <martin@arp242.net>
Martins Sipenko <martins.sipenko@gmail.com> Martins Sipenko <martins.sipenko@gmail.com>
Martynas Budriūnas <mabu@google.com> Martynas Budriūnas <mabu@google.com>
Marvin Stenger <marvin.stenger94@gmail.com> Marvin Stenger <marvin.stenger94@gmail.com>
@ -1165,31 +1279,37 @@ Matthew Dempsky <mdempsky@google.com>
Matthew Denton <mdenton@skyportsystems.com> Matthew Denton <mdenton@skyportsystems.com>
Matthew Holt <Matthew.Holt+git@gmail.com> Matthew Holt <Matthew.Holt+git@gmail.com>
Matthew Horsnell <matthew.horsnell@gmail.com> Matthew Horsnell <matthew.horsnell@gmail.com>
Matthew Waters <mwwaters@gmail.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com> Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu Olivier <olivier.matthieu@gmail.com> Matthieu Olivier <olivier.matthieu@gmail.com>
Matthijs Kooijman <matthijs@stdin.nl> Matthijs Kooijman <matthijs@stdin.nl>
Max Riveiro <kavu13@gmail.com> Max Riveiro <kavu13@gmail.com>
Max Schmitt <max@schmitt.mx> Max Schmitt <max@schmitt.mx>
Max Ushakov <ushmax@gmail.com>
Maxim Khitrov <max@mxcrypt.com> Maxim Khitrov <max@mxcrypt.com>
Maxim Pimenov <mpimenov@google.com> Maxim Pimenov <mpimenov@google.com>
Maxim Ushakov <ushakov@google.com> Maxim Ushakov <ushakov@google.com>
Maxime de Roucy <maxime.deroucy@gmail.com> Maxime de Roucy <maxime.deroucy@gmail.com>
Máximo Cuadros Ortiz <mcuadros@gmail.com> Máximo Cuadros Ortiz <mcuadros@gmail.com>
Maxwell Krohn <themax@gmail.com> Maxwell Krohn <themax@gmail.com>
Maya Rashish <maya@NetBSD.org>
Mayank Kumar <krmayankk@gmail.com> Mayank Kumar <krmayankk@gmail.com>
Meir Fischer <meirfischer@gmail.com> Meir Fischer <meirfischer@gmail.com>
Meng Zhuo <mengzhuo1203@gmail.com> Meng Zhuo <mengzhuo1203@gmail.com>
Mhd Sulhan <m.shulhan@gmail.com> Mhd Sulhan <m.shulhan@gmail.com>
Micah Stetson <micah.stetson@gmail.com> Micah Stetson <micah.stetson@gmail.com>
Michael Anthony Knyszek <mknyszek@google.com>
Michael Brandenburg <mbrandenburg@bolste.com> Michael Brandenburg <mbrandenburg@bolste.com>
Michael Chaten <mchaten@gmail.com> Michael Chaten <mchaten@gmail.com>
Michael Darakananda <pongad@google.com> Michael Darakananda <pongad@google.com>
Michael Dorner <mail@michaeldorner.de> Michael Dorner <mail@michaeldorner.de>
Michael Edwards <medwards@walledcity.ca> Michael Edwards <medwards@walledcity.ca>
Michael Elkins <michael.elkins@gmail.com> Michael Elkins <michael.elkins@gmail.com>
Michael Ellis <micellis@justin.tv>
Michael Fraenkel <michael.fraenkel@gmail.com> Michael Fraenkel <michael.fraenkel@gmail.com>
Michael Fromberger <michael.j.fromberger@gmail.com> Michael Fromberger <michael.j.fromberger@gmail.com>
Michael Gehring <mg@ebfe.org> <gnirheg.leahcim@gmail.com> Michael Gehring <mg@ebfe.org> <gnirheg.leahcim@gmail.com>
Michael Henderson <mdhender@users.noreply.github.com>
Michael Hendricks <michael@ndrix.org> Michael Hendricks <michael@ndrix.org>
Michael Hoisie <hoisie@gmail.com> Michael Hoisie <hoisie@gmail.com>
Michael Hudson-Doyle <michael.hudson@linaro.org> Michael Hudson-Doyle <michael.hudson@linaro.org>
@ -1214,18 +1334,21 @@ Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
Michael Steinert <mike.steinert@gmail.com> Michael Steinert <mike.steinert@gmail.com>
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com> Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com> Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
Michael Traver <mtraver@google.com>
Michael Vetter <g.bluehut@gmail.com> Michael Vetter <g.bluehut@gmail.com>
Michal Bohuslávek <mbohuslavek@gmail.com> Michal Bohuslávek <mbohuslavek@gmail.com>
Michal Cierniak <cierniak@google.com> Michal Cierniak <cierniak@google.com>
Michał Derkacz <ziutek@lnet.pl> Michał Derkacz <ziutek@lnet.pl>
Michal Franc <lam.michal.franc@gmail.com> Michal Franc <lam.michal.franc@gmail.com>
Michal Pristas <michal.pristas@gmail.com> Michal Pristas <michal.pristas@gmail.com>
Michal Rostecki <mrostecki@suse.de>
Michalis Kargakis <michaliskargakis@gmail.com> Michalis Kargakis <michaliskargakis@gmail.com>
Michel Lespinasse <walken@google.com> Michel Lespinasse <walken@google.com>
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com> Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
Miguel Mendez <stxmendez@gmail.com> Miguel Mendez <stxmendez@gmail.com>
Miguel Molina <hi@mvader.me> Miguel Molina <hi@mvader.me>
Mihai Borobocea <MihaiBorobocea@gmail.com> Mihai Borobocea <MihaiBorobocea@gmail.com>
Mihai Todor <todormihai@gmail.com>
Mihail Minaev <minaev.mike@gmail.com> Mihail Minaev <minaev.mike@gmail.com>
Mikael Tillenius <mikti42@gmail.com> Mikael Tillenius <mikti42@gmail.com>
Mike Andrews <mra@xoba.com> Mike Andrews <mra@xoba.com>
@ -1244,6 +1367,7 @@ Mikhail Panchenko <m@mihasya.com>
Miki Tebeka <miki.tebeka@gmail.com> Miki Tebeka <miki.tebeka@gmail.com>
Mikio Hara <mikioh.mikioh@gmail.com> Mikio Hara <mikioh.mikioh@gmail.com>
Mikkel Krautz <mikkel@krautz.dk> <krautz@gmail.com> Mikkel Krautz <mikkel@krautz.dk> <krautz@gmail.com>
Mikołaj Baranowski <mikolajb@gmail.com>
Milan Knezevic <milan.knezevic@mips.com> Milan Knezevic <milan.knezevic@mips.com>
Milutin Jovanović <jovanovic.milutin@gmail.com> Milutin Jovanović <jovanovic.milutin@gmail.com>
MinJae Kwon <mingrammer@gmail.com> MinJae Kwon <mingrammer@gmail.com>
@ -1286,6 +1410,7 @@ Niall Sheridan <nsheridan@gmail.com>
Nic Day <nic.day@me.com> Nic Day <nic.day@me.com>
Nicholas Katsaros <nick@nickkatsaros.com> Nicholas Katsaros <nick@nickkatsaros.com>
Nicholas Maniscalco <nicholas@maniscalco.com> Nicholas Maniscalco <nicholas@maniscalco.com>
Nicholas Ng <nickng@nickng.io>
Nicholas Presta <nick@nickpresta.ca> <nick1presta@gmail.com> Nicholas Presta <nick@nickpresta.ca> <nick1presta@gmail.com>
Nicholas Sullivan <nicholas.sullivan@gmail.com> Nicholas Sullivan <nicholas.sullivan@gmail.com>
Nicholas Waples <nwaples@gmail.com> Nicholas Waples <nwaples@gmail.com>
@ -1326,12 +1451,15 @@ Oleg Vakheta <helginet@gmail.com>
Oleku Konko <oleku.konko@gmail.com> Oleku Konko <oleku.konko@gmail.com>
Oling Cat <olingcat@gmail.com> Oling Cat <olingcat@gmail.com>
Oliver Hookins <ohookins@gmail.com> Oliver Hookins <ohookins@gmail.com>
Oliver Stenbom <ostenbom@pivotal.io>
Oliver Tonnhofer <olt@bogosoft.com> Oliver Tonnhofer <olt@bogosoft.com>
Olivier Antoine <olivier.antoine@gmail.com> Olivier Antoine <olivier.antoine@gmail.com>
Olivier Duperray <duperray.olivier@gmail.com> Olivier Duperray <duperray.olivier@gmail.com>
Olivier Poitrey <rs@dailymotion.com> Olivier Poitrey <rs@dailymotion.com>
Olivier Saingre <osaingre@gmail.com> Olivier Saingre <osaingre@gmail.com>
Omar Jarjur <ojarjur@google.com> Omar Jarjur <ojarjur@google.com>
Oryan Moshe <iamoryanmoshe@gmail.com>
Osamu TONOMORI <osamingo@gmail.com>
Özgür Kesim <oec-go@kesim.org> Özgür Kesim <oec-go@kesim.org>
Pablo Lalloni <plalloni@gmail.com> Pablo Lalloni <plalloni@gmail.com>
Pablo Rozas Larraondo <pablo.larraondo@anu.edu.au> Pablo Rozas Larraondo <pablo.larraondo@anu.edu.au>
@ -1341,6 +1469,7 @@ Pallat Anchaleechamaikorn <yod.pallat@gmail.com>
Paolo Giarrusso <p.giarrusso@gmail.com> Paolo Giarrusso <p.giarrusso@gmail.com>
Paolo Martini <mrtnpaolo@gmail.com> Paolo Martini <mrtnpaolo@gmail.com>
Parker Moore <parkrmoore@gmail.com> Parker Moore <parkrmoore@gmail.com>
Parminder Singh <parmsingh101@gmail.com>
Pascal S. de Kloe <pascal@quies.net> Pascal S. de Kloe <pascal@quies.net>
Pat Moroney <pat@pat.email> Pat Moroney <pat@pat.email>
Patrick Crosby <patrick@stathat.com> Patrick Crosby <patrick@stathat.com>
@ -1360,6 +1489,7 @@ Paul Hammond <paul@paulhammond.org>
Paul Hankin <paulhankin@google.com> Paul Hankin <paulhankin@google.com>
Paul Jolly <paul@myitcv.org.uk> Paul Jolly <paul@myitcv.org.uk>
Paul Lalonde <paul.a.lalonde@gmail.com> Paul Lalonde <paul.a.lalonde@gmail.com>
Paul M Furley <paul@paulfurley.com>
Paul Marks <pmarks@google.com> Paul Marks <pmarks@google.com>
Paul Meyer <paul.meyer@microsoft.com> Paul Meyer <paul.meyer@microsoft.com>
Paul Nasrat <pnasrat@google.com> Paul Nasrat <pnasrat@google.com>
@ -1386,8 +1516,10 @@ Peter Armitage <peter.armitage@gmail.com>
Peter Bourgon <peter@bourgon.org> Peter Bourgon <peter@bourgon.org>
Peter Collingbourne <pcc@google.com> Peter Collingbourne <pcc@google.com>
Peter Conerly <pconerly@gmail.com> Peter Conerly <pconerly@gmail.com>
Peter Dotchev <dotchev@gmail.com>
Peter Froehlich <peter.hans.froehlich@gmail.com> Peter Froehlich <peter.hans.froehlich@gmail.com>
Peter Gonda <pgonda@google.com> Peter Gonda <pgonda@google.com>
Peter Hoyes <pahoyes@gmail.com>
Peter Kleiweg <pkleiweg@xs4all.nl> Peter Kleiweg <pkleiweg@xs4all.nl>
Peter McKenzie <petermck@google.com> Peter McKenzie <petermck@google.com>
Peter Moody <pmoody@uber.com> Peter Moody <pmoody@uber.com>
@ -1421,11 +1553,13 @@ Piers <google@hellopiers.pro>
Pieter Droogendijk <pieter@binky.org.uk> Pieter Droogendijk <pieter@binky.org.uk>
Pietro Gagliardi <pietro10@mac.com> Pietro Gagliardi <pietro10@mac.com>
Piyush Mishra <piyush@codeitout.com> Piyush Mishra <piyush@codeitout.com>
Plekhanov Maxim <kishtatix@gmail.com>
Pontus Leitzler <leitzler@gmail.com> Pontus Leitzler <leitzler@gmail.com>
Prasanna Swaminathan <prasanna@mediamath.com> Prasanna Swaminathan <prasanna@mediamath.com>
Prashant Varanasi <prashant@prashantv.com> Prashant Varanasi <prashant@prashantv.com>
Pravendra Singh <hackpravj@gmail.com> Pravendra Singh <hackpravj@gmail.com>
Preetam Jinka <pj@preet.am> Preetam Jinka <pj@preet.am>
Qais Patankar <qaisjp@gmail.com>
Qiuxuan Zhu <ilsh1022@gmail.com> Qiuxuan Zhu <ilsh1022@gmail.com>
Quan Tran <qeed.quan@gmail.com> Quan Tran <qeed.quan@gmail.com>
Quan Yong Zhai <qyzhai@gmail.com> Quan Yong Zhai <qyzhai@gmail.com>
@ -1433,10 +1567,12 @@ Quentin Perez <qperez@ocs.online.net>
Quentin Renard <contact@asticode.com> Quentin Renard <contact@asticode.com>
Quentin Smith <quentin@golang.org> Quentin Smith <quentin@golang.org>
Quinn Slack <sqs@sourcegraph.com> Quinn Slack <sqs@sourcegraph.com>
Quinten Yearsley <qyearsley@chromium.org>
Quoc-Viet Nguyen <afelion@gmail.com> Quoc-Viet Nguyen <afelion@gmail.com>
Radek Sohlich <sohlich@gmail.com> Radek Sohlich <sohlich@gmail.com>
Radu Berinde <radu@cockroachlabs.com> Radu Berinde <radu@cockroachlabs.com>
Rafal Jeczalik <rjeczalik@gmail.com> Rafal Jeczalik <rjeczalik@gmail.com>
Raghavendra Nagaraj <jamdagni86@gmail.com>
Rahul Chaudhry <rahulchaudhry@chromium.org> Rahul Chaudhry <rahulchaudhry@chromium.org>
Raif S. Naffah <go@naffah-raif.name> Raif S. Naffah <go@naffah-raif.name>
Rajat Goel <rajat.goel2010@gmail.com> Rajat Goel <rajat.goel2010@gmail.com>
@ -1470,6 +1606,7 @@ Richard Musiol <mail@richard-musiol.de> <neelance@gmail.com>
Rick Arnold <rickarnoldjr@gmail.com> Rick Arnold <rickarnoldjr@gmail.com>
Rick Hudson <rlh@golang.org> Rick Hudson <rlh@golang.org>
Rick Sayre <whorfin@gmail.com> Rick Sayre <whorfin@gmail.com>
Rijnard van Tonder <rvantonder@gmail.com>
Riku Voipio <riku.voipio@linaro.org> Riku Voipio <riku.voipio@linaro.org>
Risto Jaakko Saarelma <rsaarelm@gmail.com> Risto Jaakko Saarelma <rsaarelm@gmail.com>
Rob Earhart <earhart@google.com> Rob Earhart <earhart@google.com>
@ -1488,22 +1625,28 @@ Robert Snedegar <roberts@google.com>
Robert Stepanek <robert.stepanek@gmail.com> Robert Stepanek <robert.stepanek@gmail.com>
Robert-André Mauchin <zebob.m@gmail.com> Robert-André Mauchin <zebob.m@gmail.com>
Roberto Clapis <robclap8@gmail.com> Roberto Clapis <robclap8@gmail.com>
Roberto Selbach <roberto@selbach.ca>
Robin Eklind <r.eklind.87@gmail.com> Robin Eklind <r.eklind.87@gmail.com>
Rodolfo Carvalho <rhcarvalho@gmail.com> Rodolfo Carvalho <rhcarvalho@gmail.com>
Rodolfo Rodriguez <rodolfobgibson@gmail.com>
Rodrigo Moraes de Oliveira <rodrigo.moraes@gmail.com> Rodrigo Moraes de Oliveira <rodrigo.moraes@gmail.com>
Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com> Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
Roger Pau Monné <royger@gmail.com> Roger Pau Monné <royger@gmail.com>
Roger Peppe <rogpeppe@gmail.com> Roger Peppe <rogpeppe@gmail.com>
Roland Illig <roland.illig@gmx.de>
Roland Shoemaker <rolandshoemaker@gmail.com> Roland Shoemaker <rolandshoemaker@gmail.com>
Roman Budnikov <romanyx90@yandex.ru> Roman Budnikov <romanyx90@yandex.ru>
Roman Shchekin <mrqtros@gmail.com>
Ron Hashimoto <mail@h2so5.net> Ron Hashimoto <mail@h2so5.net>
Ron Minnich <rminnich@gmail.com> Ron Minnich <rminnich@gmail.com>
Ross Chater <rdchater@gmail.com> Ross Chater <rdchater@gmail.com>
Ross Light <light@google.com> <rlight2@gmail.com> Ross Light <light@google.com> <rlight2@gmail.com>
Ross Smith II <ross@smithii.com>
Rowan Marshall <rowanajmarshall@gmail.com> Rowan Marshall <rowanajmarshall@gmail.com>
Rowan Worth <sqweek@gmail.com> Rowan Worth <sqweek@gmail.com>
Rudi Kramer <rudi.kramer@gmail.com> Rudi Kramer <rudi.kramer@gmail.com>
Rui Ueyama <ruiu@google.com> Rui Ueyama <ruiu@google.com>
Ruslan Nigmatullin <elessar@dropbox.com>
Russ Cox <rsc@golang.org> Russ Cox <rsc@golang.org>
Russell Haering <russellhaering@gmail.com> Russell Haering <russellhaering@gmail.com>
Ryan Bagwell <ryanbagwell@outlook.com> Ryan Bagwell <ryanbagwell@outlook.com>
@ -1511,6 +1654,7 @@ Ryan Barrett <ryanb@google.com>
Ryan Boehning <ryan.boehning@apcera.com> Ryan Boehning <ryan.boehning@apcera.com>
Ryan Brown <ribrdb@google.com> Ryan Brown <ribrdb@google.com>
Ryan Canty <jrcanty@gmail.com> Ryan Canty <jrcanty@gmail.com>
Ryan Dahl <ry@tinyclouds.org>
Ryan Hitchman <hitchmanr@gmail.com> Ryan Hitchman <hitchmanr@gmail.com>
Ryan Lower <rpjlower@gmail.com> Ryan Lower <rpjlower@gmail.com>
Ryan Roden-Corrent <ryan@rcorre.net> Ryan Roden-Corrent <ryan@rcorre.net>
@ -1534,9 +1678,11 @@ Sam Whited <sam@samwhited.com>
Sameer Ajmani <sameer@golang.org> <ajmani@gmail.com> Sameer Ajmani <sameer@golang.org> <ajmani@gmail.com>
Sami Commerot <samic@google.com> Sami Commerot <samic@google.com>
Sami Pönkänen <sami.ponkanen@gmail.com> Sami Pönkänen <sami.ponkanen@gmail.com>
Samuel Kelemen <SCKelemen@users.noreply.github.com>
Samuel Tan <samueltan@google.com> Samuel Tan <samueltan@google.com>
Samuele Pedroni <pedronis@lucediurna.net> Samuele Pedroni <pedronis@lucediurna.net>
Sanjay Menakuru <balasanjay@gmail.com> Sanjay Menakuru <balasanjay@gmail.com>
Santhosh Kumar Tekuri <santhosh.tekuri@gmail.com>
Sarah Adams <shadams@google.com> Sarah Adams <shadams@google.com>
Sascha Brawer <sascha@brawer.ch> Sascha Brawer <sascha@brawer.ch>
Sasha Lionheart <lionhearts@google.com> Sasha Lionheart <lionhearts@google.com>
@ -1550,13 +1696,17 @@ Scott Mansfield <smansfield@netflix.com>
Scott Schwartz <scotts@golang.org> Scott Schwartz <scotts@golang.org>
Scott Van Woudenberg <scottvw@google.com> Scott Van Woudenberg <scottvw@google.com>
Sean Burford <sburford@google.com> Sean Burford <sburford@google.com>
Sean Chen <oohcode@gmail.com>
Sean Chittenden <seanc@joyent.com> Sean Chittenden <seanc@joyent.com>
Sean Christopherson <sean.j.christopherson@intel.com> Sean Christopherson <sean.j.christopherson@intel.com>
Sean Dolphin <Sean.Dolphin@kpcompass.com> Sean Dolphin <Sean.Dolphin@kpcompass.com>
Sean Harger <sharger@google.com> Sean Harger <sharger@google.com>
Sean Rees <sean@erifax.org> Sean Rees <sean@erifax.org>
Sebastiaan van Stijn <github@gone.nl>
Sebastian Schmidt <yath@google.com>
Sebastien Binet <seb.binet@gmail.com> Sebastien Binet <seb.binet@gmail.com>
Sébastien Paolacci <sebastien.paolacci@gmail.com> Sébastien Paolacci <sebastien.paolacci@gmail.com>
Sebastien Williams-Wynn <sebastien@cytora.com>
Seiji Takahashi <timaki.st@gmail.com> Seiji Takahashi <timaki.st@gmail.com>
Sergei Skorobogatov <skorobo@rambler.ru> Sergei Skorobogatov <skorobo@rambler.ru>
Sergey 'SnakE' Gromov <snake.scaly@gmail.com> Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
@ -1568,6 +1718,7 @@ Sergey Mudrik <sergey.mudrik@gmail.com>
Sergey Semin <gray12511@gmail.com> Sergey Semin <gray12511@gmail.com>
Sergio Luis O. B. Correia <sergio@correia.cc> Sergio Luis O. B. Correia <sergio@correia.cc>
Sergiusz Bazanski <bazanski@gmail.com> Sergiusz Bazanski <bazanski@gmail.com>
Serhii Aheienko <serhii.aheienko@gmail.com>
Seth Hoenig <seth.a.hoenig@gmail.com> Seth Hoenig <seth.a.hoenig@gmail.com>
Seth Vargo <sethvargo@gmail.com> Seth Vargo <sethvargo@gmail.com>
Shahar Kohanim <skohanim@gmail.com> Shahar Kohanim <skohanim@gmail.com>
@ -1581,9 +1732,11 @@ Shawn Walker-Salas <shawn.walker@oracle.com>
Shenghou Ma <minux@golang.org> <minux.ma@gmail.com> Shenghou Ma <minux@golang.org> <minux.ma@gmail.com>
Shengyu Zhang <shengyu.zhang@chaitin.com> Shengyu Zhang <shengyu.zhang@chaitin.com>
Shi Han Ng <shihanng@gmail.com> Shi Han Ng <shihanng@gmail.com>
Shijie Hao <haormj@gmail.com>
Shinji Tanaka <shinji.tanaka@gmail.com> Shinji Tanaka <shinji.tanaka@gmail.com>
Shintaro Kaneko <kaneshin0120@gmail.com> Shintaro Kaneko <kaneshin0120@gmail.com>
Shivakumar GN <shivakumar.gn@gmail.com> Shivakumar GN <shivakumar.gn@gmail.com>
Shivansh Rai <shivansh@freebsd.org>
Shun Fan <sfan@google.com> Shun Fan <sfan@google.com>
Silvan Jegen <s.jegen@gmail.com> Silvan Jegen <s.jegen@gmail.com>
Simon Jefford <simon.jefford@gmail.com> Simon Jefford <simon.jefford@gmail.com>
@ -1603,6 +1756,7 @@ Stan Schwertly <stan@schwertly.com>
Stanislav Afanasev <php.progger@gmail.com> Stanislav Afanasev <php.progger@gmail.com>
Steeve Morin <steeve.morin@gmail.com> Steeve Morin <steeve.morin@gmail.com>
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com> Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
Stepan Shabalin <neverliberty@gmail.com>
Stephan Renatus <srenatus@chef.io> Stephan Renatus <srenatus@chef.io>
Stéphane Travostino <stephane.travostino@gmail.com> Stéphane Travostino <stephane.travostino@gmail.com>
Stephen Lewis <stephen@sock.org.uk> Stephen Lewis <stephen@sock.org.uk>
@ -1613,6 +1767,7 @@ Stephen Searles <stephens2424@gmail.com>
Stephen Weinberg <stephen@q5comm.com> Stephen Weinberg <stephen@q5comm.com>
Steve Francia <spf@golang.org> Steve Francia <spf@golang.org>
Steve Gilbert <stevegilbert23@gmail.com> Steve Gilbert <stevegilbert23@gmail.com>
Steve LoFurno <slofurno@gmail.com>
Steve McCoy <mccoyst@gmail.com> Steve McCoy <mccoyst@gmail.com>
Steve Newman <snewman@google.com> Steve Newman <snewman@google.com>
Steve Phillips <elimisteve@gmail.com> Steve Phillips <elimisteve@gmail.com>
@ -1621,7 +1776,10 @@ Steven Buss <sbuss@google.com>
Steven Elliot Harris <seharris@gmail.com> Steven Elliot Harris <seharris@gmail.com>
Steven Erenst <stevenerenst@gmail.com> Steven Erenst <stevenerenst@gmail.com>
Steven Hartland <steven.hartland@multiplay.co.uk> Steven Hartland <steven.hartland@multiplay.co.uk>
Steven Littiebrant <imgroxx@gmail.com>
Steven Wilkin <stevenwilkin@gmail.com> Steven Wilkin <stevenwilkin@gmail.com>
Stuart Jansen <sjansen@buscaluz.org>
Sue Spence <virtuallysue@gmail.com>
Sugu Sougoumarane <ssougou@gmail.com> Sugu Sougoumarane <ssougou@gmail.com>
Suharsh Sivakumar <suharshs@google.com> Suharsh Sivakumar <suharshs@google.com>
Sukrit Handa <sukrit.handa@utoronto.ca> Sukrit Handa <sukrit.handa@utoronto.ca>
@ -1634,8 +1792,11 @@ Sven Blumenstein <svbl@google.com>
Sylvain Zimmer <sylvain@sylvainzimmer.com> Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com> Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net> Szabolcs Nagy <nsz@port70.net>
Taavi Kivisik <taavi.kivisik@gmail.com>
Tad Fisher <tadfisher@gmail.com> Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com> Tad Glines <tad.glines@gmail.com>
Tadas Valiukas <tadovas@gmail.com>
Taesu Pyo <pyotaesu@gmail.com>
Taj Khattra <taj.khattra@gmail.com> Taj Khattra <taj.khattra@gmail.com>
Takashi Matsuo <tmatsuo@google.com> Takashi Matsuo <tmatsuo@google.com>
Takayoshi Nishida <takayoshi.nishida@gmail.com> Takayoshi Nishida <takayoshi.nishida@gmail.com>
@ -1644,11 +1805,14 @@ Takuto Ikuta <tikuta@google.com>
Takuya Ueda <uedatakuya@gmail.com> Takuya Ueda <uedatakuya@gmail.com>
Tal Shprecher <tshprecher@gmail.com> Tal Shprecher <tshprecher@gmail.com>
Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@gmail.com>
Tao Shen <shentaoskyking@gmail.com>
Tao Wang <twang2218@gmail.com> Tao Wang <twang2218@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com> Tarmigan Casebolt <tarmigan@gmail.com>
Taro Aoki <aizu.s1230022@gmail.com> Taro Aoki <aizu.s1230022@gmail.com>
Taru Karttunen <taruti@taruti.net> Taru Karttunen <taruti@taruti.net>
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Tatsuya Kaneko <m.ddotx.f@gmail.com>
Taufiq Rahman <taufiqrx8@gmail.com>
Teague Cole <tnc1443@gmail.com> Teague Cole <tnc1443@gmail.com>
Ted Kornish <golang@tedkornish.com> Ted Kornish <golang@tedkornish.com>
Tejasvi Nareddy <tejunareddy@gmail.com> Tejasvi Nareddy <tejunareddy@gmail.com>
@ -1664,6 +1828,7 @@ Thomas Alan Copeland <talan.copeland@gmail.com>
Thomas Bonfort <thomas.bonfort@gmail.com> Thomas Bonfort <thomas.bonfort@gmail.com>
Thomas Bouldin <inlined@google.com> Thomas Bouldin <inlined@google.com>
Thomas Bruyelle <thomas.bruyelle@gmail.com> Thomas Bruyelle <thomas.bruyelle@gmail.com>
Thomas Bushnell, BSG <tbushnell@google.com>
Thomas de Zeeuw <thomasdezeeuw@gmail.com> Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Thomas Desrosiers <thomasdesr@gmail.com> Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Habets <habets@google.com> Thomas Habets <habets@google.com>
@ -1682,6 +1847,7 @@ Tim Henderson <tim.tadh@gmail.com>
Tim Hockin <thockin@google.com> Tim Hockin <thockin@google.com>
Tim Swast <swast@google.com> Tim Swast <swast@google.com>
Tim Wright <tenortim@gmail.com> Tim Wright <tenortim@gmail.com>
Tim Xu <xiaoxubeii@gmail.com>
Timo Savola <timo.savola@gmail.com> Timo Savola <timo.savola@gmail.com>
Timo Truyts <alkaloid.btx@gmail.com> Timo Truyts <alkaloid.btx@gmail.com>
Timothy Studd <tim@timstudd.com> Timothy Studd <tim@timstudd.com>
@ -1705,6 +1871,7 @@ Tom Wilkie <tom@weave.works>
Tommy Schaefer <tommy.schaefer@teecom.com> Tommy Schaefer <tommy.schaefer@teecom.com>
Tomoya Ishizaki <zaq1tomo@gmail.com> Tomoya Ishizaki <zaq1tomo@gmail.com>
Tonis Tiigi <tonistiigi@gmail.com> Tonis Tiigi <tonistiigi@gmail.com>
Tony Reix <tony.reix@bull.net>
Tony Walker <walkert.uk@gmail.com> Tony Walker <walkert.uk@gmail.com>
Tor Andersson <tor.andersson@gmail.com> Tor Andersson <tor.andersson@gmail.com>
Tormod Erevik Lea <tormodlea@gmail.com> Tormod Erevik Lea <tormodlea@gmail.com>
@ -1732,7 +1899,9 @@ Tzu-Jung Lee <roylee17@currant.com>
Ugorji Nwoke <ugorji@gmail.com> Ugorji Nwoke <ugorji@gmail.com>
Ulf Holm Nielsen <doktor@dyregod.dk> Ulf Holm Nielsen <doktor@dyregod.dk>
Ulrich Kunitz <uli.kunitz@gmail.com> Ulrich Kunitz <uli.kunitz@gmail.com>
Umang Parmar <umangjparmar@gmail.com>
Uriel Mangado <uriel@berlinblue.org> Uriel Mangado <uriel@berlinblue.org>
Urvil Patel <patelurvil38@gmail.com>
Uttam C Pawar <uttam.c.pawar@intel.com> Uttam C Pawar <uttam.c.pawar@intel.com>
Vadim Grek <vadimprog@gmail.com> Vadim Grek <vadimprog@gmail.com>
Vadim Vygonets <unixdj@gmail.com> Vadim Vygonets <unixdj@gmail.com>
@ -1740,6 +1909,7 @@ Val Polouchkine <vpolouch@justin.tv>
Vega Garcia Luis Alfonso <vegacom@gmail.com> Vega Garcia Luis Alfonso <vegacom@gmail.com>
Venil Noronha <veniln@vmware.com> Venil Noronha <veniln@vmware.com>
Veselkov Konstantin <kostozyb@gmail.com> Veselkov Konstantin <kostozyb@gmail.com>
Viacheslav Poturaev <vearutop@gmail.com>
Victor Chudnovsky <vchudnov@google.com> Victor Chudnovsky <vchudnov@google.com>
Victor Vrantchan <vrancean+github@gmail.com> Victor Vrantchan <vrancean+github@gmail.com>
Vignesh Ramachandra <vickyramachandra@gmail.com> Vignesh Ramachandra <vickyramachandra@gmail.com>
@ -1750,8 +1920,10 @@ Vincent Vanackere <vincent.vanackere@gmail.com>
Vinu Rajashekhar <vinutheraj@gmail.com> Vinu Rajashekhar <vinutheraj@gmail.com>
Vish Subramanian <vish@google.com> Vish Subramanian <vish@google.com>
Vishvananda Ishaya <vishvananda@gmail.com> Vishvananda Ishaya <vishvananda@gmail.com>
Visweswara R <r.visweswara@gmail.com>
Vitor De Mario <vitordemario@gmail.com> Vitor De Mario <vitordemario@gmail.com>
Vlad Krasnov <vlad@cloudflare.com> Vlad Krasnov <vlad@cloudflare.com>
Vladimir Kovpak <cn007b@gmail.com>
Vladimir Kuzmin <vkuzmin@uber.com> Vladimir Kuzmin <vkuzmin@uber.com>
Vladimir Mihailenco <vladimir.webdev@gmail.com> Vladimir Mihailenco <vladimir.webdev@gmail.com>
Vladimir Nikishenko <vova616@gmail.com> Vladimir Nikishenko <vova616@gmail.com>
@ -1763,17 +1935,22 @@ W. Trevor King <wking@tremily.us>
Wade Simmons <wade@wades.im> Wade Simmons <wade@wades.im>
Walter Poupore <wpoupore@google.com> Walter Poupore <wpoupore@google.com>
Wander Lairson Costa <wcosta@mozilla.com> Wander Lairson Costa <wcosta@mozilla.com>
Warren Fernandes <warren.f.fernandes@gmail.com>
Wayne Ashley Berry <wayneashleyberry@gmail.com> Wayne Ashley Berry <wayneashleyberry@gmail.com>
Wedson Almeida Filho <wedsonaf@google.com> Wedson Almeida Filho <wedsonaf@google.com>
Weerasak Chongnguluam <singpor@gmail.com>
Wèi Cōngruì <crvv.mail@gmail.com> Wèi Cōngruì <crvv.mail@gmail.com>
Wei Fu <fhfuwei@163.com> Wei Fu <fhfuwei@163.com>
Wei Guangjing <vcc.163@gmail.com> Wei Guangjing <vcc.163@gmail.com>
Wei Xiao <wei.xiao@arm.com> Wei Xiao <wei.xiao@arm.com>
Weichao Tang <tevic.tt@gmail.com> Weichao Tang <tevic.tt@gmail.com>
Wembley G. Leach, Jr <wembley.gl@gmail.com> Wembley G. Leach, Jr <wembley.gl@gmail.com>
Wil Selwood <wselwood@gmail.com>
Wilfried Teiken <wteiken@google.com> Wilfried Teiken <wteiken@google.com>
Will Beason <willbeason@gmail.com>
Will Chan <willchan@google.com> Will Chan <willchan@google.com>
Will Faught <will.faught@gmail.com> Will Faught <will.faught@gmail.com>
Will Morrow <wmorrow.qdt@qualcommdatacenter.com>
Will Norris <willnorris@google.com> Will Norris <willnorris@google.com>
Will Storey <will@summercat.com> Will Storey <will@summercat.com>
Willem van der Schyff <willemvds@gmail.com> Willem van der Schyff <willemvds@gmail.com>
@ -1806,6 +1983,7 @@ Yestin Sun <ylh@pdx.edu>
Yesudeep Mangalapilly <yesudeep@google.com> Yesudeep Mangalapilly <yesudeep@google.com>
Yissakhar Z. Beck <yissakhar.beck@gmail.com> Yissakhar Z. Beck <yissakhar.beck@gmail.com>
Yo-An Lin <yoanlin93@gmail.com> Yo-An Lin <yoanlin93@gmail.com>
Yohei Takeda <yo.tak0812@gmail.com>
Yongjian Xu <i3dmaster@gmail.com> Yongjian Xu <i3dmaster@gmail.com>
Yorman Arias <cixtords@gmail.com> Yorman Arias <cixtords@gmail.com>
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp> Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
@ -1814,6 +1992,7 @@ Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
Yu Heng Zhang <annita.zhang@cn.ibm.com> Yu Heng Zhang <annita.zhang@cn.ibm.com>
Yu Xuan Zhang <zyxsh@cn.ibm.com> Yu Xuan Zhang <zyxsh@cn.ibm.com>
Yuji Yaginuma <yuuji.yaginuma@gmail.com> Yuji Yaginuma <yuuji.yaginuma@gmail.com>
Yuki OKUSHI <huyuumi.dev@gmail.com>
Yuki Yugui Sonoda <yugui@google.com> Yuki Yugui Sonoda <yugui@google.com>
Yukihiro Nishinaka <6elpinal@gmail.com> Yukihiro Nishinaka <6elpinal@gmail.com>
Yury Smolsky <yury@smolsky.by> Yury Smolsky <yury@smolsky.by>
@ -1824,12 +2003,14 @@ Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
Zac Bergquist <zbergquist99@gmail.com> Zac Bergquist <zbergquist99@gmail.com>
Zach Bintliff <zbintliff@gmail.com> Zach Bintliff <zbintliff@gmail.com>
Zach Gershman <zachgersh@gmail.com> Zach Gershman <zachgersh@gmail.com>
Zachary Amsden <zach@thundertoken.com>
Zachary Gershman <zgershman@pivotal.io> Zachary Gershman <zgershman@pivotal.io>
Zak <zrjknill@gmail.com> Zak <zrjknill@gmail.com>
Zakatell Kanda <hi@zkanda.io> Zakatell Kanda <hi@zkanda.io>
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com> Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
Zev Goldstein <zev.goldstein@gmail.com> Zev Goldstein <zev.goldstein@gmail.com>
Zheng Dayu <davidzheng23@gmail.com> Zheng Dayu <davidzheng23@gmail.com>
Zheng Xu <zheng.xu@arm.com>
Zhengyu He <hzy@google.com> Zhengyu He <hzy@google.com>
Zhongpeng Lin <zplin@uber.com> Zhongpeng Lin <zplin@uber.com>
Zhongtao Chen <chenzhongtao@126.com> Zhongtao Chen <chenzhongtao@126.com>

View file

@ -386,15 +386,11 @@ pkg syscall (windows-amd64), type RawSockaddrAny struct, Pad [96]int8
pkg syscall (freebsd-386), func Mknod(string, uint32, int) error pkg syscall (freebsd-386), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386), type Dirent struct, Fileno uint32 pkg syscall (freebsd-386), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386), type Dirent struct, Namlen uint8 pkg syscall (freebsd-386), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-386), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-386), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-386), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-386), type Stat_t struct, Dev uint32 pkg syscall (freebsd-386), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386), type Stat_t struct, Gen uint32 pkg syscall (freebsd-386), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386), type Stat_t struct, Ino uint32 pkg syscall (freebsd-386), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386), type Stat_t struct, Lspare int32 pkg syscall (freebsd-386), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-386), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-386), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386), type Stat_t struct, Pad_cgo_0 [8]uint8 pkg syscall (freebsd-386), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-386), type Stat_t struct, Rdev uint32
@ -403,15 +399,11 @@ pkg syscall (freebsd-386), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-386-cgo), func Mknod(string, uint32, int) error pkg syscall (freebsd-386-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386-cgo), type Dirent struct, Fileno uint32 pkg syscall (freebsd-386-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-386-cgo), type Dirent struct, Namlen uint8 pkg syscall (freebsd-386-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-386-cgo), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-386-cgo), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-386-cgo), type Stat_t struct, Dev uint32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Gen uint32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ino uint32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Lspare int32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-386-cgo), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-386-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-386-cgo), type Stat_t struct, Pad_cgo_0 [8]uint8 pkg syscall (freebsd-386-cgo), type Stat_t struct, Pad_cgo_0 [8]uint8
pkg syscall (freebsd-386-cgo), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-386-cgo), type Stat_t struct, Rdev uint32
@ -420,15 +412,11 @@ pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64), func Mknod(string, uint32, int) error pkg syscall (freebsd-amd64), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64), type Dirent struct, Fileno uint32 pkg syscall (freebsd-amd64), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64), type Dirent struct, Namlen uint8 pkg syscall (freebsd-amd64), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-amd64), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-amd64), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-amd64), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-amd64), type Stat_t struct, Dev uint32 pkg syscall (freebsd-amd64), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Gen uint32 pkg syscall (freebsd-amd64), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Ino uint32 pkg syscall (freebsd-amd64), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64), type Stat_t struct, Lspare int32 pkg syscall (freebsd-amd64), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-amd64), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-amd64), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-amd64), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntfromname [88]int8 pkg syscall (freebsd-amd64), type Statfs_t struct, Mntfromname [88]int8
@ -436,15 +424,11 @@ pkg syscall (freebsd-amd64), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-amd64-cgo), func Mknod(string, uint32, int) error pkg syscall (freebsd-amd64-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Fileno uint32 pkg syscall (freebsd-amd64-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Namlen uint8 pkg syscall (freebsd-amd64-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Dev uint32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Gen uint32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ino uint32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Lspare int32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntfromname [88]int8 pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntfromname [88]int8
@ -452,15 +436,11 @@ pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm), func Mknod(string, uint32, int) error pkg syscall (freebsd-arm), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm), type Dirent struct, Fileno uint32 pkg syscall (freebsd-arm), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm), type Dirent struct, Namlen uint8 pkg syscall (freebsd-arm), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-arm), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-arm), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-arm), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-arm), type Stat_t struct, Dev uint32 pkg syscall (freebsd-arm), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm), type Stat_t struct, Gen uint32 pkg syscall (freebsd-arm), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm), type Stat_t struct, Ino uint32 pkg syscall (freebsd-arm), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm), type Stat_t struct, Lspare int32 pkg syscall (freebsd-arm), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-arm), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-arm), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-arm), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm), type Statfs_t struct, Mntfromname [88]int8 pkg syscall (freebsd-arm), type Statfs_t struct, Mntfromname [88]int8
@ -468,15 +448,11 @@ pkg syscall (freebsd-arm), type Statfs_t struct, Mntonname [88]int8
pkg syscall (freebsd-arm-cgo), func Mknod(string, uint32, int) error pkg syscall (freebsd-arm-cgo), func Mknod(string, uint32, int) error
pkg syscall (freebsd-arm-cgo), type Dirent struct, Fileno uint32 pkg syscall (freebsd-arm-cgo), type Dirent struct, Fileno uint32
pkg syscall (freebsd-arm-cgo), type Dirent struct, Namlen uint8 pkg syscall (freebsd-arm-cgo), type Dirent struct, Namlen uint8
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Atimespec Timespec
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Birthtimespec Timespec
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Blksize uint32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Blksize uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ctimespec Timespec
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Dev uint32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Dev uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Gen uint32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Gen uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ino uint32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ino uint32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Lspare int32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Lspare int32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Mtimespec Timespec
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Nlink uint16 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Nlink uint16
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Rdev uint32 pkg syscall (freebsd-arm-cgo), type Stat_t struct, Rdev uint32
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [88]int8 pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [88]int8

228
api/go1.12.txt Normal file
View file

@ -0,0 +1,228 @@
pkg bytes, func ReplaceAll([]uint8, []uint8, []uint8) []uint8
pkg crypto/tls, const TLS_AES_128_GCM_SHA256 = 4865
pkg crypto/tls, const TLS_AES_128_GCM_SHA256 uint16
pkg crypto/tls, const TLS_AES_256_GCM_SHA384 = 4866
pkg crypto/tls, const TLS_AES_256_GCM_SHA384 uint16
pkg crypto/tls, const TLS_CHACHA20_POLY1305_SHA256 = 4867
pkg crypto/tls, const TLS_CHACHA20_POLY1305_SHA256 uint16
pkg crypto/tls, const VersionTLS13 = 772
pkg crypto/tls, const VersionTLS13 ideal-int
pkg crypto/tls, type RecordHeaderError struct, Conn net.Conn
pkg debug/elf, const R_RISCV_32_PCREL = 57
pkg debug/elf, const R_RISCV_32_PCREL R_RISCV
pkg debug/pe, const IMAGE_FILE_MACHINE_ARMNT = 452
pkg debug/pe, const IMAGE_FILE_MACHINE_ARMNT ideal-int
pkg expvar, method (*Map) Delete(string)
pkg go/doc, const PreserveAST = 4
pkg go/doc, const PreserveAST Mode
pkg go/importer, func ForCompiler(*token.FileSet, string, Lookup) types.Importer
pkg go/token, method (*File) LineStart(int) Pos
pkg io, type StringWriter interface { WriteString }
pkg io, type StringWriter interface, WriteString(string) (int, error)
pkg log, method (*Logger) Writer() io.Writer
pkg math/bits, func Add(uint, uint, uint) (uint, uint)
pkg math/bits, func Add32(uint32, uint32, uint32) (uint32, uint32)
pkg math/bits, func Add64(uint64, uint64, uint64) (uint64, uint64)
pkg math/bits, func Div(uint, uint, uint) (uint, uint)
pkg math/bits, func Div32(uint32, uint32, uint32) (uint32, uint32)
pkg math/bits, func Div64(uint64, uint64, uint64) (uint64, uint64)
pkg math/bits, func Mul(uint, uint) (uint, uint)
pkg math/bits, func Mul32(uint32, uint32) (uint32, uint32)
pkg math/bits, func Mul64(uint64, uint64) (uint64, uint64)
pkg math/bits, func Sub(uint, uint, uint) (uint, uint)
pkg math/bits, func Sub32(uint32, uint32, uint32) (uint32, uint32)
pkg math/bits, func Sub64(uint64, uint64, uint64) (uint64, uint64)
pkg net/http, const StatusTooEarly = 425
pkg net/http, const StatusTooEarly ideal-int
pkg net/http, method (*Client) CloseIdleConnections()
pkg os, const ModeType = 2401763328
pkg os, func UserHomeDir() (string, error)
pkg os, method (*File) SyscallConn() (syscall.RawConn, error)
pkg os, method (*ProcessState) ExitCode() int
pkg os/exec, method (ExitError) ExitCode() int
pkg reflect, method (*MapIter) Key() Value
pkg reflect, method (*MapIter) Next() bool
pkg reflect, method (*MapIter) Value() Value
pkg reflect, method (Value) MapRange() *MapIter
pkg reflect, type MapIter struct
pkg runtime/debug, func ReadBuildInfo() (*BuildInfo, bool)
pkg runtime/debug, type BuildInfo struct
pkg runtime/debug, type BuildInfo struct, Deps []*Module
pkg runtime/debug, type BuildInfo struct, Main Module
pkg runtime/debug, type BuildInfo struct, Path string
pkg runtime/debug, type Module struct
pkg runtime/debug, type Module struct, Path string
pkg runtime/debug, type Module struct, Replace *Module
pkg runtime/debug, type Module struct, Sum string
pkg runtime/debug, type Module struct, Version string
pkg strings, func ReplaceAll(string, string, string) string
pkg strings, method (*Builder) Cap() int
pkg syscall (freebsd-386), const S_IRWXG = 56
pkg syscall (freebsd-386), const S_IRWXG ideal-int
pkg syscall (freebsd-386), const S_IRWXO = 7
pkg syscall (freebsd-386), const S_IRWXO ideal-int
pkg syscall (freebsd-386), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-386), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-386), type Dirent struct, Fileno uint64
pkg syscall (freebsd-386), type Dirent struct, Namlen uint16
pkg syscall (freebsd-386), type Dirent struct, Off int64
pkg syscall (freebsd-386), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-386), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-386), type Stat_t struct, Atim_ext int32
pkg syscall (freebsd-386), type Stat_t struct, Blksize int32
pkg syscall (freebsd-386), type Stat_t struct, Btim_ext int32
pkg syscall (freebsd-386), type Stat_t struct, Ctim_ext int32
pkg syscall (freebsd-386), type Stat_t struct, Dev uint64
pkg syscall (freebsd-386), type Stat_t struct, Gen uint64
pkg syscall (freebsd-386), type Stat_t struct, Ino uint64
pkg syscall (freebsd-386), type Stat_t struct, Mtim_ext int32
pkg syscall (freebsd-386), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-386), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-386), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-386), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-386), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-386), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-386), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (freebsd-386-cgo), const S_IRWXG = 56
pkg syscall (freebsd-386-cgo), const S_IRWXG ideal-int
pkg syscall (freebsd-386-cgo), const S_IRWXO = 7
pkg syscall (freebsd-386-cgo), const S_IRWXO ideal-int
pkg syscall (freebsd-386-cgo), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-386-cgo), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-386-cgo), type Dirent struct, Fileno uint64
pkg syscall (freebsd-386-cgo), type Dirent struct, Namlen uint16
pkg syscall (freebsd-386-cgo), type Dirent struct, Off int64
pkg syscall (freebsd-386-cgo), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-386-cgo), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-386-cgo), type Stat_t struct, Atim_ext int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Blksize int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Btim_ext int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ctim_ext int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Dev uint64
pkg syscall (freebsd-386-cgo), type Stat_t struct, Gen uint64
pkg syscall (freebsd-386-cgo), type Stat_t struct, Ino uint64
pkg syscall (freebsd-386-cgo), type Stat_t struct, Mtim_ext int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-386-cgo), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-386-cgo), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-386-cgo), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-386-cgo), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-386-cgo), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (freebsd-amd64), const S_IRWXG = 56
pkg syscall (freebsd-amd64), const S_IRWXG ideal-int
pkg syscall (freebsd-amd64), const S_IRWXO = 7
pkg syscall (freebsd-amd64), const S_IRWXO ideal-int
pkg syscall (freebsd-amd64), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-amd64), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-amd64), type Dirent struct, Fileno uint64
pkg syscall (freebsd-amd64), type Dirent struct, Namlen uint16
pkg syscall (freebsd-amd64), type Dirent struct, Off int64
pkg syscall (freebsd-amd64), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-amd64), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-amd64), type Stat_t struct, Blksize int32
pkg syscall (freebsd-amd64), type Stat_t struct, Dev uint64
pkg syscall (freebsd-amd64), type Stat_t struct, Gen uint64
pkg syscall (freebsd-amd64), type Stat_t struct, Ino uint64
pkg syscall (freebsd-amd64), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-amd64), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-amd64), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-amd64), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-amd64), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-amd64), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (freebsd-amd64-cgo), const S_IRWXG = 56
pkg syscall (freebsd-amd64-cgo), const S_IRWXG ideal-int
pkg syscall (freebsd-amd64-cgo), const S_IRWXO = 7
pkg syscall (freebsd-amd64-cgo), const S_IRWXO ideal-int
pkg syscall (freebsd-amd64-cgo), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-amd64-cgo), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Fileno uint64
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Namlen uint16
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Off int64
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-amd64-cgo), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Blksize int32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Dev uint64
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Gen uint64
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Ino uint64
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-amd64-cgo), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-amd64-cgo), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (freebsd-arm), const S_IRWXG = 56
pkg syscall (freebsd-arm), const S_IRWXG ideal-int
pkg syscall (freebsd-arm), const S_IRWXO = 7
pkg syscall (freebsd-arm), const S_IRWXO ideal-int
pkg syscall (freebsd-arm), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-arm), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-arm), type Dirent struct, Fileno uint64
pkg syscall (freebsd-arm), type Dirent struct, Namlen uint16
pkg syscall (freebsd-arm), type Dirent struct, Off int64
pkg syscall (freebsd-arm), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-arm), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-arm), type Stat_t struct, Blksize int32
pkg syscall (freebsd-arm), type Stat_t struct, Dev uint64
pkg syscall (freebsd-arm), type Stat_t struct, Gen uint64
pkg syscall (freebsd-arm), type Stat_t struct, Ino uint64
pkg syscall (freebsd-arm), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-arm), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-arm), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-arm), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-arm), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-arm), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-arm), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (freebsd-arm-cgo), const S_IRWXG = 56
pkg syscall (freebsd-arm-cgo), const S_IRWXG ideal-int
pkg syscall (freebsd-arm-cgo), const S_IRWXO = 7
pkg syscall (freebsd-arm-cgo), const S_IRWXO ideal-int
pkg syscall (freebsd-arm-cgo), func Fstatat(int, string, *Stat_t, int) error
pkg syscall (freebsd-arm-cgo), func Mknod(string, uint32, uint64) error
pkg syscall (freebsd-arm-cgo), type Dirent struct, Fileno uint64
pkg syscall (freebsd-arm-cgo), type Dirent struct, Namlen uint16
pkg syscall (freebsd-arm-cgo), type Dirent struct, Off int64
pkg syscall (freebsd-arm-cgo), type Dirent struct, Pad0 uint8
pkg syscall (freebsd-arm-cgo), type Dirent struct, Pad1 uint16
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Blksize int32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Dev uint64
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Gen uint64
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Ino uint64
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Nlink uint64
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Padding0 int16
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Padding1 int32
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Rdev uint64
pkg syscall (freebsd-arm-cgo), type Stat_t struct, Spare [10]uint64
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [1024]int8
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntonname [1024]int8
pkg syscall (openbsd-386), const S_IRWXG = 56
pkg syscall (openbsd-386), const S_IRWXG ideal-int
pkg syscall (openbsd-386), const S_IRWXO = 7
pkg syscall (openbsd-386), const S_IRWXO ideal-int
pkg syscall (openbsd-386-cgo), const S_IRWXG = 56
pkg syscall (openbsd-386-cgo), const S_IRWXG ideal-int
pkg syscall (openbsd-386-cgo), const S_IRWXO = 7
pkg syscall (openbsd-386-cgo), const S_IRWXO ideal-int
pkg syscall (openbsd-amd64), const S_IRWXG = 56
pkg syscall (openbsd-amd64), const S_IRWXG ideal-int
pkg syscall (openbsd-amd64), const S_IRWXO = 7
pkg syscall (openbsd-amd64), const S_IRWXO ideal-int
pkg syscall (openbsd-amd64-cgo), const S_IRWXG = 56
pkg syscall (openbsd-amd64-cgo), const S_IRWXG ideal-int
pkg syscall (openbsd-amd64-cgo), const S_IRWXO = 7
pkg syscall (openbsd-amd64-cgo), const S_IRWXO ideal-int
pkg syscall (windows-386), const UNIX_PATH_MAX = 108
pkg syscall (windows-386), const UNIX_PATH_MAX ideal-int
pkg syscall (windows-386), func Syscall18(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
pkg syscall (windows-386), type RawSockaddrAny struct, Pad [100]int8
pkg syscall (windows-386), type RawSockaddrUnix struct, Family uint16
pkg syscall (windows-386), type RawSockaddrUnix struct, Path [108]int8
pkg syscall (windows-amd64), const UNIX_PATH_MAX = 108
pkg syscall (windows-amd64), const UNIX_PATH_MAX ideal-int
pkg syscall (windows-amd64), func Syscall18(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
pkg syscall (windows-amd64), type RawSockaddrAny struct, Pad [100]int8
pkg syscall (windows-amd64), type RawSockaddrUnix struct, Family uint16
pkg syscall (windows-amd64), type RawSockaddrUnix struct, Path [108]int8
pkg syscall, type RawSockaddrUnix struct

View file

@ -276,7 +276,7 @@ CodewalkViewer.prototype.changeSelectedComment = function(target) {
} }
// Force original file even if user hasn't changed comments since they may // Force original file even if user hasn't changed comments since they may
// have nagivated away from it within the iframe without us knowing. // have navigated away from it within the iframe without us knowing.
this.navigateToCode(currentFile); this.navigateToCode(currentFile);
}; };

View file

@ -922,13 +922,13 @@ New files that you contribute should use the standard copyright header:
</p> </p>
<pre> <pre>
// Copyright 2018 The Go Authors. All rights reserved. // Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
</pre> </pre>
<p> <p>
(Use the current year if you're reading this in 2019 or beyond.) (Use the current year if you're reading this in 2020 or beyond.)
Files in the repository are copyrighted the year they are added. Files in the repository are copyrighted the year they are added.
Do not update the copyright year on files that you change. Do not update the copyright year on files that you change.
</p> </p>

View file

@ -49,6 +49,23 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.2">Go
1.11.2 milestone</a> on our issue tracker for details. 1.11.2 milestone</a> on our issue tracker for details.
</p> </p>
<p>
go1.11.3 (released 2018/12/12) includes three security fixes to "go get" and
the <code>crypto/x509</code> package.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.3">Go
1.11.3 milestone</a> on our issue tracker for details.
</p>
<p>
go1.11.4 (released 2018/12/14) includes fixes to cgo, the compiler, linker,
runtime, documentation, go command, and the <code>net/http</code> and
<code>go/types</code> packages.
It includes a fix to a bug introduced in Go 1.11.3 that broke <code>go</code>
<code>get</code> for import path patterns containing "<code>...</code>".
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.4+label%3ACherryPickApproved">Go
1.11.4 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2> <h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
<p> <p>
@ -98,6 +115,22 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.5">Go
1.10.5 milestone</a> on our issue tracker for details. 1.10.5 milestone</a> on our issue tracker for details.
</p> </p>
<p>
go1.10.6 (released 2018/12/12) includes three security fixes to "go get" and
the <code>crypto/x509</code> package.
It contains the same fixes as Go 1.11.3 and was released at the same time.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.6">Go
1.10.6 milestone</a> on our issue tracker for details.
</p>
<p>
go1.10.7 (released 2018/12/14) includes a fix to a bug introduced in Go 1.10.6
that broke <code>go</code> <code>get</code> for import path patterns containing
"<code>...</code>".
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.7+label%3ACherryPickApproved">
Go 1.10.7 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2> <h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
<p> <p>

View file

@ -456,3 +456,15 @@ each collection, summarizing the amount of memory collected
and the length of the pause.</li> and the length of the pause.</li>
<li>GODEBUG=schedtrace=X prints scheduling events every X milliseconds.</li> <li>GODEBUG=schedtrace=X prints scheduling events every X milliseconds.</li>
</ul> </ul>
<p>The GODEBUG environmental variable can be used to disable use of
instruction set extensions in the standard library and runtime.</p>
<ul>
<li>GODEBUG=cpu.all=off disables the use of all optional
instruction set extensions.</li>
<li>GODEBUG=cpu.<em>extension</em>=off disables use of instructions from the
specified instruction set extension.<br>
<em>extension</em> is the lower case name for the instruction set extension
such as <em>sse41</em> or <em>avx</em>.</li>
</ul>

View file

@ -1710,7 +1710,7 @@ prints
&amp;{7 -2.35 abc def} &amp;{7 -2.35 abc def}
&amp;{a:7 b:-2.35 c:abc def} &amp;{a:7 b:-2.35 c:abc def}
&amp;main.T{a:7, b:-2.35, c:"abc\tdef"} &amp;main.T{a:7, b:-2.35, c:"abc\tdef"}
map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200} map[string]int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}
</pre> </pre>
<p> <p>
(Note the ampersands.) (Note the ampersands.)
@ -1733,7 +1733,7 @@ fmt.Printf(&quot;%T\n&quot;, timeZone)
prints prints
</p> </p>
<pre> <pre>
map[string] int map[string]int
</pre> </pre>
<p> <p>
If you want to control the default format for a custom type, all that's required is to define If you want to control the default format for a custom type, all that's required is to define
@ -2106,12 +2106,14 @@ In this contrived example <code>Sequence</code> satisfies both.
<p> <p>
The <code>String</code> method of <code>Sequence</code> is recreating the The <code>String</code> method of <code>Sequence</code> is recreating the
work that <code>Sprint</code> already does for slices. We can share the work that <code>Sprint</code> already does for slices.
effort if we convert the <code>Sequence</code> to a plain (It also has complexity O(N²), which is poor.) We can share the
effort (and also speed it up) if we convert the <code>Sequence</code> to a plain
<code>[]int</code> before calling <code>Sprint</code>. <code>[]int</code> before calling <code>Sprint</code>.
</p> </p>
<pre> <pre>
func (s Sequence) String() string { func (s Sequence) String() string {
s = s.Copy()
sort.Sort(s) sort.Sort(s)
return fmt.Sprint([]int(s)) return fmt.Sprint([]int(s))
} }
@ -2138,6 +2140,7 @@ type Sequence []int
// Method for printing - sorts the elements before printing // Method for printing - sorts the elements before printing
func (s Sequence) String() string { func (s Sequence) String() string {
s = s.Copy()
sort.IntSlice(s).Sort() sort.IntSlice(s).Sort()
return fmt.Sprint([]int(s)) return fmt.Sprint([]int(s))
} }

View file

@ -400,6 +400,16 @@ details. <!-- CL 126275, CL 127156, CL 122217, CL 122575, CL 123177 -->
information. information.
</p> </p>
<h3 id="run">Run</h3>
<p>
<!-- CL 109341 -->
The <a href="/cmd/go/"><code>go</code>&nbsp;<code>run</code></a>
command now allows a single import path, a directory name or a
pattern matching a single package.
This allows <code>go</code>&nbsp;<code>run</code>&nbsp;<code>pkg</code> or <code>go</code>&nbsp;<code>run</code>&nbsp;<code>dir</code>, most importantly <code>go</code>&nbsp;<code>run</code>&nbsp;<code>.</code>
</p>
<h2 id="runtime">Runtime</h2> <h2 id="runtime">Runtime</h2>
<p><!-- CL 85887 --> <p><!-- CL 85887 -->

View file

@ -26,8 +26,8 @@ Do not send CLs removing the interior tags from such phrases.
<p> <p>
The latest Go release, version 1.12, arrives six months after <a href="go1.11">Go 1.11</a>. The latest Go release, version 1.12, arrives six months after <a href="go1.11">Go 1.11</a>.
Most of its changes are in TODO. Most of its changes are in the implementation of the toolchain, runtime, and libraries.
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>. As always, the release maintains the Go 1 <a href="/doc/go1compat">promise of compatibility</a>.
We expect almost all Go programs to continue to compile and run as before. We expect almost all Go programs to continue to compile and run as before.
</p> </p>
@ -37,19 +37,268 @@ Do not send CLs removing the interior tags from such phrases.
There are no changes to the language specification. There are no changes to the language specification.
</p> </p>
<h2 id="ports">Ports</h2>
<p><!-- CL 138675 -->
The race detector is now supported on <code>linux/arm64</code>.
</p>
<p id="freebsd">
Go 1.12 is the last release that is supported on FreeBSD 10.x, which has
already reached end-of-life. Go 1.13 will require FreeBSD 11.2+ or FreeBSD
12.0+.
FreeBSD 12.0+ requires a kernel with the COMPAT_FREEBSD11 option set (this is the default).
</p>
<p><!-- CL 146898 -->
cgo is now supported on <code>linux/ppc64</code>.
</p>
<p id="hurd"><!-- CL 146023 -->
<code>hurd</code> is now a recognized value for <code>GOOS</code>, reserved
for the GNU/Hurd system for use with <code>gccgo</code>.
</p>
<h3 id="windows">Windows</h3>
<p>
Go's new <code>windows/arm</code> port supports running Go on Windows 10
IoT Core on 32-bit ARM chips such as the Raspberry Pi 3.
</p>
<h3 id="aix">AIX</h3>
<p>
Go now supports AIX 7.2 and later on POWER8 architectures (<code>aix/ppc64</code>). External linking, cgo, pprof and the race detector aren't yet supported.
</p>
<h3 id="darwin">Darwin</h3>
<p>
Go 1.12 is the last release that will run on macOS 10.10 Yosemite.
Go 1.13 will require macOS 10.11 El Capitan or later.
</p>
<p><!-- CL 141639 -->
<code>libSystem</code> is now used when making syscalls on Darwin,
ensuring forward-compatibility with future versions of macOS and iOS.
<!-- CL 153338 -->
The switch to <code>libSystem</code> triggered additional App Store
checks for private API usage. Since it is considered private,
<code>syscall.Getdirentries</code> now always fails with
<code>ENOSYS</code> on iOS.
</p>
<h2 id="tools">Tools</h2> <h2 id="tools">Tools</h2>
<h3 id="vet"><code>go tool vet</code> no longer supported</h3>
<p>
The <code>go vet</code> command has been rewritten to serve as the
base for a range of different source code analysis tools. See
the <a href="https://godoc.org/golang.org/x/tools/go/analysis">golang.org/x/tools/go/analysis</a>
package for details. A side-effect is that <code>go tool vet</code>
is no longer supported. External tools that use <code>go tool
vet</code> must be changed to use <code>go
vet</code>. Using <code>go vet</code> instead of <code>go tool
vet</code> should work with all supported versions of Go.
</p>
<p>
As part of this change, the experimental <code>-shadow</code> option
is no longer available with <code>go vet</code>. Checking for
variable shadowing may now be done using
<pre>
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
go vet -vettool=$(which shadow)
</pre>
</p>
<h3 id="tour">Tour</h3>
<p> <!-- CL 152657 -->
The Go tour is no longer included in the main binary distribution. To
run the tour locally, instead of running <code>go</code> <code>tool</code> <code>tour</code>,
manually install it:
<pre>
go install golang.org/x/tour
tour
</pre>
</p>
<h3 id="gocache">Build cache requirement</h3> <h3 id="gocache">Build cache requirement</h3>
<p> <p>
The build cache is now required as a step toward eliminating The <a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a> is now
required as a step toward eliminating
<code>$GOPATH/pkg</code>. Setting the environment variable <code>$GOPATH/pkg</code>. Setting the environment variable
<code>GOCACHE=off</code> to disable the <code>GOCACHE=off</code> will cause <code>go</code> commands that write to the
<a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a> cache to fail.
has no effect in Go 1.12.
</p> </p>
<h3 id="godoc">Godoc</h3> <h3 id="binary-only">Binary-only packages</h3>
<p>
Go 1.12 is the last release that will support binary-only packages.
</p>
<h3 id="cgo">Cgo</h3>
<p>
Go 1.12 will translate the C type <code>EGLDisplay</code> to the Go type <code>uintptr</code>.
This change is similar to how Go 1.10 and newer treats Darwin's CoreFoundation
and Java's JNI types. See the
<a href="/cmd/cgo/#hdr-Special_cases">cgo documentation</a>
for more information.
</p>
<p><!-- CL 152657 -->
Mangled C names are no longer accepted in packages that use Cgo. Use the Cgo
names instead. For example, use the documented cgo name <code>C.char</code>
rather than the mangled name <code>_Ctype_char</code> that cgo generates.
</p>
<h3 id="modules">Modules</h3>
<p><!-- CL 148517 -->
When <code>GO111MODULE</code> is set to <code>on</code>, the <code>go</code>
command now supports module-aware operations outside of a module directory,
provided that those operations do not need to resolve import paths relative to
the current directory or explicitly edit the <code>go.mod</code> file.
Commands such as <code>go</code> <code>get</code>,
<code>go</code> <code>list</code>, and
<code>go</code> <code>mod</code> <code>download</code> behave as if in a
module with initially-empty requirements.
In this mode, <code>go</code> <code>env</code> <code>GOMOD</code> reports
the system's null device (<code>/dev/null</code> or <code>NUL</code>).
</p>
<p><!-- CL 146382 -->
<code>go</code> commands that download and extract modules are now safe to
invoke concurrently.
The module cache (<code>GOPATH/pkg/mod</code>) must reside in a filesystem that
supports file locking.
</p>
<p><!-- CL 147282, 147281 -->
The <code>go</code> directive in a <code>go.mod</code> file now indicates the
version of the language used by the files within that module.
It will be set to the current release
(<code>go</code> <code>1.12</code>) if no existing version is
present.
If the <code>go</code> directive for a module specifies a
version <em>newer</em> than the toolchain in use, the <code>go</code> command
will attempt to build the packages regardless, and will note the mismatch only if
that build fails.
</p>
<p><!-- CL 152739 -->
When an import cannot be resolved using the active modules,
the <code>go</code> command will now try to use the modules mentioned in the
main module's <code>replace</code> directives before consulting the module
cache and the usual network sources.
If a matching replacement is found but the <code>replace</code> directive does
not specify a version, the <code>go</code> command uses a pseudo-version
derived from the zero <code>time.Time</code> (such
as <code>v0.0.0-00010101000000-000000000000</code>).
</p>
<h3 id="compiler">Compiler toolchain</h3>
<p><!-- CL 134155, 134156 -->
The compiler's live variable analysis has improved. This may mean that
finalizers will be executed sooner in this release than in previous
releases. If that is a problem, consider the appropriate addition of a
<a href="/pkg/runtime/#KeepAlive"><code>runtime.KeepAlive</code></a> call.
</p>
<p><!-- CL 147361 -->
More functions are now eligible for inlining by default, including
functions that do nothing but call another function.
This extra inlining makes it additionally important to use
<a href="/pkg/runtime/#CallersFrames"><code>runtime.CallersFrames</code></a>
instead of iterating over the result of
<a href="/pkg/runtime/#Callers"><code>runtime.Callers</code></a> directly.
<pre>
// Old code which no longer works correctly (it will miss inlined call frames).
var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
for _, pc := range pcs[:n] {
f := runtime.FuncForPC(pc)
if f != nil {
fmt.Println(f.Name())
}
}
</pre>
<pre>
// New code which will work correctly.
var pcs [10]uintptr
n := runtime.Callers(1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
for {
frame, more := frames.Next()
fmt.Println(frame.Function)
if !more {
break
}
}
</pre>
</p>
<p><!-- CL 153477 -->
Wrappers generated by the compiler to implement method expressions
are no longer reported
by <a href="/pkg/runtime/#CallersFrames"><code>runtime.CallersFrames</code></a>
and <a href="/pkg/runtime/#Stack"><code>runtime.Stack</code></a>. They
are also not printed in panic stack traces.
This change aligns the <code>gc</code> toolchain to match
the <code>gccgo</code> toolchain, which already elided such wrappers
from stack traces.
Clients of these APIs might need to adjust for the missing
frames. For code that must interoperate between 1.11 and 1.12
releases, you can replace the method expression <code>x.M</code>
with the function literal <code>func (...) { x.M(...) } </code>.
</p>
<p><!-- CL 144340 -->
The compiler now accepts a <code>-lang</code> flag to set the Go language
version to use. For example, <code>-lang=go1.8</code> causes the compiler to
emit an error if the program uses type aliases, which were added in Go 1.9.
Language changes made before Go 1.12 are not consistently enforced.
</p>
<p><!-- CL 147160 -->
The compiler toolchain now uses different conventions to call Go
functions and assembly functions. This should be invisible to users,
except for calls that simultaneously cross between Go and
assembly <em>and</em> cross a package boundary. If linking results
in an error like "relocation target not defined for ABIInternal (but
is defined for ABI0)", please refer to the
<a href="https://github.com/golang/proposal/blob/master/design/27539-internal-abi.md#compatibility">compatibility section</a>
of the ABI design document.
</p>
<p><!-- CL 145179 -->
There have been many improvements to the DWARF debug information
produced by the compiler, including improvements to argument
printing and variable location information.
</p>
<p><!-- CL 61511 -->
Go programs now also maintain stack frame pointers on <code>linux/arm64</code>
for the benefit of profiling tools like <code>perf</code>. The frame pointer
maintenance has a small run-time overhead that varies but averages around 3%.
To build a toolchain that does not use frame pointers, set
<code>GOEXPERIMENT=noframepointer</code> when running <code>make.bash</code>.
</p>
<p><!-- CL 142717 -->
The obsolete "safe" compiler mode (enabled by the <code>-u</code> gcflag) has been removed.
</p>
<h3 id="godoc"><code>godoc</code> and <code>go</code> <code>doc</code></h3>
<p> <p>
In Go 1.12, <code>godoc</code> no longer has a command-line interface and In Go 1.12, <code>godoc</code> no longer has a command-line interface and
@ -57,10 +306,138 @@ Do not send CLs removing the interior tags from such phrases.
for command-line help output instead. for command-line help output instead.
</p> </p>
<p><!-- CL 141977 -->
<code>go</code> <code>doc</code> now supports the <code>-all</code> flag,
which will cause it to print all exported APIs and their documentation,
as the <code>godoc</code> command line used to do.
</p>
<p><!-- CL 140959 -->
<code>go</code> <code>doc</code> also now includes the <code>-src</code> flag,
which will show the target's source code.
</p>
<h3 id="trace">Trace</h3>
<p><!-- CL 60790 -->
The trace tool now supports plotting mutator utilization curves,
including cross-references to the execution trace. These are useful
for analyzing the impact of the garbage collector on application
latency and throughput.
</p>
<h3 id="assembler">Assembler</h3>
<p><!-- CL 147218 -->
On <code>arm64</code>, the platform register was renamed from
<code>R18</code> to <code>R18_PLATFORM</code> to prevent accidental
use, as the OS could choose to reserve this register.
</p>
<h2 id="runtime">Runtime</h2>
<p><!-- CL 138959 -->
Go 1.12 significantly improves the performance of sweeping when a
large fraction of the heap remains live. This reduces allocation
latency immediately following a garbage collection.
</p>
<p><!-- CL 139719 -->
The Go runtime now releases memory back to the operating system more
aggressively, particularly in response to large allocations that
can't reuse existing heap space.
</p>
<p><!-- CL 146342, CL 146340, CL 146345, CL 146339, CL 146343, CL 146337, CL 146341, CL 146338 -->
The Go runtime's timer and deadline code is faster and scales better
with higher numbers of CPUs. In particular, this improves the
performance of manipulating network connection deadlines.
</p>
<p><!-- CL 135395 -->
On Linux, the runtime now uses <code>MADV_FREE</code> to release unused
memory. This is more efficient but may result in higher reported
RSS. The kernel will reclaim the unused data when it is needed.
To revert to the Go 1.11 behavior (<code>MADV_DONTNEED</code>), set the
environment variable <code>GODEBUG=madvdontneed=1</code>.
</p>
<p><!-- CL 149578 -->
Adding cpu.<em>extension</em>=off to the
<a href="/doc/diagnostics.html#godebug">GODEBUG</a> environment
variable now disables the use of optional CPU instruction
set extensions in the standard library and runtime. This is not
yet supported on Windows.
</p>
<p><!-- CL 158337 -->
Go 1.12 improves the accuracy of memory profiles by fixing
overcounting of large heap allocations.
</p>
<p><!-- CL 159717 -->
Tracebacks, <code>runtime.Caller</code>,
and <code>runtime.Callers</code> no longer include
compiler-generated initialization functions. Doing a traceback
during the initialization of a global variable will now show a
function named <code>PKG.init.ializers</code>.
</p>
<h2 id="library">Core library</h2> <h2 id="library">Core library</h2>
<h3 id="tls_1_3">TLS 1.3</h3>
<p> <p>
All of the changes to the standard library are minor. Go 1.12 adds opt-in support for TLS 1.3 in the <code>crypto/tls</code> package as
specified by <a href="https://www.rfc-editor.org/info/rfc8446">RFC 8446</a>. It can
be enabled by adding the value <code>tls13=1</code> to the <code>GODEBUG</code>
environment variable. It will be enabled by default in Go 1.13.
</p>
<p>
To negotiate TLS 1.3, make sure you do not set an explicit <code>MaxVersion</code> in
<a href="/pkg/crypto/tls/#Config"><code>Config</code></a> and run your program with
the environment variable <code>GODEBUG=tls13=1</code> set.
</p>
<p>
All TLS 1.2 features except <code>TLSUnique</code> in
<a href="/pkg/crypto/tls/#ConnectionState"><code>ConnectionState</code></a>
and renegotiation are available in TLS 1.3 and provide equivalent or
better security and performance. Note that even though TLS 1.3 is backwards
compatible with previous versions, certain legacy systems might not work
correctly when attempting to negotiate it. RSA certificate keys too small
to be secure (including 512-bit keys) will not work with TLS 1.3.
</p>
<p>
TLS 1.3 cipher suites are not configurable. All supported cipher suites are
safe, and if <code>PreferServerCipherSuites</code> is set in
<a href="/pkg/crypto/tls/#Config"><code>Config</code></a> the preference order
is based on the available hardware.
</p>
<p>
Early data (also called "0-RTT mode") is not currently supported as a
client or server. Additionally, a Go 1.12 server does not support skipping
unexpected early data if a client sends it. Since TLS 1.3 0-RTT mode
involves clients keeping state regarding which servers support 0-RTT,
a Go 1.12 server cannot be part of a load-balancing pool where some other
servers do support 0-RTT. If switching a domain from a server that supported
0-RTT to a Go 1.12 server, 0-RTT would have to be disabled for at least the
lifetime of the issued session tickets before the switch to ensure
uninterrupted operation.
</p>
<p>
In TLS 1.3 the client is the last one to speak in the handshake, so if it causes
an error to occur on the server, it will be returned on the client by the first
<a href="/pkg/crypto/tls/#Conn.Read"><code>Read</code></a>, not by
<a href="/pkg/crypto/tls/#Conn.Handshake"><code>Handshake</code></a>. For
example, that will be the case if the server rejects the client certificate.
Similarly, session tickets are now post-handshake messages, so are only
received by the client upon its first
<a href="/pkg/crypto/tls/#Conn.Read"><code>Read</code></a>.
</p> </p>
<h3 id="minor_library_changes">Minor changes to the library</h3> <h3 id="minor_library_changes">Minor changes to the library</h3>
@ -71,43 +448,83 @@ Do not send CLs removing the interior tags from such phrases.
in mind. in mind.
</p> </p>
<!-- CL 142717: https://golang.org/cl/142717: cmd/compile: remove obsolete "safe" mode --> <!-- TODO: CL 115677: https://golang.org/cl/115677: cmd/vet: check embedded field tags too -->
<!-- CL 144340: https://golang.org/cl/144340: cmd/compile: add -lang flag to specify language version -->
<!-- CL 141977: https://golang.org/cl/141977: cmd/doc: add -all flag to print all documentation for package --> <dl id="bufio"><dt><a href="/pkg/bufio/">bufio</a></dt>
<!-- CL 126656: https://golang.org/cl/126656: cmd/go: add $GOFLAGS environment variable -->
<!-- CL 115677: https://golang.org/cl/115677: cmd/vet: check embedded field tags too -->
<dl id="build"><dt><a href="/pkg/build/">build</a></dt>
<dd> <dd>
<p><!-- CL 61511 --> <p><!-- CL 149297 -->
TODO: <a href="https://golang.org/cl/61511">https://golang.org/cl/61511</a>: support frame-pointer for arm64 <code>Reader</code>'s <a href="/pkg/bufio/#Reader.UnreadRune"><code>UnreadRune</code></a> and
<a href="/pkg/bufio/#Reader.UnreadByte"><code>UnreadByte</code></a> methods will now return an error
if they are called after <a href="/pkg/bufio/#Reader.Peek"><code>Peek</code></a>.
</p> </p>
</dl><!-- build --> </dl><!-- bufio -->
<dl id="bytes, strings"><dt><a href="/pkg/bytes, strings/">bytes, strings</a></dt> <dl id="bytes"><dt><a href="/pkg/bytes/">bytes</a></dt>
<dd> <dd>
<p><!-- CL 137855 --> <p><!-- CL 137855 -->
TODO: <a href="https://golang.org/cl/137855">https://golang.org/cl/137855</a>: add ReplaceAll The new function <a href="/pkg/bytes/#ReplaceAll"><code>ReplaceAll</code></a> returns a copy of
a byte slice with all non-overlapping instances of a value replaced by another.
</p> </p>
<p><!-- CL 145098 --> <p><!-- CL 145098 -->
TODO: <a href="https://golang.org/cl/145098">https://golang.org/cl/145098</a>: fix Reader.UnreadRune returning without error on a zero Reader A pointer to a zero-value <a href="/pkg/bytes/#Reader"><code>Reader</code></a> is now
functionally equivalent to <a href="/pkg/bytes/#NewReader"><code>NewReader</code></a><code>(nil)</code>.
Prior to Go 1.12, the former could not be used as a substitute for the latter in all cases.
</p> </p>
</dl><!-- bytes, strings --> </dl><!-- bytes -->
<dl id="crypto/tls, net/http"><dt><a href="/pkg/crypto/tls, net/http/">crypto/tls, net/http</a></dt> <dl id="crypto/rand"><dt><a href="/pkg/crypto/rand/">crypto/rand</a></dt>
<dd>
<p><!-- CL 139419 -->
A warning will now be printed to standard error the first time
<code>Reader.Read</code> is blocked for more than 60 seconds waiting
to read entropy from the kernel.
</p>
<p><!-- CL 120055 -->
On FreeBSD, <code>Reader</code> now uses the <code>getrandom</code>
system call if available, <code>/dev/urandom</code> otherwise.
</p>
</dl><!-- crypto/rand -->
<dl id="crypto/rc4"><dt><a href="/pkg/crypto/rc4/">crypto/rc4</a></dt>
<dd>
<p><!-- CL 130397 -->
This release removes the optimized assembly implementations. RC4 is insecure
and should only be used for compatibility with legacy systems.
</p>
</dl><!-- crypto/rc4 -->
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
<dd> <dd>
<p><!-- CL 143177 --> <p><!-- CL 143177 -->
TODO: <a href="https://golang.org/cl/143177">https://golang.org/cl/143177</a>: reject HTTP requests to HTTPS server If a client sends an initial message that does not look like TLS, the server
will no longer reply with an alert, and it will expose the underlying
<code>net.Conn</code> in the new field <code>Conn</code> of
<a href="/pkg/crypto/tls/#RecordHeaderError"><code>RecordHeaderError</code></a>.
</p> </p>
</dl><!-- crypto/tls, net/http --> </dl><!-- crypto/tls -->
<dl id="database/sql"><dt><a href="/pkg/database/sql/">database/sql</a></dt>
<dd>
<p><!-- CL 145738 -->
A query cursor can now be obtained by passing a
<a href="/pkg/database/sql/#Rows"><code>*Rows</code></a>
value to the <a href="/pkg/database/sql/#Row.Scan"><code>Row.Scan</code></a> method.
</p>
</dl><!-- database/sql -->
<dl id="expvar"><dt><a href="/pkg/expvar/">expvar</a></dt> <dl id="expvar"><dt><a href="/pkg/expvar/">expvar</a></dt>
<dd> <dd>
<p><!-- CL 139537 --> <p><!-- CL 139537 -->
TODO: <a href="https://golang.org/cl/139537">https://golang.org/cl/139537</a>: add Map.Delete The new <a href="/pkg/expvar/#Map.Delete"><code>Delete</code></a> method allows
for deletion of key/value pairs from a <a href="/pkg/expvar/#Map"><code>Map</code></a>.
</p> </p>
</dl><!-- expvar --> </dl><!-- expvar -->
@ -115,39 +532,55 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="fmt"><dt><a href="/pkg/fmt/">fmt</a></dt> <dl id="fmt"><dt><a href="/pkg/fmt/">fmt</a></dt>
<dd> <dd>
<p><!-- CL 142737 --> <p><!-- CL 142737 -->
TODO: <a href="https://golang.org/cl/142737">https://golang.org/cl/142737</a>: print maps in key-sorted order Maps are now printed in key-sorted order to ease testing. The ordering rules are:
<ul>
<li>When applicable, nil compares low
<li>ints, floats, and strings order by <
<li>NaN compares less than non-NaN floats
<li>bool compares false before true
<li>Complex compares real, then imaginary
<li>Pointers compare by machine address
<li>Channel values compare by machine address
<li>Structs compare each field in turn
<li>Arrays compare each element in turn
<li>Interface values compare first by <code>reflect.Type</code> describing the concrete type
and then by concrete value as described in the previous rules.
</ul>
</p>
<p><!-- CL 129777 -->
When printing maps, non-reflexive key values like <code>NaN</code> were previously
displayed as <code>&lt;nil&gt;</code>. As of this release, the correct values are printed.
</p> </p>
</dl><!-- fmt --> </dl><!-- fmt -->
<dl id="go/build, cmd/go"><dt><a href="/pkg/go/build, cmd/go/">go/build, cmd/go</a></dt>
<dd>
<p><!-- CL 146023 -->
TODO: <a href="https://golang.org/cl/146023">https://golang.org/cl/146023</a>: add &#34;hurd&#34; as a GOOS value
</p>
</dl><!-- go/build, cmd/go -->
<dl id="go/doc"><dt><a href="/pkg/go/doc/">go/doc</a></dt> <dl id="go/doc"><dt><a href="/pkg/go/doc/">go/doc</a></dt>
<dd> <dd>
<p><!-- CL 140958 --> <p><!-- CL 140958 -->
TODO: <a href="https://golang.org/cl/140958">https://golang.org/cl/140958</a>: add new mode bit PreserveAST to control clearing of data in AST To address some outstanding issues in <a href="/cmd/doc/"><code>cmd/doc</code></a>,
this package has a new <a href="/pkg/go/doc/#Mode"><code>Mode</code></a> bit,
<code>PreserveAST</code>, which controls whether AST data is cleared.
</p> </p>
</dl><!-- go/doc --> </dl><!-- go/doc -->
<dl id="godoc, cmd/godoc"><dt><a href="/pkg/godoc, cmd/godoc/">godoc, cmd/godoc</a></dt> <dl id="go/token"><dt><a href="/pkg/go/token/">go/token</a></dt>
<dd> <dd>
<p><!-- CL 141397 --> <p><!-- CL 134075 -->
TODO: <a href="https://golang.org/cl/141397">https://golang.org/cl/141397</a>: remove CLI support The <a href="/pkg/go/token#File"><code>File</code></a> type has a new
<a href="/pkg/go/token#File.LineStart"><code>LineStart</code></a> field,
which returns the position of the start of a given line. This is especially useful
in programs that occasionally handle non-Go files, such as assembly, but wish to use
the <code>token.Pos</code> mechanism to identify file positions.
</p> </p>
</dl><!-- godoc, cmd/godoc --> </dl><!-- go/token -->
<dl id="image"><dt><a href="/pkg/image/">image</a></dt> <dl id="image"><dt><a href="/pkg/image/">image</a></dt>
<dd> <dd>
<p><!-- CL 118755 --> <p><!-- CL 118755 -->
TODO: <a href="https://golang.org/cl/118755">https://golang.org/cl/118755</a>: make RegisterFormat safe for concurrent use The <a href="/pkg/image/#RegisterFormat"><code>RegisterFormat</code></a> function is now safe for concurrent use.
</p> </p>
</dl><!-- image --> </dl><!-- image -->
@ -155,119 +588,295 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="image/png"><dt><a href="/pkg/image/png/">image/png</a></dt> <dl id="image/png"><dt><a href="/pkg/image/png/">image/png</a></dt>
<dd> <dd>
<p><!-- CL 134235 --> <p><!-- CL 134235 -->
TODO: <a href="https://golang.org/cl/134235">https://golang.org/cl/134235</a>: pack image data for small bitdepth paletted images Paletted images with fewer than 16 colors now encode to smaller outputs.
</p> </p>
</dl><!-- image/png --> </dl><!-- image/png -->
<dl id="internal/poll"><dt><a href="/pkg/internal/poll/">internal/poll</a></dt>
<dd>
<p><!-- CL 130676 -->
TODO: <a href="https://golang.org/cl/130676">https://golang.org/cl/130676</a>: use F_FULLFSYNC fcntl for FD.Fsync on OS X
</p>
</dl><!-- internal/poll -->
<dl id="io"><dt><a href="/pkg/io/">io</a></dt> <dl id="io"><dt><a href="/pkg/io/">io</a></dt>
<dd> <dd>
<p><!-- CL 139457 --> <p><!-- CL 139457 -->
TODO: <a href="https://golang.org/cl/139457">https://golang.org/cl/139457</a>: export StringWriter The new <a href="/pkg/io#StringWriter"><code>StringWriter</code></a> interface wraps the
<a href="/pkg/io/#WriteString"><code>WriteString</code></a> function.
</p> </p>
</dl><!-- io --> </dl><!-- io -->
<dl id="lib/time"><dt><a href="/pkg/lib/time/">lib/time</a></dt>
<dd>
<p><!-- CL 151299 -->
The time zone database in <code>$GOROOT/lib/time/zoneinfo.zip</code>
has been updated to version 2018i. Note that this ZIP file is
only used if a time zone database is not provided by the operating
system.
</p>
</dl><!-- lib/time -->
<dl id="math"><dt><a href="/pkg/math/">math</a></dt>
<dd>
<p><!-- CL 153059 -->
The functions
<a href="/pkg/math/#Sin"><code>Sin</code></a>,
<a href="/pkg/math/#Cos"><code>Cos</code></a>,
<a href="/pkg/math/#Tan"><code>Tan</code></a>,
and <a href="/pkg/math/#Sincos"><code>Sincos</code></a> now
apply Payne-Hanek range reduction to huge arguments. This
produces more accurate answers, but they will not be bit-for-bit
identical with the results in earlier releases.
</p>
</dl><!-- math -->
<dl id="math/bits"><dt><a href="/pkg/math/bits/">math/bits</a></dt> <dl id="math/bits"><dt><a href="/pkg/math/bits/">math/bits</a></dt>
<dd> <dd>
<p><!-- CL 123157 --> <p><!-- CL 123157 -->
TODO: <a href="https://golang.org/cl/123157">https://golang.org/cl/123157</a>: add extended precision Add, Sub, Mul, Div New extended precision operations <a href="/pkg/math/bits/#Add"><code>Add</code></a>, <a href="/pkg/math/bits/#Sub"><code>Sub</code></a>, <a href="/pkg/math/bits/#Mul"><code>Mul</code></a>, and <a href="/pkg/math/bits/#Div"><code>Div</code></a> are available in <code>uint</code>, <code>uint32</code>, and <code>uint64</code> versions.
</p> </p>
</dl><!-- math/bits --> </dl><!-- math/bits -->
<dl id="net"><dt><a href="/pkg/net/">net</a></dt> <dl id="net"><dt><a href="/pkg/net/">net</a></dt>
<dd> <dd>
<p><!-- CL 113997 --> <p><!-- CL 146659 -->
TODO: <a href="https://golang.org/cl/113997">https://golang.org/cl/113997</a>: use splice(2) on Linux when reading from UnixConn, rework splice tests The
<a href="/pkg/net/#Dialer.DualStack"><code>Dialer.DualStack</code></a> setting is now ignored and deprecated;
RFC 6555 Fast Fallback ("Happy Eyeballs") is now enabled by default. To disable, set
<a href="/pkg/net/#Dialer.FallbackDelay"><code>Dialer.FallbackDelay</code></a> to a negative value.
</p> </p>
<p><!-- CL 107196 -->
Similarly, TCP keep-alives are now enabled by default if
<a href="/pkg/net/#Dialer.KeepAlive"><code>Dialer.KeepAlive</code></a> is zero.
To disable, set it to a negative value.
</p>
<p><!-- CL 113997 -->
On Linux, the <a href="http://man7.org/linux/man-pages/man2/splice.2.html"><code>splice</code> system call</a> is now used when copying from a
<a href="/pkg/net/#UnixConn"><code>UnixConn</code></a> to a
<a href="/pkg/net/#TCPConn"><code>TCPConn</code></a>.
</p>
</dl><!-- net --> </dl><!-- net -->
<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt> <dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
<dd> <dd>
<p><!-- CL 143177 -->
The HTTP server now rejects misdirected HTTP requests to HTTPS servers with a plaintext "400 Bad Request" response.
</p>
<p><!-- CL 130115 --> <p><!-- CL 130115 -->
TODO: <a href="https://golang.org/cl/130115">https://golang.org/cl/130115</a>: add Client.CloseIdleConnections The new <a href="/pkg/net/http/#Client.CloseIdleConnections"><code>Client.CloseIdleConnections</code></a>
method calls the <code>Client</code>'s underlying <code>Transport</code>'s <code>CloseIdleConnections</code>
if it has one.
</p> </p>
<p><!-- CL 145398 --> <p><!-- CL 145398 -->
TODO: <a href="https://golang.org/cl/145398">https://golang.org/cl/145398</a>: in Transport, don&#39;t error on non-chunked response with Trailer header The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer rejects HTTP responses which declare
HTTP Trailers but don't use chunked encoding. Instead, the declared trailers are now just ignored.
</p>
<p><!-- CL 152080 --> <!-- CL 151857 -->
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer handles <code>MAX_CONCURRENT_STREAMS</code> values
advertised from HTTP/2 servers as strictly as it did during Go 1.10 and Go 1.11. The default behavior is now back
to how it was in Go 1.9: each connection to a server can have up to <code>MAX_CONCURRENT_STREAMS</code> requests
active and then new TCP connections are created as needed. In Go 1.10 and Go 1.11 the <code>http2</code> package
would block and wait for requests to finish instead of creating new connections.
To get the stricter behavior back, import the
<a href="https://godoc.org/golang.org/x/net/http2"><code>golang.org/x/net/http2</code></a> package
directly and set
<a href="https://godoc.org/golang.org/x/net/http2#Transport.StrictMaxConcurrentStreams"><code>Transport.StrictMaxConcurrentStreams</code></a> to
<code>true</code>.
</p> </p>
</dl><!-- net/http --> </dl><!-- net/http -->
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd>
<p><!-- CL 146437 -->
The <a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a> now automatically
proxies WebSocket requests.
</p>
</dl><!-- net/http/httputil -->
<dl id="os"><dt><a href="/pkg/os/">os</a></dt> <dl id="os"><dt><a href="/pkg/os/">os</a></dt>
<dd> <dd>
<p><!-- CL 125443 --> <p><!-- CL 125443 -->
TODO: <a href="https://golang.org/cl/125443">https://golang.org/cl/125443</a>: add ExitCode method to ProcessState The new <a href="/pkg/os/#ProcessState.ExitCode"><code>ProcessState.ExitCode</code></a> method
returns the process's exit code.
</p> </p>
<p><!-- CL 135075 --> <p><!-- CL 135075 -->
TODO: <a href="https://golang.org/cl/135075">https://golang.org/cl/135075</a>: add ModeCharDevice to ModeType <code>ModeCharDevice</code> has been added to the <code>ModeType</code> bitmask, allowing for
<code>ModeDevice | ModeCharDevice</code> to be recovered when masking a
<a href="/pkg/os/#FileMode"><code>FileMode</code></a> with <code>ModeType</code>.
</p> </p>
<p><!-- CL 139418 --> <p><!-- CL 139418 -->
TODO: <a href="https://golang.org/cl/139418">https://golang.org/cl/139418</a>: add UserHomeDir The new function <a href="/pkg/os/#UserHomeDir"><code>UserHomeDir</code></a> returns the
current user's home directory.
</p>
<p><!-- CL 146020 -->
<a href="/pkg/os/#RemoveAll"><code>RemoveAll</code></a> now supports paths longer than 4096 characters
on most Unix systems.
</p>
<p><!-- CL 130676 -->
<a href="/pkg/os/#File.Sync"><code>File.Sync</code></a> now uses <code>F_FULLFSYNC</code> on macOS
to correctly flush the file contents to permanent storage.
This may cause the method to run more slowly than in previous releases.
</p>
<p><!--CL 155517 -->
<a href="/pkg/os/#File"><code>File</code></a> now supports
a <a href="/pkg/os/#File.SyscallConn"><code>SyscallConn</code></a>
method returning
a <a href="/pkg/syscall/#RawConn"><code>syscall.RawConn</code></a>
interface value. This may be used to invoke system-specific
operations on the underlying file descriptor.
</p> </p>
</dl><!-- os --> </dl><!-- os -->
<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
<dd>
<p><!-- CL 145220 -->
The <a href="/pkg/path/filepath/#IsAbs"><code>IsAbs</code></a> function now returns true when passed
a reserved filename on Windows such as <code>NUL</code>.
<a href="https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#naming-conventions">List of reserved names.</a>
</p>
</dl><!-- path/filepath -->
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt> <dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
<dd> <dd>
<p><!-- CL 33572 --> <p><!-- CL 33572 -->
TODO: <a href="https://golang.org/cl/33572">https://golang.org/cl/33572</a>: add Value.MapRange method and MapIter type A new <a href="/pkg/reflect#MapIter"><code>MapIter</code></a> type is
an iterator for ranging over a map. This type is exposed through the
<a href="/pkg/reflect#Value"><code>Value</code></a> type's new
<a href="/pkg/reflect#Value.MapRange"><code>MapRange</code></a> method.
This follows the same iteration semantics as a range statement, with <code>Next</code>
to advance the iterator, and <code>Key</code>/<code>Value</code> to access each entry.
</p> </p>
</dl><!-- reflect --> </dl><!-- reflect -->
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt> <dl id="regexp"><dt><a href="/pkg/regexp/">regexp</a></dt>
<dd> <dd>
<p><!-- CL 135395 --> <p><!-- CL 139784 -->
TODO: <a href="https://golang.org/cl/135395">https://golang.org/cl/135395</a>: use MADV_FREE on Linux if available <a href="/pkg/regexp/#Regexp.Copy"><code>Copy</code></a> is no longer necessary
to avoid lock contention, so it has been given a partial deprecation comment.
<a href="/pkg/regexp/#Regexp.Copy"><code>Copy</code></a>
may still be appropriate if the reason for its use is to make two copies with
different <a href="/pkg/regexp/#Regexp.Longest"><code>Longest</code></a> settings.
</p> </p>
</dl><!-- runtime --> </dl><!-- regexp -->
<dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
<dd>
<p><!-- CL 144220 -->
A new <a href="/pkg/runtime/debug/#BuildInfo"><code>BuildInfo</code></a> type
exposes the build information read from the running binary, available only in
binaries built with module support. This includes the main package path, main
module information, and the module dependencies. This type is given though the
<a href="/pkg/runtime/debug/#ReadBuildInfo"><code>ReadBuildInfo</code></a> function
on <a href="/pkg/runtime/debug/#BuildInfo"><code>BuildInfo</code></a>.
</p>
</dl><!-- runtime/debug -->
<dl id="strings"><dt><a href="/pkg/strings/">strings</a></dt> <dl id="strings"><dt><a href="/pkg/strings/">strings</a></dt>
<dd> <dd>
<p><!-- CL 137855 -->
The new function <a href="/pkg/strings/#ReplaceAll"><code>ReplaceAll</code></a> returns a copy of
a string with all non-overlapping instances of a value replaced by another.
</p>
<p><!-- CL 145098 -->
A pointer to a zero-value <a href="/pkg/strings/#Reader"><code>Reader</code></a> is now
functionally equivalent to <a href="/pkg/strings/#NewReader"><code>NewReader</code></a><code>(nil)</code>.
Prior to Go 1.12, the former could not be used as a substitute for the latter in all cases.
</p>
<p><!-- CL 122835 --> <p><!-- CL 122835 -->
TODO: <a href="https://golang.org/cl/122835">https://golang.org/cl/122835</a>: add Builder.Cap The new <a href="/pkg/strings/#Builder.Cap"><code>Builder.Cap</code></a> method returns the capacity of the builder's underlying byte slice.
</p>
<p><!-- CL 131495 -->
The character mapping functions <a href="/pkg/strings/#Map"><code>Map</code></a>,
<a href="/pkg/strings/#Title"><code>Title</code></a>,
<a href="/pkg/strings/#ToLower"><code>ToLower</code></a>,
<a href="/pkg/strings/#ToLowerSpecial"><code>ToLowerSpecial</code></a>,
<a href="/pkg/strings/#ToTitle"><code>ToTitle</code></a>,
<a href="/pkg/strings/#ToTitleSpecial"><code>ToTitleSpecial</code></a>,
<a href="/pkg/strings/#ToUpper"><code>ToUpper</code></a>, and
<a href="/pkg/strings/#ToUpperSpecial"><code>ToUpperSpecial</code></a>
now always guarantee to return valid UTF-8. In earlier releases, if the input was invalid UTF-8 but no character replacements
needed to be applied, these routines incorrectly returned the invalid UTF-8 unmodified.
</p> </p>
</dl><!-- strings --> </dl><!-- strings -->
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt> <dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
<dd> <dd>
<p><!-- CL 125456 --> <p><!-- CL 138595 -->
TODO: <a href="https://golang.org/cl/125456">https://golang.org/cl/125456</a>: implement Unix Socket for Windows 64-bit inodes are now supported on FreeBSD 12. Some types have been adjusted accordingly.
</p> </p>
<p><!-- CL 138595 --> <p><!-- CL 125456 -->
TODO: <a href="https://golang.org/cl/138595">https://golang.org/cl/138595</a>: FreeBSD 12 ino64 support The Unix socket
(<a href="https://blogs.msdn.microsoft.com/commandline/2017/12/19/af_unix-comes-to-windows/"><code>AF_UNIX</code></a>)
address family is now supported for compatible versions of Windows.
</p>
<p><!-- CL 147117 -->
The new function <a href="/pkg/syscall/?GOOS=windows&GOARCH=amd64#Syscall18"><code>Syscall18</code></a>
has been introduced for Windows, allowing for calls with up to 18 arguments.
</p> </p>
</dl><!-- syscall --> </dl><!-- syscall -->
<dl id="syscall/js"><dt><a href="/pkg/syscall/js/">syscall/js</a></dt> <dl id="syscall/js"><dt><a href="/pkg/syscall/js/">syscall/js</a></dt>
<dd> <dd>
<p><!-- CL 153559 -->
<p>
The <code>Callback</code> type and <code>NewCallback</code> function have been renamed;
they are now called
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Func"><code>Func</code></a> and
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#FuncOf"><code>FuncOf</code></a>, respectively.
This is a breaking change, but WebAssembly support is still experimental
and not yet subject to the
<a href="/doc/go1compat">Go 1 compatibility promise</a>. Any code using the
old names will need to be updated.
</p>
<p><!-- CL 141644 --> <p><!-- CL 141644 -->
TODO: <a href="https://golang.org/cl/141644">https://golang.org/cl/141644</a>: add Wrapper interface to support external Value wrapper types If a type implements the new
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Wrapper"><code>Wrapper</code></a>
interface,
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#ValueOf"><code>ValueOf</code></a>
will use it to return the JavaScript value for that type.
</p> </p>
<p><!-- CL 143137 --> <p><!-- CL 143137 -->
TODO: <a href="https://golang.org/cl/143137">https://golang.org/cl/143137</a>: make zero js.Value represent &#34;undefined&#34; The meaning of the zero
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Value"><code>Value</code></a>
has changed. It now represents the JavaScript <code>undefined</code> value
instead of the number zero.
This is a breaking change, but WebAssembly support is still experimental
and not yet subject to the
<a href="/doc/go1compat">Go 1 compatibility promise</a>. Any code relying on
the zero <a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Value"><code>Value</code></a>
to mean the number zero will need to be updated.
</p> </p>
<p><!-- CL 144384 --> <p><!-- CL 144384 -->
TODO: <a href="https://golang.org/cl/144384">https://golang.org/cl/144384</a>: add the Value.Truthy method The new
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Value.Truthy"><code>Value.Truthy</code></a>
method reports the
<a href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy">JavaScript "truthiness"</a>
of a given value.
</p> </p>
</dl><!-- syscall/js --> </dl><!-- syscall/js -->
@ -275,8 +884,39 @@ Do not send CLs removing the interior tags from such phrases.
<dl id="testing"><dt><a href="/pkg/testing/">testing</a></dt> <dl id="testing"><dt><a href="/pkg/testing/">testing</a></dt>
<dd> <dd>
<p><!-- CL 139258 --> <p><!-- CL 139258 -->
TODO: <a href="https://golang.org/cl/139258">https://golang.org/cl/139258</a>: implement -benchtime=100x The <a href="/cmd/go/#hdr-Testing_flags"><code>-benchtime</code></a> flag now supports setting an explicit iteration count instead of a time when the value ends with an "<code>x</code>". For example, <code>-benchtime=100x</code> runs the benchmark 100 times.
</p> </p>
</dl><!-- testing --> </dl><!-- testing -->
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
<dd>
<p><!-- CL 142217 -->
When executing a template, long context values are no longer truncated in errors.
</p>
<p>
<code>executing "tmpl" at <.very.deep.context.v...>: map has no entry for key "notpresent"</code>
</p>
<p>
is now
</p>
<p>
<code>executing "tmpl" at <.very.deep.context.value.notpresent>: map has no entry for key "notpresent"</code>
</p>
<dd>
<p><!-- CL 143097 -->
If a user-defined function called by a template panics, the
panic is now caught and returned as an error by
the <code>Execute</code> or <code>ExecuteTemplate</code> method.
</p>
</dl><!-- text/template -->
<dl id="unsafe"><dt><a href="/pkg/unsafe/">unsafe</a></dt>
<dd>
<p><!-- CL 146058 -->
It is invalid to convert a nil <code>unsafe.Pointer</code> to <code>uintptr</code> and back with arithmetic.
(This was already invalid, but will now cause the compiler to misbehave.)
</p>
</dl><!-- unsafe -->

View file

@ -1769,7 +1769,7 @@ while that of the corresponding pointer
type <code>*T</code> consists of all methods with receiver <code>*T</code> or type <code>*T</code> consists of all methods with receiver <code>*T</code> or
<code>T</code>. <code>T</code>.
That means the method set of <code>*T</code> That means the method set of <code>*T</code>
includes that of <code>T</code>), includes that of <code>T</code>,
but not the reverse. but not the reverse.
</p> </p>

View file

@ -418,8 +418,12 @@ func twoprint() {
</pre> </pre>
<p> <p>
calling <code>twoprint</code> causes <code>"hello, world"</code> to be printed twice. calling <code>twoprint</code> will call <code>setup</code> exactly
The first call to <code>doprint</code> runs <code>setup</code> once. once.
The <code>setup</code> function will complete before either call
of <code>print</code>.
The result will be that <code>"hello, world"</code> will be printed
twice.
</p> </p>
<h2>Incorrect synchronization</h2> <h2>Incorrect synchronization</h2>

View file

@ -1,6 +1,6 @@
<!--{ <!--{
"Title": "The Go Programming Language Specification", "Title": "The Go Programming Language Specification",
"Subtitle": "Version of October 23, 2018", "Subtitle": "Version of November 16, 2018",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
@ -823,6 +823,7 @@ particular architecture.
<p> <p>
A <i>string type</i> represents the set of string values. A <i>string type</i> represents the set of string values.
A string value is a (possibly empty) sequence of bytes. A string value is a (possibly empty) sequence of bytes.
The number of bytes is called the length of the string and is never negative.
Strings are immutable: once created, Strings are immutable: once created,
it is impossible to change the contents of a string. it is impossible to change the contents of a string.
The predeclared string type is <code>string</code>; The predeclared string type is <code>string</code>;
@ -830,7 +831,7 @@ it is a <a href="#Type_definitions">defined type</a>.
</p> </p>
<p> <p>
The length of a string <code>s</code> (its size in bytes) can be discovered using The length of a string <code>s</code> can be discovered using
the built-in function <a href="#Length_and_capacity"><code>len</code></a>. the built-in function <a href="#Length_and_capacity"><code>len</code></a>.
The length is a compile-time constant if the string is a constant. The length is a compile-time constant if the string is a constant.
A string's bytes can be accessed by integer <a href="#Index_expressions">indices</a> A string's bytes can be accessed by integer <a href="#Index_expressions">indices</a>
@ -846,8 +847,7 @@ string, <code>&amp;s[i]</code> is invalid.
<p> <p>
An array is a numbered sequence of elements of a single An array is a numbered sequence of elements of a single
type, called the element type. type, called the element type.
The number of elements is called the length and is never The number of elements is called the length of the array and is never negative.
negative.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
@ -883,6 +883,7 @@ multi-dimensional types.
A slice is a descriptor for a contiguous segment of an <i>underlying array</i> and A slice is a descriptor for a contiguous segment of an <i>underlying array</i> and
provides access to a numbered sequence of elements from that array. provides access to a numbered sequence of elements from that array.
A slice type denotes the set of all slices of arrays of its element type. A slice type denotes the set of all slices of arrays of its element type.
The number of elements is called the length of the slice and is never negative.
The value of an uninitialized slice is <code>nil</code>. The value of an uninitialized slice is <code>nil</code>.
</p> </p>
@ -891,8 +892,7 @@ SliceType = "[" "]" ElementType .
</pre> </pre>
<p> <p>
Like arrays, slices are indexable and have a length. The length of a The length of a slice <code>s</code> can be discovered by the built-in function
slice <code>s</code> can be discovered by the built-in function
<a href="#Length_and_capacity"><code>len</code></a>; unlike with arrays it may change during <a href="#Length_and_capacity"><code>len</code></a>; unlike with arrays it may change during
execution. The elements can be addressed by integer <a href="#Index_expressions">indices</a> execution. The elements can be addressed by integer <a href="#Index_expressions">indices</a>
0 through <code>len(s)-1</code>. The slice index of a 0 through <code>len(s)-1</code>. The slice index of a
@ -1348,8 +1348,9 @@ ChannelType = ( "chan" | "chan" "&lt;-" | "&lt;-" "chan" ) ElementType .
The optional <code>&lt;-</code> operator specifies the channel <i>direction</i>, The optional <code>&lt;-</code> operator specifies the channel <i>direction</i>,
<i>send</i> or <i>receive</i>. If no direction is given, the channel is <i>send</i> or <i>receive</i>. If no direction is given, the channel is
<i>bidirectional</i>. <i>bidirectional</i>.
A channel may be constrained only to send or only to receive by explicit A channel may be constrained only to send or only to receive by
<a href="#Conversions">conversion</a> or <a href="#Assignments">assignment</a>. <a href="#Assignments">assignment</a> or
explicit <a href="#Conversions">conversion</a>.
</p> </p>
<pre> <pre>
@ -3624,7 +3625,7 @@ For signed integers, the operations <code>+</code>,
<code>-</code>, <code>*</code>, <code>/</code>, and <code>&lt;&lt;</code> may legally <code>-</code>, <code>*</code>, <code>/</code>, and <code>&lt;&lt;</code> may legally
overflow and the resulting value exists and is deterministically defined overflow and the resulting value exists and is deterministically defined
by the signed integer representation, the operation, and its operands. by the signed integer representation, the operation, and its operands.
Overflow does not cause a <a href="#Run_time_panics">run-time panic</a>. Overflow does not cause a <a href="#Run_time_panics">run-time panic</a>.
A compiler may not optimize code under the assumption that overflow does A compiler may not optimize code under the assumption that overflow does
not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true. not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true.
</p> </p>

View file

@ -271,6 +271,39 @@ which describes some essential concepts about using the Go tools.
</p> </p>
<h2 id="extra_versions">Installing extra Go versions</h2>
<p>
It may be useful to have multiple Go versions installed on the same machine, for
example, to ensure that a package's tests pass on multiple Go versions.
Once you have one Go version installed, you can install another (such as 1.10.7)
as follows:
</p>
<pre>
$ go get golang.org/dl/go1.10.7
$ go1.10.7 download
</pre>
<p>
The newly downloaded version can be used like <code>go</code>:
</p>
<pre>
$ go1.10.7 version
go version go1.10.7 linux/amd64
</pre>
<p>
All Go versions available via this method are listed on
<a href="https://godoc.org/golang.org/dl#pkg-subdirectories">the download page</a>.
You can find where each of these extra Go versions is installed by looking
at its <code>GOROOT</code>; for example, <code>go1.10.7 env GOROOT</code>.
To uninstall a downloaded version, just remove its <code>GOROOT</code> directory
and the <code>goX.Y.Z</code> binary.
</p>
<h2 id="uninstall">Uninstalling Go</h2> <h2 id="uninstall">Uninstalling Go</h2>
<p> <p>

View file

@ -28,11 +28,18 @@ func (s Sequence) Swap(i, j int) {
s[i], s[j] = s[j], s[i] s[i], s[j] = s[j], s[i]
} }
// Copy returns a copy of the Sequence.
func (s Sequence) Copy() Sequence {
copy := make(Sequence, 0, len(s))
return append(copy, s...)
}
// Method for printing - sorts the elements before printing. // Method for printing - sorts the elements before printing.
func (s Sequence) String() string { func (s Sequence) String() string {
s = s.Copy() // Make a copy; don't overwrite argument.
sort.Sort(s) sort.Sort(s)
str := "[" str := "["
for i, elem := range s { for i, elem := range s { // Loop is O(N²); will fix that in next example.
if i > 0 { if i > 0 {
str += " " str += " "
} }

View file

@ -70,7 +70,7 @@ This person coordinates the fix and release process.</li>
<li>Code is audited to find any potential similar problems.</li> <li>Code is audited to find any potential similar problems.</li>
<li>If it is determined, in consultation with the submitter, that a CVE-ID is <li>If it is determined, in consultation with the submitter, that a CVE-ID is
required, the primary handler obtains one via email to required, the primary handler obtains one via email to
<a href="http://oss-security.openwall.org/wiki/mailing-lists/distros">oss-distros</a>.</li> <a href="https://oss-security.openwall.org/wiki/mailing-lists/distros">oss-distros</a>.</li>
<li>Fixes are prepared for the two most recent major releases and the head/master <li>Fixes are prepared for the two most recent major releases and the head/master
revision. These fixes are not yet committed to the public repository.</li> revision. These fixes are not yet committed to the public repository.</li>
<li>A notification is sent to the <li>A notification is sent to the

View file

@ -8,8 +8,8 @@
# Consult https://www.iana.org/time-zones for the latest versions. # Consult https://www.iana.org/time-zones for the latest versions.
# Versions to use. # Versions to use.
CODE=2018e CODE=2018i
DATA=2018e DATA=2018i
set -e set -e
rm -rf work rm -rf work

Binary file not shown.

View file

@ -121,12 +121,19 @@ func TestReportsTypeErrors(t *testing.T) {
"issue16591.go", "issue16591.go",
"issue18452.go", "issue18452.go",
"issue18889.go", "issue18889.go",
"issue26745.go",
"issue28721.go",
} { } {
check(t, file) check(t, file)
} }
if sizeofLongDouble(t) > 8 { if sizeofLongDouble(t) > 8 {
check(t, "err4.go") for _, file := range []string{
"err4.go",
"issue28069.go",
} {
check(t, file)
}
} }
} }

View file

@ -406,6 +406,24 @@ var ptrTests = []ptrTest{
body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`, body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`,
fail: false, fail: false,
}, },
{
// Test that bgsweep releasing a finalizer is OK.
name: "finalizer",
c: `// Nothing to declare.`,
imports: []string{"os"},
support: `func open() { os.Open(os.Args[0]) }; var G [][]byte`,
body: `for i := 0; i < 10000; i++ { G = append(G, make([]byte, 4096)); if i % 100 == 0 { G = nil; open() } }`,
fail: false,
},
{
// Test that converting generated struct to interface is OK.
name: "structof",
c: `// Nothing to declare.`,
imports: []string{"reflect"},
support: `type MyInt int; func (i MyInt) Get() int { return int(i) }; type Getter interface { Get() int }`,
body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt", Type: reflect.TypeOf(MyInt(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter).Get()`,
fail: false,
},
} }
func TestPointerChecks(t *testing.T) { func TestPointerChecks(t *testing.T) {
@ -478,7 +496,7 @@ func testOne(t *testing.T, pt ptrTest) {
cmd := exec.Command("go", "build") cmd := exec.Command("go", "build")
cmd.Dir = src cmd.Dir = src
cmd.Env = addEnv("GOPATH", gopath) cmd.Env = append(os.Environ(), "GOPATH="+gopath)
buf, err := cmd.CombinedOutput() buf, err := cmd.CombinedOutput()
if err != nil { if err != nil {
t.Logf("%#q:\n%s", args(cmd), buf) t.Logf("%#q:\n%s", args(cmd), buf)
@ -550,16 +568,5 @@ func testOne(t *testing.T, pt ptrTest) {
} }
func cgocheckEnv(val string) []string { func cgocheckEnv(val string) []string {
return addEnv("GODEBUG", "cgocheck="+val) return append(os.Environ(), "GODEBUG=cgocheck="+val)
}
func addEnv(key, val string) []string {
env := []string{key + "=" + val}
look := key + "="
for _, e := range os.Environ() {
if !strings.HasPrefix(e, look) {
env = append(env, e)
}
}
return env
} }

View file

@ -0,0 +1,17 @@
// 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 main
// int a;
// void CF(int i) {}
import "C"
func F1(i int) int {
return C.a + 1 // ERROR HERE: :13
}
func F2(i int) {
C.CF(i) // ERROR HERE: :6
}

View file

@ -0,0 +1,26 @@
// 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.
// Test that the error message for an unrepresentable typedef in a
// union appears on the right line. This test is only run if the size
// of long double is larger than 64.
package main
/*
typedef long double Float128;
typedef struct SV {
union {
Float128 float128;
} value;
} SV;
*/
import "C"
type ts struct {
tv *C.SV // ERROR HERE
}
func main() {}

View file

@ -0,0 +1,29 @@
// 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.
// cgo should reject the use of mangled C names.
package main
/*
typedef struct a {
int i;
} a;
void fn(void) {}
*/
import "C"
type B _Ctype_struct_a // ERROR HERE
var a _Ctype_struct_a // ERROR HERE
type A struct {
a *_Ctype_struct_a // ERROR HERE
}
var notExist _Ctype_NotExist // ERROR HERE
func main() {
_Cfunc_fn() // ERROR HERE
}

View file

@ -179,7 +179,6 @@ func testCallbackCallers(t *testing.T) {
pc := make([]uintptr, 100) pc := make([]uintptr, 100)
n := 0 n := 0
name := []string{ name := []string{
"runtime.call16",
"runtime.cgocallbackg1", "runtime.cgocallbackg1",
"runtime.cgocallbackg", "runtime.cgocallbackg",
"runtime.cgocallback_gofunc", "runtime.cgocallback_gofunc",
@ -193,9 +192,6 @@ func testCallbackCallers(t *testing.T) {
"testing.tRunner", "testing.tRunner",
"runtime.goexit", "runtime.goexit",
} }
if unsafe.Sizeof((*byte)(nil)) == 8 {
name[0] = "runtime.call32"
}
nestedCall(func() { nestedCall(func() {
n = runtime.Callers(4, pc) n = runtime.Callers(4, pc)
}) })

View file

@ -93,6 +93,8 @@ func Test23356(t *testing.T) { test23356(t) }
func Test26066(t *testing.T) { test26066(t) } func Test26066(t *testing.T) { test26066(t) }
func Test26213(t *testing.T) { test26213(t) } func Test26213(t *testing.T) { test26213(t) }
func Test27660(t *testing.T) { test27660(t) } func Test27660(t *testing.T) { test27660(t) }
func Test28896(t *testing.T) { test28896(t) }
func Test30065(t *testing.T) { test30065(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) } func BenchmarkGoString(b *testing.B) { benchGoString(b) }

View file

@ -0,0 +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.
// This is the relevant part of EGL/egl.h.
typedef void *EGLDisplay;

View file

@ -0,0 +1,17 @@
// 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 issue27054
/*
#include "egl.h"
*/
import "C"
import (
"testing"
)
func Test27054(t *testing.T) {
var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type.
}

View file

@ -0,0 +1,12 @@
// 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.
// Failed to resolve typedefs consistently.
// No runtime test; just make sure it compiles.
package cgotest
import "./issue27340"
var issue27340Var = issue27340.Issue27340GoFunc

View file

@ -0,0 +1,42 @@
// 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.
// Failed to resolve typedefs consistently.
// No runtime test; just make sure it compiles.
// In separate directory to isolate #pragma GCC diagnostic.
package issue27340
// We use the #pragma to avoid a compiler warning about incompatible
// pointer types, because we generate code passing a struct ptr rather
// than using the typedef. This warning is expected and does not break
// a normal build.
// We can only disable -Wincompatible-pointer-types starting with GCC 5.
// #if __GNU_MAJOR__ >= 5
//
// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
//
// typedef struct {
// int a;
// } issue27340Struct, *issue27340Ptr;
//
// static void issue27340CFunc(issue27340Ptr p) {}
//
// #else /* _GNU_MAJOR_ < 5 */
//
// typedef struct {
// int a;
// } issue27340Struct;
//
// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; }
//
// static void issue27340CFunc(issue27340Struct *p) {}
// #endif /* _GNU_MAJOR_ < 5 */
import "C"
func Issue27340GoFunc() {
var s C.issue27340Struct
C.issue27340CFunc(C.issue27340Ptr(&s))
}

View file

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Failed to add type conversion for negative constant. // Failed to add type conversion for negative constant.
// Issue 28772: Failed to add type conversion for Go constant set to C constant.
// No runtime test; just make sure it compiles. // No runtime test; just make sure it compiles.
package cgotest package cgotest
@ -10,11 +11,16 @@ package cgotest
/* /*
#include <complex.h> #include <complex.h>
#define issue28772Constant 1
static void issue28545F(char **p, int n, complex double a) {} static void issue28545F(char **p, int n, complex double a) {}
*/ */
import "C" import "C"
const issue28772Constant = C.issue28772Constant
func issue28545G(p **C.char) { func issue28545G(p **C.char) {
C.issue28545F(p, -1, (0)) C.issue28545F(p, -1, (0))
C.issue28545F(p, 2+3, complex(1, 1)) C.issue28545F(p, 2+3, complex(1, 1))
C.issue28545F(p, issue28772Constant, issue28772Constant2)
} }

View file

@ -0,0 +1,12 @@
// 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 cgotest
// Constants didn't work if defined in different source file.
// #define issue28772Constant2 2
import "C"
const issue28772Constant2 = C.issue28772Constant2

View file

@ -0,0 +1,83 @@
// 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.
// cgo was incorrectly adding padding after a packed struct.
package cgotest
/*
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct {
void *f1;
uint32_t f2;
} __attribute__((__packed__)) innerPacked;
typedef struct {
innerPacked g1;
uint64_t g2;
} outerPacked;
typedef struct {
void *f1;
uint32_t f2;
} innerUnpacked;
typedef struct {
innerUnpacked g1;
uint64_t g2;
} outerUnpacked;
size_t offset(int x) {
switch (x) {
case 0:
return offsetof(innerPacked, f2);
case 1:
return offsetof(outerPacked, g2);
case 2:
return offsetof(innerUnpacked, f2);
case 3:
return offsetof(outerUnpacked, g2);
default:
abort();
}
}
*/
import "C"
import (
"testing"
"unsafe"
)
func offset(i int) uintptr {
var pi C.innerPacked
var po C.outerPacked
var ui C.innerUnpacked
var uo C.outerUnpacked
switch i {
case 0:
return unsafe.Offsetof(pi.f2)
case 1:
return unsafe.Offsetof(po.g2)
case 2:
return unsafe.Offsetof(ui.f2)
case 3:
return unsafe.Offsetof(uo.g2)
default:
panic("can't happen")
}
}
func test28896(t *testing.T) {
for i := 0; i < 4; i++ {
c := uintptr(C.offset(C.int(i)))
g := offset(i)
if c != g {
t.Errorf("%d: C: %d != Go %d", i, c, g)
}
}
}

View file

@ -0,0 +1,19 @@
// 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.
// cgo's /*line*/ comments failed when inserted after '/',
// because the result looked like a "//" comment.
// No runtime test; just make sure it compiles.
package cgotest
// #include <stddef.h>
import "C"
func Issue29383(n, size uint) int {
if ^C.size_t(0)/C.size_t(n) < C.size_t(size) {
return 0
}
return 0
}

View file

@ -0,0 +1,22 @@
// Copyright 2019 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.
// Error handling a struct initializer that requires pointer checking.
// Compilation test only, nothing to run.
package cgotest
// typedef struct { char **p; } S29748;
// static int f29748(S29748 *p) { return 0; }
import "C"
var Vissue29748 = C.f29748(&C.S29748{
nil,
})
func Fissue299748() {
C.f29748(&C.S29748{
nil,
})
}

View file

@ -0,0 +1,17 @@
// Copyright 2019 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.
// Error with newline inserted into constant expression.
// Compilation test only, nothing to run.
package cgotest
// static void issue29781F(char **p, int n) {}
// #define ISSUE29781C 0
import "C"
func issue29781G() {
var p *C.char
C.issue29781F(&p, C.ISSUE29781C+1)
}

View file

@ -0,0 +1,38 @@
// Copyright 2019 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.
// Don't make a private copy of an array when taking the address of an
// element.
package cgotest
// #include <string.h>
import "C"
import (
"testing"
"unsafe"
)
func test30065(t *testing.T) {
var a [256]byte
b := []byte("a")
C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1)
if a[0] != 'a' {
t.Errorf("&a failed: got %c, want %c", a[0], 'a')
}
b = []byte("b")
C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1)
if a[0] != 'b' {
t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b')
}
d := make([]byte, 256)
b = []byte("c")
C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1)
if d[0] != 'c' {
t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c')
}
}

View file

@ -5,7 +5,8 @@
package cgotest package cgotest
/* /*
#include "issue4339.h" // We've historically permitted #include <>, so test it here. Issue 29333.
#include <issue4339.h>
*/ */
import "C" import "C"

View file

@ -29,7 +29,7 @@ func Test(t *testing.T) {
// Brittle: the assertion may fail spuriously when the algorithm // Brittle: the assertion may fail spuriously when the algorithm
// changes, but should remain stable otherwise. // changes, but should remain stable otherwise.
got := fmt.Sprintf("%T %T", in, opts) got := fmt.Sprintf("%T %T", in, opts)
want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1" want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0"
if got != want { if got != want {
t.Errorf("Non-deterministic type names: got %s, want %s", got, want) t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
} }

View file

@ -602,3 +602,55 @@ func copyFile(t *testing.T, dst, src string) {
t.Fatal(err) t.Fatal(err)
} }
} }
func TestGo2C2Go(t *testing.T) {
switch GOOS {
case "darwin":
// Darwin shared libraries don't support the multiple
// copies of the runtime package implied by this test.
t.Skip("linking c-shared into Go programs not supported on Darwin; issue 29061")
case "android":
t.Skip("test fails on android; issue 29087")
}
t.Parallel()
tmpdir, err := ioutil.TempDir("", "cshared-TestGo2C2Go")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
shlib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix)
run(t, gopathEnv, "go", "build", "-buildmode=c-shared", "-o", shlib, "go2c2go/go")
cgoCflags := os.Getenv("CGO_CFLAGS")
if cgoCflags != "" {
cgoCflags += " "
}
cgoCflags += "-I" + tmpdir
cgoLdflags := os.Getenv("CGO_LDFLAGS")
if cgoLdflags != "" {
cgoLdflags += " "
}
cgoLdflags += "-L" + tmpdir + " -ltestgo2c2go"
goenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "CGO_CFLAGS="+cgoCflags, "CGO_LDFLAGS="+cgoLdflags)
ldLibPath := os.Getenv("LD_LIBRARY_PATH")
if ldLibPath != "" {
ldLibPath += ":"
}
ldLibPath += tmpdir
runenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "LD_LIBRARY_PATH="+ldLibPath)
bin := filepath.Join(tmpdir, "m1") + exeSuffix
run(t, goenv, "go", "build", "-o", bin, "go2c2go/m1")
runExe(t, runenv, bin)
bin = filepath.Join(tmpdir, "m2") + exeSuffix
run(t, goenv, "go", "build", "-o", bin, "go2c2go/m2")
runExe(t, runenv, bin)
}

View file

@ -0,0 +1,12 @@
// 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 main
import "C"
//export GoFunc
func GoFunc() int { return 1 }
func main() {}

View file

@ -0,0 +1,9 @@
// 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.
#include "libtestgo2c2go.h"
int CFunc(void) {
return (GoFunc() << 8) + 2;
}

View file

@ -0,0 +1,22 @@
// 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 main
// extern int CFunc(void);
import "C"
import (
"fmt"
"os"
)
func main() {
got := C.CFunc()
const want = (1 << 8) | 2
if got != want {
fmt.Printf("got %#x, want %#x\n", got, want)
os.Exit(1)
}
}

View file

@ -0,0 +1,22 @@
// 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 main
// #include "libtestgo2c2go.h"
import "C"
import (
"fmt"
"os"
)
func main() {
got := C.GoFunc()
const want = 1
if got != want {
fmt.Printf("got %#x, want %#x\n", got, want)
os.Exit(1)
}
}

View file

@ -5,9 +5,9 @@
package sanitizers_test package sanitizers_test
import ( import (
"runtime"
"strings" "strings"
"testing" "testing"
"runtime"
) )
func TestTSAN(t *testing.T) { func TestTSAN(t *testing.T) {

View file

@ -911,3 +911,9 @@ func TestGlobal(t *testing.T) {
func TestTestInstalledShared(t *testing.T) { func TestTestInstalledShared(t *testing.T) {
goCmd(nil, "test", "-linkshared", "-test.short", "sync/atomic") goCmd(nil, "test", "-linkshared", "-test.short", "sync/atomic")
} }
// Test generated pointer method with -linkshared.
// Issue 25065.
func TestGeneratedMethod(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "issue25065")
}

View file

@ -0,0 +1,20 @@
// 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 issue25065 has a type with a method that is
// 1) referenced in a method expression
// 2) not called
// 3) not converted to an interface
// 4) is a value method but the reference is to the pointer method
// These cases avoid the call to makefuncsym from typecheckfunc, but we
// still need to call makefuncsym somehow or the symbol will not be defined.
package issue25065
type T int
func (t T) M() {}
func F() func(*T) {
return (*T).M
}

View file

@ -37,9 +37,6 @@ go src=..
buildid buildid
testdata testdata
+ +
xcoff
testdata
+
gofmt gofmt
gofmt.go gofmt.go
gofmt_test.go gofmt_test.go
@ -157,7 +154,7 @@ go src=..
trace trace
testdata testdata
+ +
traceparser xcoff
testdata testdata
+ +
io io

View file

@ -1,79 +0,0 @@
// Copyright 2015 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.
// Sortac sorts the AUTHORS and CONTRIBUTORS files.
//
// Usage:
//
// sortac [file...]
//
// Sortac sorts the named files in place.
// If given no arguments, it sorts standard input to standard output.
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)
func main() {
log.SetFlags(0)
log.SetPrefix("sortac: ")
flag.Parse()
args := flag.Args()
if len(args) == 0 {
os.Stdout.Write(sortAC(os.Stdin))
} else {
for _, arg := range args {
f, err := os.Open(arg)
if err != nil {
log.Fatal(err)
}
sorted := sortAC(f)
f.Close()
if err := ioutil.WriteFile(arg, sorted, 0644); err != nil {
log.Fatal(err)
}
}
}
}
func sortAC(r io.Reader) []byte {
bs := bufio.NewScanner(r)
var header []string
var lines []string
for bs.Scan() {
t := bs.Text()
lines = append(lines, t)
if t == "# Please keep the list sorted." {
header = lines
lines = nil
continue
}
}
if err := bs.Err(); err != nil {
log.Fatal(err)
}
var out bytes.Buffer
c := collate.New(language.Und, collate.Loose)
c.SortStrings(lines)
for _, l := range header {
fmt.Fprintln(&out, l)
}
for _, l := range lines {
fmt.Fprintln(&out, l)
}
return out.Bytes()
}

View file

@ -61,6 +61,11 @@
err.code = "ENOSYS"; err.code = "ENOSYS";
callback(err); callback(err);
}, },
read(fd, buffer, offset, length, position, callback) {
const err = new Error("not implemented");
err.code = "ENOSYS";
callback(err);
},
fsync(fd, callback) { fsync(fd, callback) {
callback(null); callback(null);
}, },
@ -82,8 +87,8 @@
this._exitPromise = new Promise((resolve) => { this._exitPromise = new Promise((resolve) => {
this._resolveExitPromise = resolve; this._resolveExitPromise = resolve;
}); });
this._pendingCallback = null; this._pendingEvent = null;
this._callbackTimeouts = new Map(); this._scheduledTimeouts = new Map();
this._nextCallbackTimeoutID = 1; this._nextCallbackTimeoutID = 1;
const mem = () => { const mem = () => {
@ -199,7 +204,7 @@
this.importObject = { this.importObject = {
go: { go: {
// Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
// may trigger a synchronous callback to Go. This makes Go code get executed in the middle of the imported // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
// function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
// This changes the SP, thus we have to update the SP used by the imported function. // This changes the SP, thus we have to update the SP used by the imported function.
@ -233,22 +238,22 @@
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true); mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
}, },
// func scheduleCallback(delay int64) int32 // func scheduleTimeoutEvent(delay int64) int32
"runtime.scheduleCallback": (sp) => { "runtime.scheduleTimeoutEvent": (sp) => {
const id = this._nextCallbackTimeoutID; const id = this._nextCallbackTimeoutID;
this._nextCallbackTimeoutID++; this._nextCallbackTimeoutID++;
this._callbackTimeouts.set(id, setTimeout( this._scheduledTimeouts.set(id, setTimeout(
() => { this._resume(); }, () => { this._resume(); },
getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
)); ));
mem().setInt32(sp + 16, id, true); mem().setInt32(sp + 16, id, true);
}, },
// func clearScheduledCallback(id int32) // func clearTimeoutEvent(id int32)
"runtime.clearScheduledCallback": (sp) => { "runtime.clearTimeoutEvent": (sp) => {
const id = mem().getInt32(sp + 8, true); const id = mem().getInt32(sp + 8, true);
clearTimeout(this._callbackTimeouts.get(id)); clearTimeout(this._scheduledTimeouts.get(id));
this._callbackTimeouts.delete(id); this._scheduledTimeouts.delete(id);
}, },
// func getRandomData(r []byte) // func getRandomData(r []byte)
@ -415,7 +420,7 @@
_resume() { _resume() {
if (this.exited) { if (this.exited) {
throw new Error("bad callback: Go program has already exited"); throw new Error("Go program has already exited");
} }
this._inst.exports.resume(); this._inst.exports.resume();
if (this.exited) { if (this.exited) {
@ -423,13 +428,13 @@
} }
} }
_makeCallbackHelper(id) { _makeFuncWrapper(id) {
const go = this; const go = this;
return function () { return function () {
const cb = { id: id, this: this, args: arguments }; const event = { id: id, this: this, args: arguments };
go._pendingCallback = cb; go._pendingEvent = event;
go._resume(); go._resume();
return cb.result; return event.result;
}; };
} }
} }
@ -442,13 +447,13 @@
const go = new Go(); const go = new Go();
go.argv = process.argv.slice(2); go.argv = process.argv.slice(2);
go.env = process.env; go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env);
go.exit = process.exit; go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => { WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", (code) => { // Node.js exits if no callback is pending process.on("exit", (code) => { // Node.js exits if no event handler is pending
if (code === 0 && !go.exited) { if (code === 0 && !go.exited) {
// deadlock, make Go print error and stack traces // deadlock, make Go print error and stack traces
go._pendingCallback = { id: 0 }; go._pendingEvent = { id: 0 };
go._resume(); go._resume();
} }
}); });

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux dragonfly freebsd openbsd solaris // +build linux dragonfly openbsd solaris
package tar package tar

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin netbsd // +build darwin freebsd netbsd
package tar package tar

View file

@ -159,7 +159,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
return len(p), nil return len(p), nil
} }
func min(x, y int) int { func min(x, y int64) int64 {
if x < y { if x < y {
return x return x
} }
@ -190,7 +190,7 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
if len(parts) > 0 { if len(parts) > 0 {
skipBytes := off - parts[0].off skipBytes := off - parts[0].off
for _, part := range parts { for _, part := range parts {
repeat := min(int(part.n-skipBytes), len(p)-n) repeat := int(min(part.n-skipBytes, int64(len(p)-n)))
memset(p[n:n+repeat], part.b) memset(p[n:n+repeat], part.b)
n += repeat n += repeat
if n == len(p) { if n == len(p) {

View file

@ -33,8 +33,8 @@ type Reader struct {
rd io.Reader // reader provided by the client rd io.Reader // reader provided by the client
r, w int // buf read and write positions r, w int // buf read and write positions
err error err error
lastByte int lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
} }
const minReadBufferSize = 16 const minReadBufferSize = 16
@ -123,11 +123,17 @@ func (b *Reader) readErr() error {
// being valid at the next read call. If Peek returns fewer than n bytes, it // being valid at the next read call. If Peek returns fewer than n bytes, it
// also returns an error explaining why the read is short. The error is // also returns an error explaining why the read is short. The error is
// ErrBufferFull if n is larger than b's buffer size. // ErrBufferFull if n is larger than b's buffer size.
//
// Calling Peek prevents a UnreadByte or UnreadRune call from succeeding
// until the next read operation.
func (b *Reader) Peek(n int) ([]byte, error) { func (b *Reader) Peek(n int) ([]byte, error) {
if n < 0 { if n < 0 {
return nil, ErrNegativeCount return nil, ErrNegativeCount
} }
b.lastByte = -1
b.lastRuneSize = -1
for b.w-b.r < n && b.w-b.r < len(b.buf) && b.err == nil { for b.w-b.r < n && b.w-b.r < len(b.buf) && b.err == nil {
b.fill() // b.w-b.r < len(b.buf) => buffer is not full b.fill() // b.w-b.r < len(b.buf) => buffer is not full
} }
@ -186,9 +192,8 @@ func (b *Reader) Discard(n int) (discarded int, err error) {
// It returns the number of bytes read into p. // It returns the number of bytes read into p.
// The bytes are taken from at most one Read on the underlying Reader, // The bytes are taken from at most one Read on the underlying Reader,
// hence n may be less than len(p). // hence n may be less than len(p).
// At EOF, the count will be zero and err will be io.EOF.
//
// To read exactly len(p) bytes, use io.ReadFull(b, p). // To read exactly len(p) bytes, use io.ReadFull(b, p).
// At EOF, the count will be zero and err will be io.EOF.
func (b *Reader) Read(p []byte) (n int, err error) { func (b *Reader) Read(p []byte) (n int, err error) {
n = len(p) n = len(p)
if n == 0 { if n == 0 {
@ -250,6 +255,10 @@ func (b *Reader) ReadByte() (byte, error) {
} }
// UnreadByte unreads the last byte. Only the most recently read byte can be unread. // UnreadByte unreads the last byte. Only the most recently read byte can be unread.
//
// UnreadByte returns an error if the most recent method called on the
// Reader was not a read operation. Notably, Peek is not considered a
// read operation.
func (b *Reader) UnreadByte() error { func (b *Reader) UnreadByte() error {
if b.lastByte < 0 || b.r == 0 && b.w > 0 { if b.lastByte < 0 || b.r == 0 && b.w > 0 {
return ErrInvalidUnreadByte return ErrInvalidUnreadByte
@ -288,8 +297,8 @@ func (b *Reader) ReadRune() (r rune, size int, err error) {
return r, size, nil return r, size, nil
} }
// UnreadRune unreads the last rune. If the most recent read operation on // UnreadRune unreads the last rune. If the most recent method called on
// the buffer was not a ReadRune, UnreadRune returns an error. (In this // the Reader was not a ReadRune, UnreadRune returns an error. (In this
// regard it is stricter than UnreadByte, which will unread the last byte // regard it is stricter than UnreadByte, which will unread the last byte
// from any read operation.) // from any read operation.)
func (b *Reader) UnreadRune() error { func (b *Reader) UnreadRune() error {

View file

@ -285,6 +285,24 @@ func TestUnreadRune(t *testing.T) {
} }
} }
func TestNoUnreadRuneAfterPeek(t *testing.T) {
br := NewReader(strings.NewReader("example"))
br.ReadRune()
br.Peek(1)
if err := br.UnreadRune(); err == nil {
t.Error("UnreadRune didn't fail after Peek")
}
}
func TestNoUnreadByteAfterPeek(t *testing.T) {
br := NewReader(strings.NewReader("example"))
br.ReadByte()
br.Peek(1)
if err := br.UnreadByte(); err == nil {
t.Error("UnreadByte didn't fail after Peek")
}
}
func TestUnreadByte(t *testing.T) { func TestUnreadByte(t *testing.T) {
segments := []string{"Hello, ", "world"} segments := []string{"Hello, ", "world"}
r := NewReader(&StringReader{data: segments}) r := NewReader(&StringReader{data: segments})

View file

@ -68,7 +68,7 @@ func (b *Buffer) String() string {
return string(b.buf[b.off:]) return string(b.buf[b.off:])
} }
// empty returns whether the unread portion of the buffer is empty. // empty reports whether the unread portion of the buffer is empty.
func (b *Buffer) empty() bool { return len(b.buf) <= b.off } func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
// Len returns the number of bytes of the unread portion of the buffer; // Len returns the number of bytes of the unread portion of the buffer;

View file

@ -298,6 +298,12 @@ func ExampleReplace() {
// moo moo moo // moo moo moo
} }
func ExampleReplaceAll() {
fmt.Printf("%s\n", bytes.ReplaceAll([]byte("oink oink oink"), []byte("oink"), []byte("moo")))
// Output:
// moo moo moo
}
func ExampleRunes() { func ExampleRunes() {
rs := bytes.Runes([]byte("go gopher")) rs := bytes.Runes([]byte("go gopher"))
for _, r := range rs { for _, r := range rs {

View file

@ -442,13 +442,8 @@ func (w *Walker) Import(name string) (*types.Package, error) {
} }
w.imported[name] = &importing w.imported[name] = &importing
root := w.root
if strings.HasPrefix(name, "golang_org/x/") {
root = filepath.Join(root, "vendor")
}
// Determine package files. // Determine package files.
dir := filepath.Join(root, filepath.FromSlash(name)) dir := filepath.Join(w.root, filepath.FromSlash(name))
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() { if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
log.Fatalf("no source in tree for import %q: %v", name, err) log.Fatalf("no source in tree for import %q: %v", name, err)
} }

View file

@ -39,6 +39,8 @@ Flags:
Generate code that can be linked into a shared library. Generate code that can be linked into a shared library.
-trimpath prefix -trimpath prefix
Remove prefix from recorded source file paths. Remove prefix from recorded source file paths.
-gensymabis
Write symbol ABI information to output file. Don't assemble.
Input language: Input language:
The assembler uses mostly the same syntax for all architectures, The assembler uses mostly the same syntax for all architectures,

View file

@ -38,8 +38,7 @@ func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) {
parser := NewParser(ctxt, arch, tokenizer) parser := NewParser(ctxt, arch, tokenizer)
err := tryParse(t, func() { err := tryParse(t, func() {
parser.start(lex.Tokenize(test.input)) parser.Parse()
parser.line()
}) })
switch { switch {

View file

@ -122,6 +122,49 @@ func TestS390XOperandParser(t *testing.T) {
testOperandParser(t, parser, s390xOperandTests) testOperandParser(t, parser, s390xOperandTests)
} }
func TestFuncAddress(t *testing.T) {
type subtest struct {
arch string
tests []operandTest
}
for _, sub := range []subtest{
{"amd64", amd64OperandTests},
{"386", x86OperandTests},
{"arm", armOperandTests},
{"arm64", arm64OperandTests},
{"ppc64", ppc64OperandTests},
{"mips", mipsOperandTests},
{"mips64", mips64OperandTests},
{"s390x", s390xOperandTests},
} {
t.Run(sub.arch, func(t *testing.T) {
parser := newParser(sub.arch)
for _, test := range sub.tests {
parser.start(lex.Tokenize(test.input))
name, ok := parser.funcAddress()
isFuncSym := strings.HasSuffix(test.input, "(SB)") &&
// Ignore static symbols.
!strings.Contains(test.input, "<>") &&
// Ignore symbols with offsets.
!strings.Contains(test.input, "+")
wantName := ""
if isFuncSym {
// Strip $|* and (SB).
wantName = test.output[:len(test.output)-4]
if strings.HasPrefix(wantName, "$") || strings.HasPrefix(wantName, "*") {
wantName = wantName[1:]
}
}
if ok != isFuncSym || name != wantName {
t.Errorf("fail at %s as function address: got %s, %v; expected %s, %v", test.input, name, ok, wantName, isFuncSym)
}
}
})
}
}
type operandTest struct { type operandTest struct {
input, output string input, output string
} }

View file

@ -91,7 +91,23 @@ func (p *Parser) pos() src.XPos {
} }
func (p *Parser) Parse() (*obj.Prog, bool) { func (p *Parser) Parse() (*obj.Prog, bool) {
for p.line() { scratch := make([][]lex.Token, 0, 3)
for {
word, cond, operands, ok := p.line(scratch)
if !ok {
break
}
scratch = operands
if p.pseudo(word, operands) {
continue
}
i, present := p.arch.Instructions[word]
if present {
p.instruction(i, word, cond, operands)
continue
}
p.errorf("unrecognized instruction %q", word)
} }
if p.errorCount > 0 { if p.errorCount > 0 {
return nil, false return nil, false
@ -100,8 +116,33 @@ func (p *Parser) Parse() (*obj.Prog, bool) {
return p.firstProg, true return p.firstProg, true
} }
// WORD [ arg {, arg} ] (';' | '\n') // ParseSymABIs parses p's assembly code to find text symbol
func (p *Parser) line() bool { // definitions and references and writes a symabis file to w.
func (p *Parser) ParseSymABIs(w io.Writer) bool {
operands := make([][]lex.Token, 0, 3)
for {
word, _, operands1, ok := p.line(operands)
if !ok {
break
}
operands = operands1
p.symDefRef(w, word, operands)
}
return p.errorCount == 0
}
// line consumes a single assembly line from p.lex of the form
//
// {label:} WORD[.cond] [ arg {, arg} ] (';' | '\n')
//
// It adds any labels to p.pendingLabels and returns the word, cond,
// operand list, and true. If there is an error or EOF, it returns
// ok=false.
//
// line may reuse the memory from scratch.
func (p *Parser) line(scratch [][]lex.Token) (word, cond string, operands [][]lex.Token, ok bool) {
next:
// Skip newlines. // Skip newlines.
var tok lex.ScanToken var tok lex.ScanToken
for { for {
@ -114,24 +155,29 @@ func (p *Parser) line() bool {
case '\n', ';': case '\n', ';':
continue continue
case scanner.EOF: case scanner.EOF:
return false return "", "", nil, false
} }
break break
} }
// First item must be an identifier. // First item must be an identifier.
if tok != scanner.Ident { if tok != scanner.Ident {
p.errorf("expected identifier, found %q", p.lex.Text()) p.errorf("expected identifier, found %q", p.lex.Text())
return false // Might as well stop now. return "", "", nil, false // Might as well stop now.
} }
word := p.lex.Text() word, cond = p.lex.Text(), ""
var cond string operands = scratch[:0]
operands := make([][]lex.Token, 0, 3)
// Zero or more comma-separated operands, one per loop. // Zero or more comma-separated operands, one per loop.
nesting := 0 nesting := 0
colon := -1 colon := -1
for tok != '\n' && tok != ';' { for tok != '\n' && tok != ';' {
// Process one operand. // Process one operand.
items := make([]lex.Token, 0, 3) var items []lex.Token
if cap(operands) > len(operands) {
// Reuse scratch items slice.
items = operands[:cap(operands)][len(operands)][:0]
} else {
items = make([]lex.Token, 0, 3)
}
for { for {
tok = p.lex.Next() tok = p.lex.Next()
if len(operands) == 0 && len(items) == 0 { if len(operands) == 0 && len(items) == 0 {
@ -148,12 +194,12 @@ func (p *Parser) line() bool {
if tok == ':' { if tok == ':' {
// Labels. // Labels.
p.pendingLabels = append(p.pendingLabels, word) p.pendingLabels = append(p.pendingLabels, word)
return true goto next
} }
} }
if tok == scanner.EOF { if tok == scanner.EOF {
p.errorf("unexpected EOF") p.errorf("unexpected EOF")
return false return "", "", nil, false
} }
// Split operands on comma. Also, the old syntax on x86 for a "register pair" // Split operands on comma. Also, the old syntax on x86 for a "register pair"
// was AX:DX, for which the new syntax is DX, AX. Note the reordering. // was AX:DX, for which the new syntax is DX, AX. Note the reordering.
@ -162,7 +208,7 @@ func (p *Parser) line() bool {
// Remember this location so we can swap the operands below. // Remember this location so we can swap the operands below.
if colon >= 0 { if colon >= 0 {
p.errorf("invalid ':' in operand") p.errorf("invalid ':' in operand")
return true return word, cond, operands, true
} }
colon = len(operands) colon = len(operands)
} }
@ -188,16 +234,7 @@ func (p *Parser) line() bool {
p.errorf("missing operand") p.errorf("missing operand")
} }
} }
if p.pseudo(word, operands) { return word, cond, operands, true
return true
}
i, present := p.arch.Instructions[word]
if present {
p.instruction(i, word, cond, operands)
return true
}
p.errorf("unrecognized instruction %q", word)
return true
} }
func (p *Parser) instruction(op obj.As, word, cond string, operands [][]lex.Token) { func (p *Parser) instruction(op obj.As, word, cond string, operands [][]lex.Token) {
@ -237,6 +274,42 @@ func (p *Parser) pseudo(word string, operands [][]lex.Token) bool {
return true return true
} }
// symDefRef scans a line for potential text symbol definitions and
// references and writes symabis information to w.
//
// The symabis format is documented at
// cmd/compile/internal/gc.readSymABIs.
func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) {
switch word {
case "TEXT":
// Defines text symbol in operands[0].
if len(operands) > 0 {
p.start(operands[0])
if name, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "def %s ABI0\n", name)
}
}
return
case "GLOBL", "PCDATA":
// No text definitions or symbol references.
case "DATA", "FUNCDATA":
// For DATA, operands[0] is defined symbol.
// For FUNCDATA, operands[0] is an immediate constant.
// Remaining operands may have references.
if len(operands) < 2 {
return
}
operands = operands[1:]
}
// Search for symbol references.
for _, op := range operands {
p.start(op)
if name, ok := p.funcAddress(); ok {
fmt.Fprintf(w, "ref %s ABI0\n", name)
}
}
}
func (p *Parser) start(operand []lex.Token) { func (p *Parser) start(operand []lex.Token) {
p.input = operand p.input = operand
p.inputPos = 0 p.inputPos = 0
@ -725,6 +798,35 @@ func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, pr
} }
} }
// funcAddress parses an external function address. This is a
// constrained form of the operand syntax that's always SB-based,
// non-static, and has no additional offsets:
//
// [$|*]sym(SB)
func (p *Parser) funcAddress() (string, bool) {
switch p.peek() {
case '$', '*':
// Skip prefix.
p.next()
}
tok := p.next()
name := tok.String()
if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) {
return "", false
}
if p.next().ScanToken != '(' {
return "", false
}
if reg := p.next(); reg.ScanToken != scanner.Ident || reg.String() != "SB" {
return "", false
}
if p.next().ScanToken != ')' || p.peek() != scanner.EOF {
return "", false
}
return name, true
}
// registerIndirect parses the general form of a register indirection. // registerIndirect parses the general form of a register indirection.
// It is can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3) // It is can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3)
// where R1 may be a simple register or register pair R:R or (R, R) or (R+R). // where R1 may be a simple register or register pair R:R or (R, R) or (R+R).

View file

@ -948,6 +948,7 @@ label1:
// <MNEMONIC> VRA,VRB,VRC,VRT produces // <MNEMONIC> VRA,VRB,VRC,VRT produces
// <mnemonic> VRT,VRA,VRB,VRC // <mnemonic> VRT,VRA,VRB,VRC
VPERM V3, V2, V1, V0 VPERM V3, V2, V1, V0
VPERMXOR V3, V2, V1, V0
// Vector bit permute, VX-form // Vector bit permute, VX-form
// <MNEMONIC> VRA,VRB,VRT produces // <MNEMONIC> VRA,VRB,VRT produces

View file

@ -22,6 +22,7 @@ var (
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library") Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries") Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported") AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
) )
var ( var (

View file

@ -36,7 +36,7 @@ func main() {
ctxt := obj.Linknew(architecture.LinkArch) ctxt := obj.Linknew(architecture.LinkArch)
if *flags.PrintOut { if *flags.PrintOut {
ctxt.Debugasm = true ctxt.Debugasm = 1
} }
ctxt.Flag_dynlink = *flags.Dynlink ctxt.Flag_dynlink = *flags.Dynlink
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
@ -53,8 +53,10 @@ func main() {
defer bio.MustClose(out) defer bio.MustClose(out)
buf := bufio.NewWriter(bio.MustWriter(out)) buf := bufio.NewWriter(bio.MustWriter(out))
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version) if !*flags.SymABIs {
fmt.Fprintf(buf, "!\n") fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
fmt.Fprintf(buf, "!\n")
}
var ok, diag bool var ok, diag bool
var failedFile string var failedFile string
@ -65,16 +67,22 @@ func main() {
diag = true diag = true
log.Printf(format, args...) log.Printf(format, args...)
} }
pList := new(obj.Plist) if *flags.SymABIs {
pList.Firstpc, ok = parser.Parse() ok = parser.ParseSymABIs(buf)
} else {
pList := new(obj.Plist)
pList.Firstpc, ok = parser.Parse()
// reports errors to parser.Errorf
if ok {
obj.Flushplist(ctxt, pList, nil, "")
}
}
if !ok { if !ok {
failedFile = f failedFile = f
break break
} }
// reports errors to parser.Errorf
obj.Flushplist(ctxt, pList, nil, "")
} }
if ok { if ok && !*flags.SymABIs {
obj.WriteObjFile(ctxt, buf) obj.WriteObjFile(ctxt, buf)
} }
if !ok || diag { if !ok || diag {

View file

@ -145,6 +145,7 @@ func (f *File) ParseGo(name string, src []byte) {
if f.Ref == nil { if f.Ref == nil {
f.Ref = make([]*Ref, 0, 8) f.Ref = make([]*Ref, 0, 8)
} }
f.walk(ast2, ctxProg, (*File).validateIdents)
f.walk(ast2, ctxProg, (*File).saveExprs) f.walk(ast2, ctxProg, (*File).saveExprs)
// Accumulate exported functions. // Accumulate exported functions.
@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
return strings.Join(pieces, "") return strings.Join(pieces, "")
} }
func (f *File) validateIdents(x interface{}, context astContext) {
if x, ok := x.(*ast.Ident); ok {
if f.isMangledName(x.Name) {
error_(x.Pos(), "identifier %q may conflict with identifiers generated by cgo", x.Name)
}
}
}
// Save various references we are going to need later. // Save various references we are going to need later.
func (f *File) saveExprs(x interface{}, context astContext) { func (f *File) saveExprs(x interface{}, context astContext) {
switch x := x.(type) { switch x := x.(type) {
@ -191,6 +200,18 @@ func (f *File) saveExprs(x interface{}, context astContext) {
} }
case *ast.CallExpr: case *ast.CallExpr:
f.saveCall(x, context) f.saveCall(x, context)
case *ast.GenDecl:
if x.Tok == token.CONST {
for _, spec := range x.Specs {
vs := spec.(*ast.ValueSpec)
if vs.Type == nil {
for _, name := range spec.(*ast.ValueSpec).Names {
consts[name.Name] = true
}
}
}
}
} }
} }

View file

@ -413,6 +413,8 @@ type in Go are instead represented by a uintptr. Those include:
jobjectArray jobjectArray
jweak jweak
3. The EGLDisplay type from the EGL API.
These types are uintptr on the Go side because they would otherwise These types are uintptr on the Go side because they would otherwise
confuse the Go garbage collector; they are sometimes not really confuse the Go garbage collector; they are sometimes not really
pointers but data structures encoded in a pointer type. All operations pointers but data structures encoded in a pointer type. All operations
@ -427,6 +429,11 @@ from Go 1.9 and earlier, use the cftype or jni rewrites in the Go fix tool:
It will replace nil with 0 in the appropriate places. It will replace nil with 0 in the appropriate places.
The EGLDisplay case were introduced in Go 1.12. Use the egl rewrite
to auto-update code from Go 1.11 and earlier:
go tool fix -r egl <pkg>
Using cgo directly Using cgo directly
Usage: Usage:

View file

@ -9,7 +9,6 @@ package main
import ( import (
"bytes" "bytes"
"cmd/internal/xcoff"
"debug/dwarf" "debug/dwarf"
"debug/elf" "debug/elf"
"debug/macho" "debug/macho"
@ -21,6 +20,7 @@ import (
"go/ast" "go/ast"
"go/parser" "go/parser"
"go/token" "go/token"
"internal/xcoff"
"math" "math"
"os" "os"
"strconv" "strconv"
@ -91,7 +91,13 @@ func (p *Package) addToFlag(flag string, args []string) {
p.CgoFlags[flag] = append(p.CgoFlags[flag], args...) p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
if flag == "CFLAGS" { if flag == "CFLAGS" {
// We'll also need these when preprocessing for dwarf information. // We'll also need these when preprocessing for dwarf information.
p.GccOptions = append(p.GccOptions, args...) // However, discard any -g options: we need to be able
// to parse the debug info, so stick to what we expect.
for _, arg := range args {
if !strings.HasPrefix(arg, "-g") {
p.GccOptions = append(p.GccOptions, arg)
}
}
} }
} }
@ -164,6 +170,10 @@ func (p *Package) Translate(f *File) {
// Convert C.ulong to C.unsigned long, etc. // Convert C.ulong to C.unsigned long, etc.
cref.Name.C = cname(cref.Name.Go) cref.Name.C = cname(cref.Name.Go)
} }
var conv typeConv
conv.Init(p.PtrSize, p.IntSize)
p.loadDefines(f) p.loadDefines(f)
p.typedefs = map[string]bool{} p.typedefs = map[string]bool{}
p.typedefList = nil p.typedefList = nil
@ -171,15 +181,17 @@ func (p *Package) Translate(f *File) {
for len(p.typedefs) > numTypedefs { for len(p.typedefs) > numTypedefs {
numTypedefs = len(p.typedefs) numTypedefs = len(p.typedefs)
// Also ask about any typedefs we've seen so far. // Also ask about any typedefs we've seen so far.
for _, a := range p.typedefList { for _, info := range p.typedefList {
f.Name[a] = &Name{ n := &Name{
Go: a, Go: info.typedef,
C: a, C: info.typedef,
} }
f.Name[info.typedef] = n
f.NamePos[n] = info.pos
} }
needType := p.guessKinds(f) needType := p.guessKinds(f)
if len(needType) > 0 { if len(needType) > 0 {
p.loadDWARF(f, needType) p.loadDWARF(f, &conv, needType)
} }
// In godefs mode we're OK with the typedefs, which // In godefs mode we're OK with the typedefs, which
@ -474,7 +486,7 @@ func (p *Package) guessKinds(f *File) []*Name {
// loadDWARF parses the DWARF debug information generated // loadDWARF parses the DWARF debug information generated
// by gcc to learn the details of the constants, variables, and types // by gcc to learn the details of the constants, variables, and types
// being referred to as C.xxx. // being referred to as C.xxx.
func (p *Package) loadDWARF(f *File, names []*Name) { func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
// Extract the types from the DWARF section of an object // Extract the types from the DWARF section of an object
// from a well-formed C program. Gcc only generates DWARF info // from a well-formed C program. Gcc only generates DWARF info
// for symbols in the object file, so it is not enough to print the // for symbols in the object file, so it is not enough to print the
@ -573,7 +585,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
fatalf("malformed __cgo__ name: %s", name) fatalf("malformed __cgo__ name: %s", name)
} }
types[i] = t.Type types[i] = t.Type
p.recordTypedefs(t.Type) p.recordTypedefs(t.Type, f.NamePos[names[i]])
} }
if e.Tag != dwarf.TagCompileUnit { if e.Tag != dwarf.TagCompileUnit {
r.SkipChildren() r.SkipChildren()
@ -581,8 +593,6 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
} }
// Record types and typedef information. // Record types and typedef information.
var conv typeConv
conv.Init(p.PtrSize, p.IntSize)
for i, n := range names { for i, n := range names {
if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" { if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
@ -641,10 +651,11 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
} }
// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children. // recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
func (p *Package) recordTypedefs(dtype dwarf.Type) { func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
p.recordTypedefs1(dtype, map[dwarf.Type]bool{}) p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
} }
func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool) {
func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
if dtype == nil { if dtype == nil {
return return
} }
@ -660,23 +671,23 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool)
} }
if !p.typedefs[dt.Name] { if !p.typedefs[dt.Name] {
p.typedefs[dt.Name] = true p.typedefs[dt.Name] = true
p.typedefList = append(p.typedefList, dt.Name) p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
p.recordTypedefs1(dt.Type, visited) p.recordTypedefs1(dt.Type, pos, visited)
} }
case *dwarf.PtrType: case *dwarf.PtrType:
p.recordTypedefs1(dt.Type, visited) p.recordTypedefs1(dt.Type, pos, visited)
case *dwarf.ArrayType: case *dwarf.ArrayType:
p.recordTypedefs1(dt.Type, visited) p.recordTypedefs1(dt.Type, pos, visited)
case *dwarf.QualType: case *dwarf.QualType:
p.recordTypedefs1(dt.Type, visited) p.recordTypedefs1(dt.Type, pos, visited)
case *dwarf.FuncType: case *dwarf.FuncType:
p.recordTypedefs1(dt.ReturnType, visited) p.recordTypedefs1(dt.ReturnType, pos, visited)
for _, a := range dt.ParamType { for _, a := range dt.ParamType {
p.recordTypedefs1(a, visited) p.recordTypedefs1(a, pos, visited)
} }
case *dwarf.StructType: case *dwarf.StructType:
for _, f := range dt.Field { for _, f := range dt.Field {
p.recordTypedefs1(f.Type, visited) p.recordTypedefs1(f.Type, pos, visited)
} }
} }
} }
@ -716,9 +727,22 @@ func (p *Package) mangleName(n *Name) {
n.Mangle = prefix + n.Kind + "_" + n.Go n.Mangle = prefix + n.Kind + "_" + n.Go
} }
func (f *File) isMangledName(s string) bool {
prefix := "_C"
if strings.HasPrefix(s, prefix) {
t := s[len(prefix):]
for _, k := range nameKinds {
if strings.HasPrefix(t, k+"_") {
return true
}
}
}
return false
}
// rewriteCalls rewrites all calls that pass pointers to check that // rewriteCalls rewrites all calls that pass pointers to check that
// they follow the rules for passing pointers between Go and C. // they follow the rules for passing pointers between Go and C.
// This returns whether the package needs to import unsafe as _cgo_unsafe. // This reports whether the package needs to import unsafe as _cgo_unsafe.
func (p *Package) rewriteCalls(f *File) bool { func (p *Package) rewriteCalls(f *File) bool {
needsUnsafe := false needsUnsafe := false
// Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first. // Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first.
@ -867,6 +891,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
// Write _cgoCheckPointer calls to sbCheck. // Write _cgoCheckPointer calls to sbCheck.
var sbCheck bytes.Buffer var sbCheck bytes.Buffer
for i, param := range params { for i, param := range params {
origArg := args[i]
arg, nu := p.mangle(f, &args[i]) arg, nu := p.mangle(f, &args[i])
if nu { if nu {
needsUnsafe = true needsUnsafe = true
@ -886,7 +911,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
} }
if !p.needsPointerCheck(f, param.Go, args[i]) { if !p.needsPointerCheck(f, param.Go, args[i]) {
fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtLine(arg)) fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
continue continue
} }
@ -900,7 +925,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
continue continue
} }
fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtLine(arg)) fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d); ", i) fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d); ", i)
} }
@ -941,7 +966,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
return sb.String(), needsUnsafe return sb.String(), needsUnsafe
} }
// needsPointerCheck returns whether the type t needs a pointer check. // needsPointerCheck reports whether the type t needs a pointer check.
// This is true if t is a pointer and if the value to which it points // This is true if t is a pointer and if the value to which it points
// might contain a pointer. // might contain a pointer.
func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool { func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
@ -958,7 +983,7 @@ func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
// hasPointer is used by needsPointerCheck. If top is true it returns // hasPointer is used by needsPointerCheck. If top is true it returns
// whether t is or contains a pointer that might point to a pointer. // whether t is or contains a pointer that might point to a pointer.
// If top is false it returns whether t is or contains a pointer. // If top is false it reports whether t is or contains a pointer.
// f may be nil. // f may be nil.
func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool { func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
switch t := t.(type) { switch t := t.(type) {
@ -1095,15 +1120,20 @@ func (p *Package) mangle(f *File, arg *ast.Expr) (ast.Expr, bool) {
return *arg, needsUnsafe return *arg, needsUnsafe
} }
// checkIndex checks whether arg the form &a[i], possibly inside type // checkIndex checks whether arg has the form &a[i], possibly inside
// conversions. If so, it writes // type conversions. If so, then in the general case it writes
// _cgoIndexNN := a // _cgoIndexNN := a
// _cgoNN := &cgoIndexNN[i] // with type conversions, if any // _cgoNN := &cgoIndexNN[i] // with type conversions, if any
// to sb, and writes // to sb, and writes
// _cgoCheckPointer(_cgoNN, _cgoIndexNN) // _cgoCheckPointer(_cgoNN, _cgoIndexNN)
// to sbCheck, and returns true. This tells _cgoCheckPointer to check // to sbCheck, and returns true. If a is a simple variable or field reference,
// the complete contents of the slice or array being indexed, but no // it writes
// other part of the memory allocation. // _cgoIndexNN := &a
// and dereferences the uses of _cgoIndexNN. Taking the address avoids
// making a copy of an array.
//
// This tells _cgoCheckPointer to check the complete contents of the
// slice or array being indexed, but no other part of the memory allocation.
func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool { func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
// Strip type conversions. // Strip type conversions.
x := arg x := arg
@ -1123,19 +1153,29 @@ func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) boo
return false return false
} }
fmt.Fprintf(sb, "_cgoIndex%d := %s; ", i, gofmtLine(index.X)) addr := ""
deref := ""
if p.isVariable(index.X) {
addr = "&"
deref = "*"
}
fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos()))
origX := index.X origX := index.X
index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i)) index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtLine(arg)) if deref == "*" {
index.X = &ast.StarExpr{X: index.X}
}
fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
index.X = origX index.X = origX
fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, _cgoIndex%d); ", i, i) fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
return true return true
} }
// checkAddr checks whether arg has the form &x, possibly inside type // checkAddr checks whether arg has the form &x, possibly inside type
// conversions. If so it writes // conversions. If so, it writes
// _cgoBaseNN := &x // _cgoBaseNN := &x
// _cgoNN := _cgoBaseNN // with type conversions, if any // _cgoNN := _cgoBaseNN // with type conversions, if any
// to sb, and writes // to sb, and writes
@ -1158,11 +1198,11 @@ func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool
return false return false
} }
fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtLine(*px)) fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
origX := *px origX := *px
*px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i)) *px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtLine(arg)) fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
*px = origX *px = origX
// Use "0 == 0" to do the right thing in the unlikely event // Use "0 == 0" to do the right thing in the unlikely event
@ -1172,7 +1212,7 @@ func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool
return true return true
} }
// isType returns whether the expression is definitely a type. // isType reports whether the expression is definitely a type.
// This is conservative--it returns false for an unknown identifier. // This is conservative--it returns false for an unknown identifier.
func (p *Package) isType(t ast.Expr) bool { func (p *Package) isType(t ast.Expr) bool {
switch t := t.(type) { switch t := t.(type) {
@ -1214,7 +1254,7 @@ func (p *Package) isType(t ast.Expr) bool {
return false return false
} }
// isConst returns whether x is an untyped constant expression. // isConst reports whether x is an untyped constant expression.
func (p *Package) isConst(f *File, x ast.Expr) bool { func (p *Package) isConst(f *File, x ast.Expr) bool {
switch x := x.(type) { switch x := x.(type) {
case *ast.BasicLit: case *ast.BasicLit:
@ -1232,7 +1272,8 @@ func (p *Package) isConst(f *File, x ast.Expr) bool {
return x.Name == "nil" || return x.Name == "nil" ||
strings.HasPrefix(x.Name, "_Ciconst_") || strings.HasPrefix(x.Name, "_Ciconst_") ||
strings.HasPrefix(x.Name, "_Cfconst_") || strings.HasPrefix(x.Name, "_Cfconst_") ||
strings.HasPrefix(x.Name, "_Csconst_") strings.HasPrefix(x.Name, "_Csconst_") ||
consts[x.Name]
case *ast.UnaryExpr: case *ast.UnaryExpr:
return p.isConst(f, x.X) return p.isConst(f, x.X)
case *ast.BinaryExpr: case *ast.BinaryExpr:
@ -1254,6 +1295,17 @@ func (p *Package) isConst(f *File, x ast.Expr) bool {
return false return false
} }
// isVariable reports whether x is a variable, possibly with field references.
func (p *Package) isVariable(x ast.Expr) bool {
switch x := x.(type) {
case *ast.Ident:
return true
case *ast.SelectorExpr:
return p.isVariable(x.X)
}
return false
}
// rewriteUnsafe returns a version of t with references to unsafe.Pointer // rewriteUnsafe returns a version of t with references to unsafe.Pointer
// rewritten to use _cgo_unsafe.Pointer instead. // rewritten to use _cgo_unsafe.Pointer instead.
func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr { func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
@ -1363,7 +1415,20 @@ func (p *Package) rewriteRef(f *File) {
// Record source-level edit for cgo output. // Record source-level edit for cgo output.
if !r.Done { if !r.Done {
repl := gofmt(expr) // Prepend a space in case the earlier code ends
// with '/', which would give us a "//" comment.
repl := " " + gofmtPos(expr, old.Pos())
end := fset.Position(old.End())
// Subtract 1 from the column if we are going to
// append a close parenthesis. That will set the
// correct column for the following characters.
sub := 0
if r.Name.Kind != "type" {
sub = 1
}
if end.Column > sub {
repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub)
}
if r.Name.Kind != "type" { if r.Name.Kind != "type" {
repl = "(" + repl + ")" repl = "(" + repl + ")"
} }
@ -1481,6 +1546,17 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
return expr return expr
} }
// gofmtPos returns the gofmt-formatted string for an AST node,
// with a comment setting the position before the node.
func gofmtPos(n ast.Expr, pos token.Pos) string {
s := gofmtLine(n)
p := fset.Position(pos)
if p.Column == 0 {
return s
}
return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
}
// gccBaseCmd returns the start of the compiler command line. // gccBaseCmd returns the start of the compiler command line.
// It uses $CC if set, or else $GCC, or else the compiler recorded // It uses $CC if set, or else $GCC, or else the compiler recorded
// during the initial build as defaultCC. // during the initial build as defaultCC.
@ -1944,8 +2020,10 @@ func (p *Package) gccErrors(stdin []byte) string {
} }
} }
// Force -O0 optimization // Force -O0 optimization but keep the trailing "-" at the end.
nargs = append(nargs, "-O0") nargs = append(nargs, "-O0")
nl := len(nargs)
nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
if *debugGcc { if *debugGcc {
fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " ")) fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
@ -1988,10 +2066,10 @@ func runGcc(stdin []byte, args []string) (string, string) {
// with equivalent memory layout. // with equivalent memory layout.
type typeConv struct { type typeConv struct {
// Cache of already-translated or in-progress types. // Cache of already-translated or in-progress types.
m map[dwarf.Type]*Type m map[string]*Type
// Map from types to incomplete pointers to those types. // Map from types to incomplete pointers to those types.
ptrs map[dwarf.Type][]*Type ptrs map[string][]*Type
// Keys of ptrs in insertion order (deterministic worklist) // Keys of ptrs in insertion order (deterministic worklist)
// ptrKeys contains exactly the keys in ptrs. // ptrKeys contains exactly the keys in ptrs.
ptrKeys []dwarf.Type ptrKeys []dwarf.Type
@ -2026,8 +2104,8 @@ var unionWithPointer = make(map[ast.Expr]bool)
func (c *typeConv) Init(ptrSize, intSize int64) { func (c *typeConv) Init(ptrSize, intSize int64) {
c.ptrSize = ptrSize c.ptrSize = ptrSize
c.intSize = intSize c.intSize = intSize
c.m = make(map[dwarf.Type]*Type) c.m = make(map[string]*Type)
c.ptrs = make(map[dwarf.Type][]*Type) c.ptrs = make(map[string][]*Type)
c.getTypeIDs = make(map[string]bool) c.getTypeIDs = make(map[string]bool)
c.bool = c.Ident("bool") c.bool = c.Ident("bool")
c.byte = c.Ident("byte") c.byte = c.Ident("byte")
@ -2135,11 +2213,12 @@ func (c *typeConv) FinishType(pos token.Pos) {
// Keep looping until they're all done. // Keep looping until they're all done.
for len(c.ptrKeys) > 0 { for len(c.ptrKeys) > 0 {
dtype := c.ptrKeys[0] dtype := c.ptrKeys[0]
dtypeKey := dtype.String()
c.ptrKeys = c.ptrKeys[1:] c.ptrKeys = c.ptrKeys[1:]
ptrs := c.ptrs[dtype] ptrs := c.ptrs[dtypeKey]
delete(c.ptrs, dtype) delete(c.ptrs, dtypeKey)
// Note Type might invalidate c.ptrs[dtype]. // Note Type might invalidate c.ptrs[dtypeKey].
t := c.Type(dtype, pos) t := c.Type(dtype, pos)
for _, ptr := range ptrs { for _, ptr := range ptrs {
ptr.Go.(*ast.StarExpr).X = t.Go ptr.Go.(*ast.StarExpr).X = t.Go
@ -2151,18 +2230,29 @@ func (c *typeConv) FinishType(pos token.Pos) {
// Type returns a *Type with the same memory layout as // Type returns a *Type with the same memory layout as
// dtype when used as the type of a variable or a struct field. // dtype when used as the type of a variable or a struct field.
func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
if t, ok := c.m[dtype]; ok { // Always recompute bad pointer typedefs, as the set of such
if t.Go == nil { // typedefs changes as we see more types.
fatalf("%s: type conversion loop at %s", lineno(pos), dtype) checkCache := true
if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) {
checkCache = false
}
key := dtype.String()
if checkCache {
if t, ok := c.m[key]; ok {
if t.Go == nil {
fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
}
return t
} }
return t
} }
t := new(Type) t := new(Type)
t.Size = dtype.Size() // note: wrong for array of pointers, corrected below t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
t.Align = -1 t.Align = -1
t.C = &TypeRepr{Repr: dtype.Common().Name} t.C = &TypeRepr{Repr: dtype.Common().Name}
c.m[dtype] = t c.m[key] = t
switch dt := dtype.(type) { switch dt := dtype.(type) {
default: default:
@ -2325,10 +2415,11 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
// Placeholder initialization; completed in FinishType. // Placeholder initialization; completed in FinishType.
t.Go = &ast.StarExpr{} t.Go = &ast.StarExpr{}
t.C.Set("<incomplete>*") t.C.Set("<incomplete>*")
if _, ok := c.ptrs[dt.Type]; !ok { key := dt.Type.String()
if _, ok := c.ptrs[key]; !ok {
c.ptrKeys = append(c.ptrKeys, dt.Type) c.ptrKeys = append(c.ptrKeys, dt.Type)
} }
c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) c.ptrs[key] = append(c.ptrs[key], t)
case *dwarf.QualType: case *dwarf.QualType:
t1 := c.Type(dt.Type, pos) t1 := c.Type(dt.Type, pos)
@ -2716,11 +2807,6 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
anon := 0 anon := 0
for _, f := range dt.Field { for _, f := range dt.Field {
if f.ByteOffset > off {
fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
off = f.ByteOffset
}
name := f.Name name := f.Name
ft := f.Type ft := f.Type
@ -2769,6 +2855,19 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
// structs are in system headers that cannot be corrected. // structs are in system headers that cannot be corrected.
continue continue
} }
// Round off up to talign, assumed to be a power of 2.
off = (off + talign - 1) &^ (talign - 1)
if f.ByteOffset > off {
fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
off = f.ByteOffset
}
if f.ByteOffset < off {
// Drop a packed field that we can't represent.
continue
}
n := len(fld) n := len(fld)
fld = fld[0 : n+1] fld = fld[0 : n+1]
if name == "" { if name == "" {
@ -2818,7 +2917,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
return return
} }
// dwarfHasPointer returns whether the DWARF type dt contains a pointer. // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool { func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
switch dt := dt.(type) { switch dt := dt.(type) {
default: default:
@ -2935,6 +3034,9 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
if c.badJNI(dt) { if c.badJNI(dt) {
return true return true
} }
if c.badEGLDisplay(dt) {
return true
}
return false return false
} }
@ -3071,6 +3173,19 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
return false return false
} }
func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool {
if dt.Name != "EGLDisplay" {
return false
}
// Check that the typedef is "typedef void *EGLDisplay".
if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
if _, ok := ptr.Type.(*dwarf.VoidType); ok {
return true
}
}
return false
}
// jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
// they are mapped. The base "jobject" maps to the empty string. // they are mapped. The base "jobject" maps to the empty string.
var jniTypes = map[string]string{ var jniTypes = map[string]string{

View file

@ -127,8 +127,35 @@ func gofmt(n interface{}) string {
return gofmtBuf.String() return gofmtBuf.String()
} }
// gofmtLineReplacer is used to put a gofmt-formatted string for an
// AST expression onto a single line. The lexer normally inserts a
// semicolon at each newline, so we can replace newline with semicolon.
// However, we can't do that in cases where the lexer would not insert
// a semicolon. We only have to worry about cases that can occur in an
// expression passed through gofmt, which means composite literals and
// (due to the printer possibly inserting newlines because of position
// information) operators.
var gofmtLineReplacer = strings.NewReplacer(
"{\n", "{",
",\n", ",",
"++\n", "++;",
"--\n", "--;",
"+\n", "+",
"-\n", "-",
"*\n", "*",
"/\n", "/",
"%\n", "%",
"&\n", "&",
"|\n", "|",
"^\n", "^",
"<\n", "<",
">\n", ">",
"=\n", "=",
"\n", ";",
)
// gofmtLine returns the gofmt-formatted string for an AST node, // gofmtLine returns the gofmt-formatted string for an AST node,
// ensuring that it is on a single line. // ensuring that it is on a single line.
func gofmtLine(n interface{}) string { func gofmtLine(n interface{}) string {
return strings.Replace(gofmt(n), "\n", ";", -1) return gofmtLineReplacer.Replace(gofmt(n))
} }

View file

@ -47,7 +47,14 @@ type Package struct {
GccFiles []string // list of gcc output files GccFiles []string // list of gcc output files
Preamble string // collected preamble for _cgo_export.h Preamble string // collected preamble for _cgo_export.h
typedefs map[string]bool // type names that appear in the types of the objects we're interested in typedefs map[string]bool // type names that appear in the types of the objects we're interested in
typedefList []string typedefList []typedefInfo
}
// A typedefInfo is an element on Package.typedefList: a typedef name
// and the position where it was required.
type typedefInfo struct {
typedef string
pos token.Pos
} }
// A File collects information about a single Go input file. // A File collects information about a single Go input file.
@ -64,6 +71,9 @@ type File struct {
Edit *edit.Buffer Edit *edit.Buffer
} }
// Untyped constants in the current package.
var consts = make(map[string]bool)
func (f *File) offset(p token.Pos) int { func (f *File) offset(p token.Pos) int {
return fset.Position(p).Offset return fset.Position(p).Offset
} }
@ -96,13 +106,15 @@ func (r *Ref) Pos() token.Pos {
return (*r.Expr).Pos() return (*r.Expr).Pos()
} }
var nameKinds = []string{"iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type"}
// A Name collects information about C.xxx. // A Name collects information about C.xxx.
type Name struct { type Name struct {
Go string // name used in Go referring to package C Go string // name used in Go referring to package C
Mangle string // name used in generated Go Mangle string // name used in generated Go
C string // name used in C C string // name used in C
Define string // #define expansion Define string // #define expansion
Kind string // "iconst", "fconst", "sconst", "type", "var", "fpvar", "func", "macro", "not-type" Kind string // one of the nameKinds
Type *Type // the type of xxx Type *Type // the type of xxx
FuncType *FuncType FuncType *FuncType
AddError bool AddError bool

View file

@ -6,7 +6,6 @@ package main
import ( import (
"bytes" "bytes"
"cmd/internal/xcoff"
"debug/elf" "debug/elf"
"debug/macho" "debug/macho"
"debug/pe" "debug/pe"
@ -14,6 +13,7 @@ import (
"go/ast" "go/ast"
"go/printer" "go/printer"
"go/token" "go/token"
"internal/xcoff"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@ -776,6 +776,13 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprintf(fgcc, "#include <stdlib.h>\n") fmt.Fprintf(fgcc, "#include <stdlib.h>\n")
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n\n") fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n\n")
// We use packed structs, but they are always aligned.
// The pragmas and address-of-packed-member are not recognized as warning groups in clang 3.4.1, so ignore unknown pragmas first.
// remove as part of #27619 (all: drop support for FreeBSD 10).
fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n")
fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Wpragmas\"\n")
fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Waddress-of-packed-member\"\n")
fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);\n") fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);\n")
fmt.Fprintf(fgcc, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done();\n") fmt.Fprintf(fgcc, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done();\n")
fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n") fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n")
@ -1203,7 +1210,7 @@ func (p *Package) writeExportHeader(fgcch io.Writer) {
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog()) fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
} }
// gccgoUsesNewMangling returns whether gccgo uses the new collision-free // gccgoUsesNewMangling reports whether gccgo uses the new collision-free
// packagepath mangling scheme (see determineGccgoManglingScheme for more // packagepath mangling scheme (see determineGccgoManglingScheme for more
// info). // info).
func gccgoUsesNewMangling() bool { func gccgoUsesNewMangling() bool {
@ -1255,7 +1262,7 @@ func determineGccgoManglingScheme() bool {
cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename) cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename)
buf, cerr := cmd.CombinedOutput() buf, cerr := cmd.CombinedOutput()
if cerr != nil { if cerr != nil {
fatalf("%s", err) fatalf("%s", cerr)
} }
// New mangling: expect go.l..u00e4ufer.Run // New mangling: expect go.l..u00e4ufer.Run
@ -1271,7 +1278,7 @@ func gccgoPkgpathToSymbolNew(ppath string) string {
for _, c := range []byte(ppath) { for _, c := range []byte(ppath) {
switch { switch {
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z', case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
'0' <= c && c <= '9', '_' == c: '0' <= c && c <= '9', c == '_', c == '.':
bsl = append(bsl, c) bsl = append(bsl, c)
default: default:
changed = true changed = true
@ -1473,6 +1480,14 @@ __cgo_size_assert(double, 8)
extern char* _cgo_topofstack(void); extern char* _cgo_topofstack(void);
/* We use packed structs, but they are always aligned. */
/* The pragmas and address-of-packed-member are not recognized as warning groups in clang 3.4.1, so ignore unknown pragmas first. */
/* remove as part of #27619 (all: drop support for FreeBSD 10). */
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
` `
@ -1555,6 +1570,7 @@ const builtinProlog = `
/* Define intgo when compiling with GCC. */ /* Define intgo when compiling with GCC. */
typedef ptrdiff_t intgo; typedef ptrdiff_t intgo;
#define GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; intgo n; } _GoString_; typedef struct { const char *p; intgo n; } _GoString_;
typedef struct { char *p; intgo n; intgo c; } _GoBytes_; typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
_GoString_ GoString(char *p); _GoString_ GoString(char *p);
@ -1806,15 +1822,20 @@ void localCgoCheckResult(Eface val) {
// because _cgo_export.h defines GoString as a struct while builtinProlog // because _cgo_export.h defines GoString as a struct while builtinProlog
// defines it as a function. We don't change this to avoid unnecessarily // defines it as a function. We don't change this to avoid unnecessarily
// breaking existing code. // breaking existing code.
// The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
// error if a Go file with a cgo comment #include's the export header
// generated by a different package.
const builtinExportProlog = ` const builtinExportProlog = `
#line 1 "cgo-builtin-prolog" #line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */ #include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H #ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H #define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_; typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif #endif
` `
@ -1823,6 +1844,19 @@ func (p *Package) gccExportHeaderProlog() string {
return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1) return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
} }
// gccExportHeaderProlog is written to the exported header, after the
// import "C" comment preamble but before the generated declarations
// of exported functions. This permits the generated declarations to
// use the type names that appear in goTypes, above.
//
// The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
// error if a Go file with a cgo comment #include's the export header
// generated by a different package. Unfortunately GoString means two
// different things: in this prolog it means a C name for the Go type,
// while in the prolog written into the start of the C code generated
// from a cgo-using Go file it means the C.GoString function. There is
// no way to resolve this conflict, but it also doesn't make much
// difference, as Go code never wants to refer to the latter meaning.
const gccExportHeaderProlog = ` const gccExportHeaderProlog = `
/* Start of boilerplate cgo prologue. */ /* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog" #line 1 "cgo-gcc-export-header-prolog"
@ -1852,7 +1886,9 @@ typedef double _Complex GoComplex128;
*/ */
typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1]; typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString; typedef _GoString_ GoString;
#endif
typedef void *GoMap; typedef void *GoMap;
typedef void *GoChan; typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface; typedef struct { void *t; void *v; } GoInterface;

View file

@ -44,8 +44,12 @@ Flags:
Print compiler version and exit. Print compiler version and exit.
-asmhdr file -asmhdr file
Write assembly header to file. Write assembly header to file.
-buildid id
Record id as the build id in the export metadata.
-blockprofile file -blockprofile file
Write block profile for the compilation to file. Write block profile for the compilation to file.
-c int
Concurrency during compilation. Set 1 for no concurrency (default is 1).
-complete -complete
Assume package has no non-Go components. Assume package has no non-Go components.
-cpuprofile file -cpuprofile file
@ -54,8 +58,14 @@ Flags:
Allow references to Go symbols in shared libraries (experimental). Allow references to Go symbols in shared libraries (experimental).
-e -e
Remove the limit on the number of errors reported (default limit is 10). Remove the limit on the number of errors reported (default limit is 10).
-goversion string
Specify required go tool version of the runtime.
Exits when the runtime go version does not match goversion.
-h -h
Halt with a stack trace at the first error detected. Halt with a stack trace at the first error detected.
-importcfg file
Read import configuration from file.
In the file, set importmap, packagefile to specify import resolution.
-importmap old=new -importmap old=new
Interpret import "old" as import "new" during compilation. Interpret import "old" as import "new" during compilation.
The option may be repeated to add multiple mappings. The option may be repeated to add multiple mappings.
@ -74,6 +84,8 @@ Flags:
object to usual output file (as specified by -o). object to usual output file (as specified by -o).
Without this flag, the -o output is a combination of both Without this flag, the -o output is a combination of both
linker and compiler input. linker and compiler input.
-m
Print optimization decisions.
-memprofile file -memprofile file
Write memory profile for the compilation to file. Write memory profile for the compilation to file.
-memprofilerate rate -memprofilerate rate
@ -93,11 +105,50 @@ Flags:
Write a package (archive) file rather than an object file Write a package (archive) file rather than an object file
-race -race
Compile with race detector enabled. Compile with race detector enabled.
-s
Warn about composite literals that can be simplified.
-shared
Generate code that can be linked into a shared library.
-traceprofile file
Write an execution trace to file.
-trimpath prefix -trimpath prefix
Remove prefix from recorded source file paths. Remove prefix from recorded source file paths.
There are also a number of debugging flags; run the command with no arguments Flags related to debugging information:
for a usage message.
-dwarf
Generate DWARF symbols.
-dwarflocationlists
Add location lists to DWARF in optimized mode.
-gendwarfinl int
Generate DWARF inline info records (default 2).
Flags to debug the compiler itself:
-E
Debug symbol export.
-K
Debug missing line numbers.
-d list
Print debug information about items in list. Try -d help for further information.
-live
Debug liveness analysis.
-v
Increase debug verbosity.
-%
Debug non-static initializers.
-W
Debug parse tree after type checking.
-f
Debug stack frames.
-i
Debug line number stack.
-j
Debug runtime-initialized variables.
-r
Debug generated wrappers.
-w
Debug type checking.
Compiler Directives Compiler Directives

View file

@ -9,18 +9,24 @@
// TestFormats finds potential (Printf, etc.) format strings. // TestFormats finds potential (Printf, etc.) format strings.
// If they are used in a call, the format verbs are verified // If they are used in a call, the format verbs are verified
// based on the matching argument type against a precomputed // based on the matching argument type against a precomputed
// table of valid formats. The knownFormats table can be used // map of valid formats (knownFormats). This map can be used to
// to automatically rewrite format strings with the -u flag. // automatically rewrite format strings across all compiler
// files with the -r flag.
// //
// A new knownFormats table based on the found formats is printed // The format map needs to be updated whenever a new (type,
// when the test is run in verbose mode (-v flag). The table // format) combination is found and the format verb is not
// needs to be updated whenever a new (type, format) combination // 'v' or 'T' (as in "%v" or "%T"). To update the map auto-
// is found and the format verb is not 'v' or 'T' (as in "%v" or // matically from the compiler source's use of format strings,
// "%T"). // use the -u flag. (Whether formats are valid for the values
// to be formatted must be verified manually, of course.)
// //
// Run as: go test -run Formats [-u][-v] // The -v flag prints out the names of all functions called
// with a format string, the names of files that were not
// processed, and any format rewrites made (with -r).
// //
// Known bugs: // Run as: go test -run Formats [-r][-u][-v]
//
// Known shortcomings:
// - indexed format strings ("%[2]s", etc.) are not supported // - indexed format strings ("%[2]s", etc.) are not supported
// (the test will fail) // (the test will fail)
// - format strings that are not simple string literals cannot // - format strings that are not simple string literals cannot
@ -45,6 +51,7 @@ import (
"go/token" "go/token"
"go/types" "go/types"
"internal/testenv" "internal/testenv"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -56,7 +63,10 @@ import (
"unicode/utf8" "unicode/utf8"
) )
var update = flag.Bool("u", false, "update format strings") var (
rewrite = flag.Bool("r", false, "rewrite format strings")
update = flag.Bool("u", false, "update known formats")
)
// The following variables collect information across all processed files. // The following variables collect information across all processed files.
var ( var (
@ -173,11 +183,11 @@ func TestFormats(t *testing.T) {
// write dirty files back // write dirty files back
var filesUpdated bool var filesUpdated bool
if len(updatedFiles) > 0 && *update { if len(updatedFiles) > 0 && *rewrite {
for _, file := range updatedFiles { for _, file := range updatedFiles {
var buf bytes.Buffer var buf bytes.Buffer
if err := format.Node(&buf, fset, file.ast); err != nil { if err := format.Node(&buf, fset, file.ast); err != nil {
t.Errorf("WARNING: formatting %s failed: %v", file.name, err) t.Errorf("WARNING: gofmt %s failed: %v", file.name, err)
continue continue
} }
if err := ioutil.WriteFile(file.name, buf.Bytes(), 0x666); err != nil { if err := ioutil.WriteFile(file.name, buf.Bytes(), 0x666); err != nil {
@ -189,7 +199,7 @@ func TestFormats(t *testing.T) {
} }
} }
// report all function names containing a format string // report the names of all functions called with a format string
if len(callSites) > 0 && testing.Verbose() { if len(callSites) > 0 && testing.Verbose() {
set := make(map[string]bool) set := make(map[string]bool)
for _, p := range callSites { for _, p := range callSites {
@ -199,23 +209,33 @@ func TestFormats(t *testing.T) {
for s := range set { for s := range set {
list = append(list, s) list = append(list, s)
} }
fmt.Println("\nFunctions") fmt.Println("\nFunctions called with a format string")
printList(list) writeList(os.Stdout, list)
} }
// report all formats found // update formats
if len(foundFormats) > 0 && testing.Verbose() { if len(foundFormats) > 0 && *update {
var list []string var list []string
for s := range foundFormats { for s := range foundFormats {
list = append(list, fmt.Sprintf("%q: \"\",", s)) list = append(list, fmt.Sprintf("%q: \"\",", s))
} }
fmt.Println("\nvar knownFormats = map[string]string{") var buf bytes.Buffer
printList(list) buf.WriteString(knownFormatsHeader)
fmt.Println("}") writeList(&buf, list)
buf.WriteString("}\n")
out, err := format.Source(buf.Bytes())
const outfile = "fmtmap_test.go"
if err != nil {
t.Errorf("WARNING: gofmt %s failed: %v", outfile, err)
out = buf.Bytes() // continue with unformatted source
}
if err = ioutil.WriteFile(outfile, out, 0644); err != nil {
t.Errorf("WARNING: updating format map failed: %v", err)
}
} }
// check that knownFormats is up to date // check that knownFormats is up to date
if !testing.Verbose() && !*update { if !*rewrite && !*update {
var mismatch bool var mismatch bool
for s := range foundFormats { for s := range foundFormats {
if _, ok := knownFormats[s]; !ok { if _, ok := knownFormats[s]; !ok {
@ -232,7 +252,7 @@ func TestFormats(t *testing.T) {
} }
} }
if mismatch { if mismatch {
t.Errorf("knownFormats is out of date; please 'go test -v fmt_test.go > foo', then extract new definition of knownFormats from foo") t.Errorf("format map is out of date; run 'go test -u' to update and manually verify correctness of change'")
} }
} }
@ -256,7 +276,7 @@ func TestFormats(t *testing.T) {
list = append(list, fmt.Sprintf("%s: %s", posString(lit), nodeString(lit))) list = append(list, fmt.Sprintf("%s: %s", posString(lit), nodeString(lit)))
} }
fmt.Println("\nWARNING: Potentially missed format strings") fmt.Println("\nWARNING: Potentially missed format strings")
printList(list) writeList(os.Stdout, list)
t.Fail() t.Fail()
} }
@ -365,11 +385,11 @@ func collectPkgFormats(t *testing.T, pkg *build.Package) {
} }
} }
// printList prints list in sorted order. // writeList writes list in sorted order to w.
func printList(list []string) { func writeList(w io.Writer, list []string) {
sort.Strings(list) sort.Strings(list)
for _, s := range list { for _, s := range list {
fmt.Println("\t", s) fmt.Fprintln(w, "\t", s)
} }
} }
@ -542,7 +562,7 @@ func init() {
// verify that knownFormats entries are correctly formatted // verify that knownFormats entries are correctly formatted
for key, val := range knownFormats { for key, val := range knownFormats {
// key must be "typename format", and format starts with a '%' // key must be "typename format", and format starts with a '%'
// (formats containing '*' alone are not collected in this table) // (formats containing '*' alone are not collected in this map)
i := strings.Index(key, "%") i := strings.Index(key, "%")
if i < 0 || !oneFormat(key[i:]) { if i < 0 || !oneFormat(key[i:]) {
log.Fatalf("incorrect knownFormats key: %q", key) log.Fatalf("incorrect knownFormats key: %q", key)
@ -554,188 +574,26 @@ func init() {
} }
} }
const knownFormatsHeader = `// 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.
// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.
package main_test
// knownFormats entries are of the form "typename format" -> "newformat". // knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid. // An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged. // An empty new format means that the format should remain unchanged.
// To print out a new table, run: go test -run Formats -v.
var knownFormats = map[string]string{ var knownFormats = map[string]string{
"*bytes.Buffer %s": "", `
"*cmd/compile/internal/gc.Mpflt %v": "",
"*cmd/compile/internal/gc.Mpint %v": "",
"*cmd/compile/internal/gc.Node %#v": "",
"*cmd/compile/internal/gc.Node %+S": "",
"*cmd/compile/internal/gc.Node %+v": "",
"*cmd/compile/internal/gc.Node %0j": "",
"*cmd/compile/internal/gc.Node %L": "",
"*cmd/compile/internal/gc.Node %S": "",
"*cmd/compile/internal/gc.Node %j": "",
"*cmd/compile/internal/gc.Node %p": "",
"*cmd/compile/internal/gc.Node %v": "",
"*cmd/compile/internal/ssa.Block %s": "",
"*cmd/compile/internal/ssa.Block %v": "",
"*cmd/compile/internal/ssa.Func %s": "",
"*cmd/compile/internal/ssa.Func %v": "",
"*cmd/compile/internal/ssa.Register %s": "",
"*cmd/compile/internal/ssa.Register %v": "",
"*cmd/compile/internal/ssa.SparseTreeNode %v": "",
"*cmd/compile/internal/ssa.Value %s": "",
"*cmd/compile/internal/ssa.Value %v": "",
"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
"*cmd/compile/internal/types.Field %p": "",
"*cmd/compile/internal/types.Field %v": "",
"*cmd/compile/internal/types.Sym %0S": "",
"*cmd/compile/internal/types.Sym %S": "",
"*cmd/compile/internal/types.Sym %p": "",
"*cmd/compile/internal/types.Sym %v": "",
"*cmd/compile/internal/types.Type %#L": "",
"*cmd/compile/internal/types.Type %#v": "",
"*cmd/compile/internal/types.Type %+v": "",
"*cmd/compile/internal/types.Type %-S": "",
"*cmd/compile/internal/types.Type %0S": "",
"*cmd/compile/internal/types.Type %L": "",
"*cmd/compile/internal/types.Type %S": "",
"*cmd/compile/internal/types.Type %p": "",
"*cmd/compile/internal/types.Type %s": "",
"*cmd/compile/internal/types.Type %v": "",
"*cmd/internal/obj.Addr %v": "",
"*cmd/internal/obj.LSym %v": "",
"*math/big.Float %f": "",
"*math/big.Int %#x": "",
"*math/big.Int %s": "",
"*math/big.Int %v": "",
"[16]byte %x": "",
"[]*cmd/compile/internal/gc.Node %v": "",
"[]*cmd/compile/internal/ssa.Block %v": "",
"[]*cmd/compile/internal/ssa.Value %v": "",
"[][]string %q": "",
"[]byte %s": "",
"[]byte %x": "",
"[]cmd/compile/internal/ssa.Edge %v": "",
"[]cmd/compile/internal/ssa.ID %v": "",
"[]cmd/compile/internal/ssa.posetNode %v": "",
"[]cmd/compile/internal/ssa.posetUndo %v": "",
"[]cmd/compile/internal/syntax.token %s": "",
"[]string %v": "",
"[]uint32 %v": "",
"bool %v": "",
"byte %08b": "",
"byte %c": "",
"byte %v": "",
"cmd/compile/internal/arm.shift %d": "",
"cmd/compile/internal/gc.Class %d": "",
"cmd/compile/internal/gc.Class %s": "",
"cmd/compile/internal/gc.Class %v": "",
"cmd/compile/internal/gc.Ctype %d": "",
"cmd/compile/internal/gc.Ctype %v": "",
"cmd/compile/internal/gc.Level %d": "",
"cmd/compile/internal/gc.Level %v": "",
"cmd/compile/internal/gc.Nodes %#v": "",
"cmd/compile/internal/gc.Nodes %+v": "",
"cmd/compile/internal/gc.Nodes %.v": "",
"cmd/compile/internal/gc.Nodes %v": "",
"cmd/compile/internal/gc.Op %#v": "",
"cmd/compile/internal/gc.Op %v": "",
"cmd/compile/internal/gc.Val %#v": "",
"cmd/compile/internal/gc.Val %T": "",
"cmd/compile/internal/gc.Val %v": "",
"cmd/compile/internal/gc.fmtMode %d": "",
"cmd/compile/internal/gc.initKind %d": "",
"cmd/compile/internal/gc.itag %v": "",
"cmd/compile/internal/ssa.BranchPrediction %d": "",
"cmd/compile/internal/ssa.Edge %v": "",
"cmd/compile/internal/ssa.GCNode %v": "",
"cmd/compile/internal/ssa.ID %d": "",
"cmd/compile/internal/ssa.ID %v": "",
"cmd/compile/internal/ssa.LocPair %s": "",
"cmd/compile/internal/ssa.LocalSlot %s": "",
"cmd/compile/internal/ssa.LocalSlot %v": "",
"cmd/compile/internal/ssa.Location %T": "",
"cmd/compile/internal/ssa.Location %s": "",
"cmd/compile/internal/ssa.Op %s": "",
"cmd/compile/internal/ssa.Op %v": "",
"cmd/compile/internal/ssa.ValAndOff %s": "",
"cmd/compile/internal/ssa.domain %v": "",
"cmd/compile/internal/ssa.posetNode %v": "",
"cmd/compile/internal/ssa.posetTestOp %v": "",
"cmd/compile/internal/ssa.rbrank %d": "",
"cmd/compile/internal/ssa.regMask %d": "",
"cmd/compile/internal/ssa.register %d": "",
"cmd/compile/internal/syntax.Error %q": "",
"cmd/compile/internal/syntax.Expr %#v": "",
"cmd/compile/internal/syntax.Node %T": "",
"cmd/compile/internal/syntax.Operator %s": "",
"cmd/compile/internal/syntax.Pos %s": "",
"cmd/compile/internal/syntax.Pos %v": "",
"cmd/compile/internal/syntax.position %s": "",
"cmd/compile/internal/syntax.token %q": "",
"cmd/compile/internal/syntax.token %s": "",
"cmd/compile/internal/types.EType %d": "",
"cmd/compile/internal/types.EType %s": "",
"cmd/compile/internal/types.EType %v": "",
"error %v": "",
"float64 %.2f": "",
"float64 %.3f": "",
"float64 %.6g": "",
"float64 %g": "",
"int %-12d": "",
"int %-6d": "",
"int %-8o": "",
"int %02d": "",
"int %6d": "",
"int %c": "",
"int %d": "",
"int %v": "",
"int %x": "",
"int16 %d": "",
"int16 %x": "",
"int32 %d": "",
"int32 %v": "",
"int32 %x": "",
"int64 %+d": "",
"int64 %-10d": "",
"int64 %.5d": "",
"int64 %X": "",
"int64 %d": "",
"int64 %v": "",
"int64 %x": "",
"int8 %d": "",
"int8 %x": "",
"interface{} %#v": "",
"interface{} %T": "",
"interface{} %p": "",
"interface{} %q": "",
"interface{} %s": "",
"interface{} %v": "",
"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
"map[cmd/compile/internal/ssa.ID]uint32 %v": "",
"math/big.Accuracy %s": "",
"reflect.Type %s": "",
"rune %#U": "",
"rune %c": "",
"string %-*s": "",
"string %-16s": "",
"string %-6s": "",
"string %.*s": "",
"string %q": "",
"string %s": "",
"string %v": "",
"time.Duration %d": "",
"time.Duration %v": "",
"uint %04x": "",
"uint %5d": "",
"uint %d": "",
"uint %x": "",
"uint16 %d": "",
"uint16 %v": "",
"uint16 %x": "",
"uint32 %#x": "",
"uint32 %d": "",
"uint32 %v": "",
"uint32 %x": "",
"uint64 %08x": "",
"uint64 %d": "",
"uint64 %x": "",
"uint8 %d": "",
"uint8 %x": "",
"uintptr %d": "",
}

View file

@ -0,0 +1,204 @@
// 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.
// This file implements the knownFormats map which records the valid
// formats for a given type. The valid formats must correspond to
// supported compiler formats implemented in fmt.go, or whatever
// other format verbs are implemented for the given type. The map may
// also be used to change the use of a format verb across all compiler
// sources automatically (for instance, if the implementation of fmt.go
// changes), by using the -r option together with the new formats in the
// map. To generate this file automatically from the existing source,
// run: go test -run Formats -u.
//
// See the package comment in fmt_test.go for additional information.
package main_test
// knownFormats entries are of the form "typename format" -> "newformat".
// An absent entry means that the format is not recognized as valid.
// An empty new format means that the format should remain unchanged.
var knownFormats = map[string]string{
"*bytes.Buffer %s": "",
"*cmd/compile/internal/gc.Mpflt %v": "",
"*cmd/compile/internal/gc.Mpint %v": "",
"*cmd/compile/internal/gc.Node %#v": "",
"*cmd/compile/internal/gc.Node %+S": "",
"*cmd/compile/internal/gc.Node %+v": "",
"*cmd/compile/internal/gc.Node %0j": "",
"*cmd/compile/internal/gc.Node %L": "",
"*cmd/compile/internal/gc.Node %S": "",
"*cmd/compile/internal/gc.Node %j": "",
"*cmd/compile/internal/gc.Node %p": "",
"*cmd/compile/internal/gc.Node %v": "",
"*cmd/compile/internal/ssa.Block %s": "",
"*cmd/compile/internal/ssa.Block %v": "",
"*cmd/compile/internal/ssa.Func %s": "",
"*cmd/compile/internal/ssa.Func %v": "",
"*cmd/compile/internal/ssa.Register %s": "",
"*cmd/compile/internal/ssa.Register %v": "",
"*cmd/compile/internal/ssa.SparseTreeNode %v": "",
"*cmd/compile/internal/ssa.Value %s": "",
"*cmd/compile/internal/ssa.Value %v": "",
"*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "",
"*cmd/compile/internal/types.Field %p": "",
"*cmd/compile/internal/types.Field %v": "",
"*cmd/compile/internal/types.Sym %0S": "",
"*cmd/compile/internal/types.Sym %S": "",
"*cmd/compile/internal/types.Sym %p": "",
"*cmd/compile/internal/types.Sym %v": "",
"*cmd/compile/internal/types.Type %#L": "",
"*cmd/compile/internal/types.Type %#v": "",
"*cmd/compile/internal/types.Type %+v": "",
"*cmd/compile/internal/types.Type %-S": "",
"*cmd/compile/internal/types.Type %0S": "",
"*cmd/compile/internal/types.Type %L": "",
"*cmd/compile/internal/types.Type %S": "",
"*cmd/compile/internal/types.Type %p": "",
"*cmd/compile/internal/types.Type %s": "",
"*cmd/compile/internal/types.Type %v": "",
"*cmd/internal/obj.Addr %v": "",
"*cmd/internal/obj.LSym %v": "",
"*math/big.Float %f": "",
"*math/big.Int %#x": "",
"*math/big.Int %s": "",
"*math/big.Int %v": "",
"[16]byte %x": "",
"[]*cmd/compile/internal/gc.Node %v": "",
"[]*cmd/compile/internal/ssa.Block %v": "",
"[]*cmd/compile/internal/ssa.Value %v": "",
"[][]string %q": "",
"[]byte %s": "",
"[]byte %x": "",
"[]cmd/compile/internal/ssa.Edge %v": "",
"[]cmd/compile/internal/ssa.ID %v": "",
"[]cmd/compile/internal/ssa.posetNode %v": "",
"[]cmd/compile/internal/ssa.posetUndo %v": "",
"[]cmd/compile/internal/syntax.token %s": "",
"[]string %v": "",
"[]uint32 %v": "",
"bool %v": "",
"byte %08b": "",
"byte %c": "",
"byte %v": "",
"cmd/compile/internal/arm.shift %d": "",
"cmd/compile/internal/gc.Class %d": "",
"cmd/compile/internal/gc.Class %s": "",
"cmd/compile/internal/gc.Class %v": "",
"cmd/compile/internal/gc.Ctype %d": "",
"cmd/compile/internal/gc.Ctype %v": "",
"cmd/compile/internal/gc.Level %d": "",
"cmd/compile/internal/gc.Level %v": "",
"cmd/compile/internal/gc.Nodes %#v": "",
"cmd/compile/internal/gc.Nodes %+v": "",
"cmd/compile/internal/gc.Nodes %.v": "",
"cmd/compile/internal/gc.Nodes %v": "",
"cmd/compile/internal/gc.Op %#v": "",
"cmd/compile/internal/gc.Op %v": "",
"cmd/compile/internal/gc.Val %#v": "",
"cmd/compile/internal/gc.Val %T": "",
"cmd/compile/internal/gc.Val %v": "",
"cmd/compile/internal/gc.fmtMode %d": "",
"cmd/compile/internal/gc.initKind %d": "",
"cmd/compile/internal/gc.itag %v": "",
"cmd/compile/internal/ssa.BranchPrediction %d": "",
"cmd/compile/internal/ssa.Edge %v": "",
"cmd/compile/internal/ssa.GCNode %v": "",
"cmd/compile/internal/ssa.ID %d": "",
"cmd/compile/internal/ssa.ID %v": "",
"cmd/compile/internal/ssa.LocPair %s": "",
"cmd/compile/internal/ssa.LocalSlot %s": "",
"cmd/compile/internal/ssa.LocalSlot %v": "",
"cmd/compile/internal/ssa.Location %T": "",
"cmd/compile/internal/ssa.Location %s": "",
"cmd/compile/internal/ssa.Op %s": "",
"cmd/compile/internal/ssa.Op %v": "",
"cmd/compile/internal/ssa.ValAndOff %s": "",
"cmd/compile/internal/ssa.domain %v": "",
"cmd/compile/internal/ssa.posetNode %v": "",
"cmd/compile/internal/ssa.posetTestOp %v": "",
"cmd/compile/internal/ssa.rbrank %d": "",
"cmd/compile/internal/ssa.regMask %d": "",
"cmd/compile/internal/ssa.register %d": "",
"cmd/compile/internal/ssa.relation %s": "",
"cmd/compile/internal/syntax.Error %q": "",
"cmd/compile/internal/syntax.Expr %#v": "",
"cmd/compile/internal/syntax.Node %T": "",
"cmd/compile/internal/syntax.Operator %s": "",
"cmd/compile/internal/syntax.Pos %s": "",
"cmd/compile/internal/syntax.Pos %v": "",
"cmd/compile/internal/syntax.position %s": "",
"cmd/compile/internal/syntax.token %q": "",
"cmd/compile/internal/syntax.token %s": "",
"cmd/compile/internal/types.EType %d": "",
"cmd/compile/internal/types.EType %s": "",
"cmd/compile/internal/types.EType %v": "",
"cmd/internal/obj.ABI %v": "",
"error %v": "",
"float64 %.2f": "",
"float64 %.3f": "",
"float64 %.6g": "",
"float64 %g": "",
"int %-12d": "",
"int %-6d": "",
"int %-8o": "",
"int %02d": "",
"int %6d": "",
"int %c": "",
"int %d": "",
"int %v": "",
"int %x": "",
"int16 %d": "",
"int16 %x": "",
"int32 %d": "",
"int32 %v": "",
"int32 %x": "",
"int64 %+d": "",
"int64 %-10d": "",
"int64 %.5d": "",
"int64 %X": "",
"int64 %d": "",
"int64 %v": "",
"int64 %x": "",
"int8 %d": "",
"int8 %x": "",
"interface{} %#v": "",
"interface{} %T": "",
"interface{} %p": "",
"interface{} %q": "",
"interface{} %s": "",
"interface{} %v": "",
"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
"map[cmd/compile/internal/ssa.ID]uint32 %v": "",
"math/big.Accuracy %s": "",
"reflect.Type %s": "",
"rune %#U": "",
"rune %c": "",
"string %-*s": "",
"string %-16s": "",
"string %-6s": "",
"string %.*s": "",
"string %q": "",
"string %s": "",
"string %v": "",
"time.Duration %d": "",
"time.Duration %v": "",
"uint %04x": "",
"uint %5d": "",
"uint %d": "",
"uint %x": "",
"uint16 %d": "",
"uint16 %v": "",
"uint16 %x": "",
"uint32 %#x": "",
"uint32 %d": "",
"uint32 %v": "",
"uint32 %x": "",
"uint64 %08x": "",
"uint64 %d": "",
"uint64 %x": "",
"uint8 %d": "",
"uint8 %x": "",
"uintptr %d": "",
}

View file

@ -141,7 +141,7 @@ func zeroAuto(pp *gc.Progs, n *gc.Node) {
} }
} }
func ginsnop(pp *gc.Progs) { func ginsnop(pp *gc.Progs) *obj.Prog {
// This is actually not the x86 NOP anymore, // This is actually not the x86 NOP anymore,
// but at the point where it gets used, AX is dead // but at the point where it gets used, AX is dead
// so it's okay if we lose the high bits. // so it's okay if we lose the high bits.
@ -150,4 +150,5 @@ func ginsnop(pp *gc.Progs) {
p.From.Reg = x86.REG_AX p.From.Reg = x86.REG_AX
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_AX p.To.Reg = x86.REG_AX
return p
} }

View file

@ -68,11 +68,12 @@ func zeroAuto(pp *gc.Progs, n *gc.Node) {
} }
} }
func ginsnop(pp *gc.Progs) { func ginsnop(pp *gc.Progs) *obj.Prog {
p := pp.Prog(arm.AAND) p := pp.Prog(arm.AAND)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = arm.REG_R0 p.From.Reg = arm.REG_R0
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = arm.REG_R0 p.To.Reg = arm.REG_R0
p.Scond = arm.C_SCOND_EQ p.Scond = arm.C_SCOND_EQ
return p
} }

View file

@ -79,7 +79,8 @@ func zeroAuto(pp *gc.Progs, n *gc.Node) {
} }
} }
func ginsnop(pp *gc.Progs) { func ginsnop(pp *gc.Progs) *obj.Prog {
p := pp.Prog(arm64.AHINT) p := pp.Prog(arm64.AHINT)
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
return p
} }

View file

@ -217,7 +217,7 @@ func genhash(sym *types.Sym, t *types.Type) {
// pure memory. // pure memory.
hashel := hashfor(t.Elem()) hashel := hashfor(t.Elem())
n := nod(ORANGE, nil, nod(OIND, np, nil)) n := nod(ORANGE, nil, nod(ODEREF, np, nil))
ni := newname(lookup("i")) ni := newname(lookup("i"))
ni.Type = types.Types[TINT] ni.Type = types.Types[TINT]
n.List.Set1(ni) n.List.Set1(ni)
@ -290,10 +290,10 @@ func genhash(sym *types.Sym, t *types.Type) {
funcbody() funcbody()
fn.Func.SetDupok(true) fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, ctxStmt)
Curfn = fn Curfn = fn
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), ctxStmt)
Curfn = nil Curfn = nil
if debug_dclstack != 0 { if debug_dclstack != 0 {
@ -330,6 +330,7 @@ func hashfor(t *types.Type) *Node {
n := newname(sym) n := newname(sym)
n.SetClass(PFUNC) n.SetClass(PFUNC)
n.Sym.SetFunc(true)
n.Type = functype(nil, []*Node{ n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)),
anonfield(types.Types[TUINTPTR]), anonfield(types.Types[TUINTPTR]),
@ -374,7 +375,7 @@ func geneq(sym *types.Sym, t *types.Type) {
// pure memory. Even if we unrolled the range loop, // pure memory. Even if we unrolled the range loop,
// each iteration would be a function call, so don't bother // each iteration would be a function call, so don't bother
// unrolling. // unrolling.
nrange := nod(ORANGE, nil, nod(OIND, np, nil)) nrange := nod(ORANGE, nil, nod(ODEREF, np, nil))
ni := newname(lookup("i")) ni := newname(lookup("i"))
ni.Type = types.Types[TINT] ni.Type = types.Types[TINT]
@ -464,10 +465,10 @@ func geneq(sym *types.Sym, t *types.Type) {
funcbody() funcbody()
fn.Func.SetDupok(true) fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, ctxStmt)
Curfn = fn Curfn = fn
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), ctxStmt)
Curfn = nil Curfn = nil
if debug_dclstack != 0 { if debug_dclstack != 0 {
@ -496,8 +497,8 @@ func eqfield(p *Node, q *Node, field *types.Sym) *Node {
func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node { func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
nx := nod(OADDR, nodSym(OXDOT, p, field), nil) nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
ny := nod(OADDR, nodSym(OXDOT, q, field), nil) ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
nx = typecheck(nx, Erv) nx = typecheck(nx, ctxExpr)
ny = typecheck(ny, Erv) ny = typecheck(ny, ctxExpr)
fn, needsize := eqmemfunc(size, nx.Type.Elem()) fn, needsize := eqmemfunc(size, nx.Type.Elem())
call := nod(OCALL, fn, nil) call := nod(OCALL, fn, nil)

View file

@ -144,8 +144,9 @@ var runtimeDecls = [...]struct {
{"racewriterange", funcTag, 113}, {"racewriterange", funcTag, 113},
{"msanread", funcTag, 113}, {"msanread", funcTag, 113},
{"msanwrite", funcTag, 113}, {"msanwrite", funcTag, 113},
{"support_popcnt", varTag, 11}, {"x86HasPOPCNT", varTag, 11},
{"support_sse41", varTag, 11}, {"x86HasSSE41", varTag, 11},
{"arm64HasATOMICS", varTag, 11},
} }
func runtimeTypes() []*types.Type { func runtimeTypes() []*types.Type {

View file

@ -195,5 +195,6 @@ func msanread(addr, size uintptr)
func msanwrite(addr, size uintptr) func msanwrite(addr, size uintptr)
// architecture variants // architecture variants
var support_popcnt bool var x86HasPOPCNT bool
var support_sse41 bool var x86HasSSE41 bool
var arm64HasATOMICS bool

View file

@ -93,7 +93,7 @@ func typecheckclosure(clo *Node, top int) {
xfunc.Func.Nname.Sym = closurename(Curfn) xfunc.Func.Nname.Sym = closurename(Curfn)
disableExport(xfunc.Func.Nname.Sym) disableExport(xfunc.Func.Nname.Sym)
declare(xfunc.Func.Nname, PFUNC) declare(xfunc.Func.Nname, PFUNC)
xfunc = typecheck(xfunc, Etop) xfunc = typecheck(xfunc, ctxStmt)
clo.Func.Ntype = typecheck(clo.Func.Ntype, Etype) clo.Func.Ntype = typecheck(clo.Func.Ntype, Etype)
clo.Type = clo.Func.Ntype.Type clo.Type = clo.Func.Ntype.Type
@ -108,7 +108,7 @@ func typecheckclosure(clo *Node, top int) {
Curfn = xfunc Curfn = xfunc
olddd := decldepth olddd := decldepth
decldepth = 1 decldepth = 1
typecheckslice(xfunc.Nbody.Slice(), Etop) typecheckslice(xfunc.Nbody.Slice(), ctxStmt)
decldepth = olddd decldepth = olddd
Curfn = oldfn Curfn = oldfn
} }
@ -199,7 +199,7 @@ func capturevars(xfunc *Node) {
Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Addrtaken(), outermost.Assigned(), int32(v.Type.Width)) Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Addrtaken(), outermost.Assigned(), int32(v.Type.Width))
} }
outer = typecheck(outer, Erv) outer = typecheck(outer, ctxExpr)
clo.Func.Enter.Append(outer) clo.Func.Enter.Append(outer)
} }
@ -214,7 +214,7 @@ func transformclosure(xfunc *Node) {
lineno = xfunc.Pos lineno = xfunc.Pos
clo := xfunc.Func.Closure clo := xfunc.Func.Closure
if clo.Func.Top&Ecall != 0 { if clo.Func.Top&ctxCallee != 0 {
// If the closure is directly called, we transform it to a plain function call // If the closure is directly called, we transform it to a plain function call
// with variables passed as args. This avoids allocation of a closure object. // with variables passed as args. This avoids allocation of a closure object.
// Here we do only a part of the transformation. Walk of OCALLFUNC(OCLOSURE) // Here we do only a part of the transformation. Walk of OCALLFUNC(OCLOSURE)
@ -305,7 +305,7 @@ func transformclosure(xfunc *Node) {
} }
if len(body) > 0 { if len(body) > 0 {
typecheckslice(body, Etop) typecheckslice(body, ctxStmt)
xfunc.Func.Enter.Set(body) xfunc.Func.Enter.Set(body)
xfunc.Func.SetNeedctxt(true) xfunc.Func.SetNeedctxt(true)
} }
@ -383,7 +383,7 @@ func walkclosure(clo *Node, init *Nodes) *Node {
typ := closureType(clo) typ := closureType(clo)
clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil)) clos := nod(OCOMPLIT, nil, nod(ODEREF, typenod(typ), nil))
clos.Esc = clo.Esc clos.Esc = clo.Esc
clos.Right.SetImplicit(true) clos.Right.SetImplicit(true)
clos.List.Set(append([]*Node{nod(OCFUNC, xfunc.Func.Nname, nil)}, clo.Func.Enter.Slice()...)) clos.List.Set(append([]*Node{nod(OCFUNC, xfunc.Func.Nname, nil)}, clo.Func.Enter.Slice()...))
@ -434,8 +434,20 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
sym.SetUniq(true) sym.SetUniq(true)
savecurfn := Curfn savecurfn := Curfn
saveLineNo := lineno
Curfn = nil Curfn = nil
// Set line number equal to the line number where the method is declared.
var m *types.Field
if lookdot0(meth, rcvrtype, &m, false) == 1 && m.Pos.IsKnown() {
lineno = m.Pos
}
// Note: !m.Pos.IsKnown() happens for method expressions where
// the method is implicitly declared. The Error method of the
// built-in error type is one such method. We leave the line
// number at the use of the method expression in this
// case. See issue 29389.
tfn := nod(OTFUNC, nil, nil) tfn := nod(OTFUNC, nil, nil)
tfn.List.Set(structargs(t0.Params(), true)) tfn.List.Set(structargs(t0.Params(), true))
tfn.Rlist.Set(structargs(t0.Results(), false)) tfn.Rlist.Set(structargs(t0.Results(), false))
@ -467,7 +479,7 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil) call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
call.List.Set(paramNnames(tfn.Type)) call.List.Set(paramNnames(tfn.Type))
call.SetIsddd(tfn.Type.IsVariadic()) call.SetIsDDD(tfn.Type.IsVariadic())
if t0.NumResults() != 0 { if t0.NumResults() != 0 {
n := nod(ORETURN, nil, nil) n := nod(ORETURN, nil, nil)
n.List.Set1(call) n.List.Set1(call)
@ -478,10 +490,11 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
xfunc.Nbody.Set(body) xfunc.Nbody.Set(body)
funcbody() funcbody()
xfunc = typecheck(xfunc, Etop) xfunc = typecheck(xfunc, ctxStmt)
sym.Def = asTypesNode(xfunc) sym.Def = asTypesNode(xfunc)
xtop = append(xtop, xfunc) xtop = append(xtop, xfunc)
Curfn = savecurfn Curfn = savecurfn
lineno = saveLineNo
return xfunc return xfunc
} }
@ -516,7 +529,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
typ := partialCallType(n) typ := partialCallType(n)
clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil)) clos := nod(OCOMPLIT, nil, nod(ODEREF, typenod(typ), nil))
clos.Esc = n.Esc clos.Esc = n.Esc
clos.Right.SetImplicit(true) clos.Right.SetImplicit(true)
clos.List.Set2(nod(OCFUNC, n.Func.Nname, nil), n.Left) clos.List.Set2(nod(OCFUNC, n.Func.Nname, nil), n.Left)

View file

@ -584,11 +584,19 @@ func Isconst(n *Node, ct Ctype) bool {
// evconst rewrites constant expressions into OLITERAL nodes. // evconst rewrites constant expressions into OLITERAL nodes.
func evconst(n *Node) { func evconst(n *Node) {
if !n.isGoConst() {
// Avoid constant evaluation of things that aren't actually constants
// according to the spec. See issue 24760.
// The SSA backend has a more robust optimizer that will catch
// all of these weird cases (like uintptr(unsafe.Pointer(uintptr(1)))).
return
}
nl, nr := n.Left, n.Right nl, nr := n.Left, n.Right
// Pick off just the opcodes that can be constant evaluated. // Pick off just the opcodes that can be constant evaluated.
switch op := n.Op; op { switch op := n.Op; op {
case OPLUS, OMINUS, OCOM, ONOT: case OPLUS, ONEG, OBITNOT, ONOT:
if nl.Op == OLITERAL { if nl.Op == OLITERAL {
setconst(n, unaryOp(op, nl.Val(), n.Type)) setconst(n, unaryOp(op, nl.Val(), n.Type))
} }
@ -623,7 +631,7 @@ func evconst(n *Node) {
setconst(n, convlit1(nl, n.Type, true, false).Val()) setconst(n, convlit1(nl, n.Type, true, false).Val())
} }
case OARRAYBYTESTR: case OBYTES2STR:
// string([]byte(nil)) or string([]rune(nil)) // string([]byte(nil)) or string([]rune(nil))
if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL { if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL {
setconst(n, Val{U: ""}) setconst(n, Val{U: ""})
@ -873,7 +881,7 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
return x return x
} }
case OMINUS: case ONEG:
switch x.Ctype() { switch x.Ctype() {
case CTINT, CTRUNE: case CTINT, CTRUNE:
x := x.U.(*Mpint) x := x.U.(*Mpint)
@ -900,7 +908,7 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
return Val{U: u} return Val{U: u}
} }
case OCOM: case OBITNOT:
x := x.U.(*Mpint) x := x.U.(*Mpint)
u := new(Mpint) u := new(Mpint)
@ -1024,9 +1032,9 @@ func idealkind(n *Node) Ctype {
case OADD, case OADD,
OAND, OAND,
OANDNOT, OANDNOT,
OCOM, OBITNOT,
ODIV, ODIV,
OMINUS, ONEG,
OMOD, OMOD,
OMUL, OMUL,
OSUB, OSUB,
@ -1221,6 +1229,7 @@ func strlit(n *Node) string {
return n.Val().U.(string) return n.Val().U.(string)
} }
// TODO(gri) smallintconst is only used in one place - can we used indexconst?
func smallintconst(n *Node) bool { func smallintconst(n *Node) bool {
if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
switch simtype[n.Type.Etype] { switch simtype[n.Type.Etype] {
@ -1235,7 +1244,7 @@ func smallintconst(n *Node) bool {
case TIDEAL, TINT64, TUINT64, TPTR: case TIDEAL, TINT64, TUINT64, TPTR:
v, ok := n.Val().U.(*Mpint) v, ok := n.Val().U.(*Mpint)
if ok && v.Cmp(minintval[TINT32]) > 0 && v.Cmp(maxintval[TINT32]) < 0 { if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 {
return true return true
} }
} }
@ -1244,21 +1253,24 @@ func smallintconst(n *Node) bool {
return false return false
} }
// nonnegintconst checks if Node n contains a constant expression // indexconst checks if Node n contains a constant expression
// representable as a non-negative small integer, and returns its // representable as a non-negative int and returns its value.
// (integer) value if that's the case. Otherwise, it returns -1. // If n is not a constant expression, not representable as an
func nonnegintconst(n *Node) int64 { // integer, or negative, it returns -1. If n is too large, it
// returns -2.
func indexconst(n *Node) int64 {
if n.Op != OLITERAL { if n.Op != OLITERAL {
return -1 return -1
} }
// toint will leave n.Val unchanged if it's not castable to an v := toint(n.Val()) // toint returns argument unchanged if not representable as an *Mpint
// Mpint, so we still have to guard the conversion.
v := toint(n.Val())
vi, ok := v.U.(*Mpint) vi, ok := v.U.(*Mpint)
if !ok || vi.CmpInt64(0) < 0 || vi.Cmp(maxintval[TINT32]) > 0 { if !ok || vi.CmpInt64(0) < 0 {
return -1 return -1
} }
if vi.Cmp(maxintval[TINT]) > 0 {
return -2
}
return vi.Int64() return vi.Int64()
} }
@ -1268,7 +1280,7 @@ func nonnegintconst(n *Node) int64 {
// //
// Expressions derived from nil, like string([]byte(nil)), while they // Expressions derived from nil, like string([]byte(nil)), while they
// may be known at compile time, are not Go language constants. // may be known at compile time, are not Go language constants.
// Only called for expressions known to evaluated to compile-time // Only called for expressions known to evaluate to compile-time
// constants. // constants.
func (n *Node) isGoConst() bool { func (n *Node) isGoConst() bool {
if n.Orig != nil { if n.Orig != nil {
@ -1277,11 +1289,10 @@ func (n *Node) isGoConst() bool {
switch n.Op { switch n.Op {
case OADD, case OADD,
OADDSTR,
OAND, OAND,
OANDAND, OANDAND,
OANDNOT, OANDNOT,
OCOM, OBITNOT,
ODIV, ODIV,
OEQ, OEQ,
OGE, OGE,
@ -1289,7 +1300,7 @@ func (n *Node) isGoConst() bool {
OLE, OLE,
OLSH, OLSH,
OLT, OLT,
OMINUS, ONEG,
OMOD, OMOD,
OMUL, OMUL,
ONE, ONE,
@ -1301,14 +1312,26 @@ func (n *Node) isGoConst() bool {
OSUB, OSUB,
OXOR, OXOR,
OIOTA, OIOTA,
OCOMPLEX,
OREAL, OREAL,
OIMAG: OIMAG:
if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) { if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) {
return true return true
} }
case OCONV: case OCOMPLEX:
if n.List.Len() == 0 && n.Left.isGoConst() && n.Right.isGoConst() {
return true
}
case OADDSTR:
for _, n1 := range n.List.Slice() {
if !n1.isGoConst() {
return false
}
}
return true
case OCONV, OCONVNOP:
if okforconst[n.Type.Etype] && n.Left.isGoConst() { if okforconst[n.Type.Etype] && n.Left.isGoConst() {
return true return true
} }

View file

@ -125,6 +125,9 @@ func declare(n *Node, ctxt Class) {
s.Def = asTypesNode(n) s.Def = asTypesNode(n)
n.Name.Vargen = int32(gen) n.Name.Vargen = int32(gen)
n.SetClass(ctxt) n.SetClass(ctxt)
if ctxt == PFUNC {
n.Sym.SetFunc(true)
}
autoexport(n, ctxt) autoexport(n, ctxt)
} }
@ -280,7 +283,7 @@ func oldname(s *types.Sym) *Node {
c = newname(s) c = newname(s)
c.SetClass(PAUTOHEAP) c.SetClass(PAUTOHEAP)
c.SetIsClosureVar(true) c.SetIsClosureVar(true)
c.SetIsddd(n.Isddd()) c.SetIsDDD(n.IsDDD())
c.Name.Defn = n c.Name.Defn = n
c.SetAddable(false) c.SetAddable(false)
@ -452,7 +455,7 @@ func funcarg(n *Node, ctxt Class) {
n.Right = newnamel(n.Pos, n.Sym) n.Right = newnamel(n.Pos, n.Sym)
n.Right.Name.Param.Ntype = n.Left n.Right.Name.Param.Ntype = n.Left
n.Right.SetIsddd(n.Isddd()) n.Right.SetIsDDD(n.IsDDD())
declare(n.Right, ctxt) declare(n.Right, ctxt)
vargen++ vargen++
@ -485,7 +488,7 @@ func funcarg2(f *types.Field, ctxt Class) {
n := newnamel(f.Pos, f.Sym) n := newnamel(f.Pos, f.Sym)
f.Nname = asTypesNode(n) f.Nname = asTypesNode(n)
n.Type = f.Type n.Type = f.Type
n.SetIsddd(f.Isddd()) n.SetIsDDD(f.IsDDD())
declare(n, ctxt) declare(n, ctxt)
} }
@ -625,7 +628,7 @@ func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
fields := make([]*types.Field, len(l)) fields := make([]*types.Field, len(l))
for i, n := range l { for i, n := range l {
f := structfield(n) f := structfield(n)
f.SetIsddd(n.Isddd()) f.SetIsDDD(n.IsDDD())
if n.Right != nil { if n.Right != nil {
n.Right.Type = f.Type n.Right.Type = f.Type
f.Nname = asTypesNode(n.Right) f.Nname = asTypesNode(n.Right)
@ -801,8 +804,12 @@ func origSym(s *types.Sym) *types.Sym {
// Method symbols can be used to distinguish the same method appearing // Method symbols can be used to distinguish the same method appearing
// in different method sets. For example, T.M and (*T).M have distinct // in different method sets. For example, T.M and (*T).M have distinct
// method symbols. // method symbols.
//
// The returned symbol will be marked as a function.
func methodSym(recv *types.Type, msym *types.Sym) *types.Sym { func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
return methodSymSuffix(recv, msym, "") sym := methodSymSuffix(recv, msym, "")
sym.SetFunc(true)
return sym
} }
// methodSymSuffix is like methodsym, but allows attaching a // methodSymSuffix is like methodsym, but allows attaching a

View file

@ -671,7 +671,7 @@ func (e *EscState) isSliceSelfAssign(dst, src *Node) bool {
// when we evaluate it for dst and for src. // when we evaluate it for dst and for src.
// dst is ONAME dereference. // dst is ONAME dereference.
if dst.Op != OIND && dst.Op != ODOTPTR || dst.Left.Op != ONAME { if dst.Op != ODEREF && dst.Op != ODOTPTR || dst.Left.Op != ONAME {
return false return false
} }
// src is a slice operation. // src is a slice operation.
@ -695,7 +695,7 @@ func (e *EscState) isSliceSelfAssign(dst, src *Node) bool {
return false return false
} }
// slice is applied to ONAME dereference. // slice is applied to ONAME dereference.
if src.Left.Op != OIND && src.Left.Op != ODOTPTR || src.Left.Left.Op != ONAME { if src.Left.Op != ODEREF && src.Left.Op != ODOTPTR || src.Left.Left.Op != ONAME {
return false return false
} }
// dst and src reference the same base ONAME. // dst and src reference the same base ONAME.
@ -757,8 +757,8 @@ func (e *EscState) mayAffectMemory(n *Node) bool {
return e.mayAffectMemory(n.Left) || e.mayAffectMemory(n.Right) return e.mayAffectMemory(n.Left) || e.mayAffectMemory(n.Right)
// Left group. // Left group.
case ODOT, ODOTPTR, OIND, OCONVNOP, OCONV, OLEN, OCAP, case ODOT, ODOTPTR, ODEREF, OCONVNOP, OCONV, OLEN, OCAP,
ONOT, OCOM, OPLUS, OMINUS, OALIGNOF, OOFFSETOF, OSIZEOF: ONOT, OBITNOT, OPLUS, ONEG, OALIGNOF, OOFFSETOF, OSIZEOF:
return e.mayAffectMemory(n.Left) return e.mayAffectMemory(n.Left)
default: default:
@ -935,7 +935,7 @@ opSwitch:
e.escassignSinkWhy(n, arg, "defer func arg") e.escassignSinkWhy(n, arg, "defer func arg")
} }
case OPROC: case OGO:
// go f(x) - f and x escape // go f(x) - f and x escape
e.escassignSinkWhy(n, n.Left.Left, "go func") e.escassignSinkWhy(n, n.Left.Left, "go func")
e.escassignSinkWhy(n, n.Left.Right, "go func ...") // ODDDARG for call e.escassignSinkWhy(n, n.Left.Right, "go func ...") // ODDDARG for call
@ -991,7 +991,7 @@ opSwitch:
e.escassignSinkWhy(n, n.Left, "panic") e.escassignSinkWhy(n, n.Left, "panic")
case OAPPEND: case OAPPEND:
if !n.Isddd() { if !n.IsDDD() {
for _, nn := range n.List.Slice()[1:] { for _, nn := range n.List.Slice()[1:] {
e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference
} }
@ -1072,7 +1072,7 @@ opSwitch:
a = nod(OADDR, a, nil) a = nod(OADDR, a, nil)
a.Pos = v.Pos a.Pos = v.Pos
e.nodeEscState(a).Loopdepth = e.loopdepth e.nodeEscState(a).Loopdepth = e.loopdepth
a = typecheck(a, Erv) a = typecheck(a, ctxExpr)
} }
e.escassignWhyWhere(n, a, "captured by a closure", n) e.escassignWhyWhere(n, a, "captured by a closure", n)
@ -1083,10 +1083,10 @@ opSwitch:
OMAKEMAP, OMAKEMAP,
OMAKESLICE, OMAKESLICE,
ONEW, ONEW,
OARRAYRUNESTR, ORUNES2STR,
OARRAYBYTESTR, OBYTES2STR,
OSTRARRAYRUNE, OSTR2RUNES,
OSTRARRAYBYTE, OSTR2BYTES,
ORUNESTR: ORUNESTR:
e.track(n) e.track(n)
@ -1223,7 +1223,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
dstwhy = "slice-element-equals" dstwhy = "slice-element-equals"
dst = &e.theSink // lose track of dereference dst = &e.theSink // lose track of dereference
case OIND: case ODEREF:
dstwhy = "star-equals" dstwhy = "star-equals"
dst = &e.theSink // lose track of dereference dst = &e.theSink // lose track of dereference
@ -1243,7 +1243,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
switch src.Op { switch src.Op {
case OADDR, // dst = &x case OADDR, // dst = &x
OIND, // dst = *x ODEREF, // dst = *x
ODOTPTR, // dst = (*x).f ODOTPTR, // dst = (*x).f
ONAME, ONAME,
ODDDARG, ODDDARG,
@ -1255,10 +1255,10 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
OMAKECHAN, OMAKECHAN,
OMAKEMAP, OMAKEMAP,
OMAKESLICE, OMAKESLICE,
OARRAYRUNESTR, ORUNES2STR,
OARRAYBYTESTR, OBYTES2STR,
OSTRARRAYRUNE, OSTR2RUNES,
OSTRARRAYBYTE, OSTR2BYTES,
OADDSTR, OADDSTR,
ONEW, ONEW,
OCALLPART, OCALLPART,
@ -1293,7 +1293,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
case OCONV, case OCONV,
OCONVNOP, OCONVNOP,
ODOTMETH, ODOTMETH,
// treat recv.meth as a value with recv in it, only happens in ODEFER and OPROC // treat recv.meth as a value with recv in it, only happens in ODEFER and OGO
// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here // iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
OSLICE, OSLICE,
OSLICE3, OSLICE3,
@ -1338,8 +1338,8 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
OAND, OAND,
OANDNOT, OANDNOT,
OPLUS, OPLUS,
OMINUS, ONEG,
OCOM: OBITNOT:
e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy)) e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
e.escassign(dst, src.Right, e.stepAssign(step, originalDst, src, dstwhy)) e.escassign(dst, src.Right, e.stepAssign(step, originalDst, src, dstwhy))
@ -1500,16 +1500,16 @@ func (e *EscState) escassignDereference(dst *Node, src *Node, step *EscStep) {
e.escassign(dst, e.addDereference(src), step) e.escassign(dst, e.addDereference(src), step)
} }
// addDereference constructs a suitable OIND note applied to src. // addDereference constructs a suitable ODEREF note applied to src.
// Because this is for purposes of escape accounting, not execution, // Because this is for purposes of escape accounting, not execution,
// some semantically dubious node combinations are (currently) possible. // some semantically dubious node combinations are (currently) possible.
func (e *EscState) addDereference(n *Node) *Node { func (e *EscState) addDereference(n *Node) *Node {
ind := nod(OIND, n, nil) ind := nod(ODEREF, n, nil)
e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth
ind.Pos = n.Pos ind.Pos = n.Pos
t := n.Type t := n.Type
if t.IsPtr() || t.IsSlice() { if t.IsPtr() || t.IsSlice() {
// This should model our own sloppy use of OIND to encode // This should model our own sloppy use of ODEREF to encode
// decreasing levels of indirection; i.e., "indirecting" a slice // decreasing levels of indirection; i.e., "indirecting" a slice
// yields the type of an element. // yields the type of an element.
t = t.Elem() t = t.Elem()
@ -1652,49 +1652,79 @@ func (e *EscState) esccall(call *Node, parent *Node) {
Fatalf("graph inconsistency") Fatalf("graph inconsistency")
} }
sawRcvr := false i := 0
for _, n := range fn.Name.Defn.Func.Dcl {
switch n.Class() {
case PPARAM:
if call.Op != OCALLFUNC && !sawRcvr {
e.escassignWhyWhere(n, call.Left.Left, "call receiver", call)
sawRcvr = true
continue
}
if len(args) == 0 {
continue
}
arg := args[0]
if n.Isddd() && !call.Isddd() {
// Introduce ODDDARG node to represent ... allocation.
arg = nod(ODDDARG, nil, nil)
arr := types.NewArray(n.Type.Elem(), int64(len(args)))
arg.Type = types.NewPtr(arr) // make pointer so it will be tracked
arg.Pos = call.Pos
e.track(arg)
call.Right = arg
}
e.escassignWhyWhere(n, arg, "arg to recursive call", call) // TODO this message needs help.
if arg == args[0] {
args = args[1:]
continue
}
// "..." arguments are untracked
for _, a := range args {
if Debug['m'] > 3 {
fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
}
e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call)
}
// No more PPARAM processing, but keep
// going for PPARAMOUT.
args = nil
case PPARAMOUT: // Receiver.
if call.Op != OCALLFUNC {
rf := fntype.Recv()
if rf.Sym != nil && !rf.Sym.IsBlank() {
n := fn.Name.Defn.Func.Dcl[0]
i++
if n.Class() != PPARAM {
Fatalf("esccall: not a parameter %+v", n)
}
e.escassignWhyWhere(n, call.Left.Left, "recursive call receiver", call)
}
}
// Parameters.
for _, param := range fntype.Params().FieldSlice() {
if param.Sym == nil || param.Sym.IsBlank() {
// Unnamed parameter is not listed in Func.Dcl.
// But we need to consume the arg.
if param.IsDDD() && !call.IsDDD() {
args = nil
} else {
args = args[1:]
}
continue
}
n := fn.Name.Defn.Func.Dcl[i]
i++
if n.Class() != PPARAM {
Fatalf("esccall: not a parameter %+v", n)
}
if len(args) == 0 {
continue
}
arg := args[0]
if n.IsDDD() && !call.IsDDD() {
// Introduce ODDDARG node to represent ... allocation.
arg = nod(ODDDARG, nil, nil)
arr := types.NewArray(n.Type.Elem(), int64(len(args)))
arg.Type = types.NewPtr(arr) // make pointer so it will be tracked
arg.Pos = call.Pos
e.track(arg)
call.Right = arg
}
e.escassignWhyWhere(n, arg, "arg to recursive call", call) // TODO this message needs help.
if arg == args[0] {
args = args[1:]
continue
}
// "..." arguments are untracked
for _, a := range args {
if Debug['m'] > 3 {
fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
}
e.escassignSinkWhyWhere(arg, a, "... arg to recursive call", call)
}
// ... arg consumes all remaining arguments
args = nil
}
// Results.
for _, n := range fn.Name.Defn.Func.Dcl[i:] {
if n.Class() == PPARAMOUT {
cE.Retval.Append(n) cE.Retval.Append(n)
} }
} }
// Sanity check: all arguments must be consumed.
if len(args) != 0 {
Fatalf("esccall not consumed all args %+v\n", call)
}
return return
} }
@ -1722,7 +1752,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
for i, param := range fntype.Params().FieldSlice() { for i, param := range fntype.Params().FieldSlice() {
note := param.Note note := param.Note
var arg *Node var arg *Node
if param.Isddd() && !call.Isddd() { if param.IsDDD() && !call.IsDDD() {
rest := args[i:] rest := args[i:]
if len(rest) == 0 { if len(rest) == 0 {
break break
@ -1754,7 +1784,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
} }
} }
if types.Haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC { if types.Haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OGO {
a := arg a := arg
for a.Op == OCONVNOP { for a.Op == OCONVNOP {
a = a.Left a = a.Left
@ -2057,10 +2087,10 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep,
case OMAKECHAN, case OMAKECHAN,
OMAKEMAP, OMAKEMAP,
OMAKESLICE, OMAKESLICE,
OARRAYRUNESTR, ORUNES2STR,
OARRAYBYTESTR, OBYTES2STR,
OSTRARRAYRUNE, OSTR2RUNES,
OSTRARRAYBYTE, OSTR2BYTES,
OADDSTR, OADDSTR,
OMAPLIT, OMAPLIT,
ONEW, ONEW,
@ -2100,7 +2130,7 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep,
e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "dot of pointer", step)) e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "dot of pointer", step))
case OINDEXMAP: case OINDEXMAP:
e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "map index", step)) e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "map index", step))
case OIND: case ODEREF:
e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "indirection", step)) e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "indirection", step))
// In this case a link went directly to a call, but should really go // In this case a link went directly to a call, but should really go
@ -2142,7 +2172,7 @@ func addrescapes(n *Node) {
default: default:
// Unexpected Op, probably due to a previous type error. Ignore. // Unexpected Op, probably due to a previous type error. Ignore.
case OIND, ODOTPTR: case ODEREF, ODOTPTR:
// Nothing to do. // Nothing to do.
case ONAME: case ONAME:
@ -2347,7 +2377,7 @@ func (e *EscState) esctag(fn *Node) {
f.Note = uintptrEscapesTag f.Note = uintptrEscapesTag
} }
if f.Isddd() && f.Type.Elem().Etype == TUINTPTR { if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR {
// final argument is ...uintptr. // final argument is ...uintptr.
if Debug['m'] != 0 { if Debug['m'] != 0 {
Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg)) Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg))

View file

@ -62,13 +62,6 @@ func autoexport(n *Node, ctxt Class) {
} }
} }
// methodbyname sorts types by symbol name.
type methodbyname []*types.Field
func (x methodbyname) Len() int { return len(x) }
func (x methodbyname) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x methodbyname) Less(i, j int) bool { return x[i].Sym.Name < x[j].Sym.Name }
func dumpexport(bout *bio.Writer) { func dumpexport(bout *bio.Writer) {
// The linker also looks for the $$ marker - use char after $$ to distinguish format. // The linker also looks for the $$ marker - use char after $$ to distinguish format.
exportf(bout, "\n$$B\n") // indicate binary export format exportf(bout, "\n$$B\n") // indicate binary export format
@ -140,6 +133,9 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t
n.Op = op n.Op = op
n.Pos = pos n.Pos = pos
n.SetClass(ctxt) n.SetClass(ctxt)
if ctxt == PFUNC {
n.Sym.SetFunc(true)
}
n.Type = t n.Type = t
return n return n
} }

View file

@ -159,7 +159,7 @@ var goopnames = []string{
OCASE: "case", OCASE: "case",
OCLOSE: "close", OCLOSE: "close",
OCOMPLEX: "complex", OCOMPLEX: "complex",
OCOM: "^", OBITNOT: "^",
OCONTINUE: "continue", OCONTINUE: "continue",
OCOPY: "copy", OCOPY: "copy",
ODELETE: "delete", ODELETE: "delete",
@ -174,13 +174,14 @@ var goopnames = []string{
OGT: ">", OGT: ">",
OIF: "if", OIF: "if",
OIMAG: "imag", OIMAG: "imag",
OIND: "*", OINLMARK: "inlmark",
ODEREF: "*",
OLEN: "len", OLEN: "len",
OLE: "<=", OLE: "<=",
OLSH: "<<", OLSH: "<<",
OLT: "<", OLT: "<",
OMAKE: "make", OMAKE: "make",
OMINUS: "-", ONEG: "-",
OMOD: "%", OMOD: "%",
OMUL: "*", OMUL: "*",
ONEW: "new", ONEW: "new",
@ -464,8 +465,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
fmt.Fprintf(s, " tc(%d)", n.Typecheck()) fmt.Fprintf(s, " tc(%d)", n.Typecheck())
} }
if n.Isddd() { if n.IsDDD() {
fmt.Fprintf(s, " isddd(%v)", n.Isddd()) fmt.Fprintf(s, " isddd(%v)", n.IsDDD())
} }
if n.Implicit() { if n.Implicit() {
@ -942,7 +943,10 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
case ORETJMP: case ORETJMP:
mode.Fprintf(s, "retjmp %v", n.Sym) mode.Fprintf(s, "retjmp %v", n.Sym)
case OPROC: case OINLMARK:
mode.Fprintf(s, "inlmark %d", n.Xoffset)
case OGO:
mode.Fprintf(s, "go %v", n.Left) mode.Fprintf(s, "go %v", n.Left)
case ODEFER: case ODEFER:
@ -1064,92 +1068,92 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
} }
var opprec = []int{ var opprec = []int{
OALIGNOF: 8, OALIGNOF: 8,
OAPPEND: 8, OAPPEND: 8,
OARRAYBYTESTR: 8, OBYTES2STR: 8,
OARRAYLIT: 8, OARRAYLIT: 8,
OSLICELIT: 8, OSLICELIT: 8,
OARRAYRUNESTR: 8, ORUNES2STR: 8,
OCALLFUNC: 8, OCALLFUNC: 8,
OCALLINTER: 8, OCALLINTER: 8,
OCALLMETH: 8, OCALLMETH: 8,
OCALL: 8, OCALL: 8,
OCAP: 8, OCAP: 8,
OCLOSE: 8, OCLOSE: 8,
OCONVIFACE: 8, OCONVIFACE: 8,
OCONVNOP: 8, OCONVNOP: 8,
OCONV: 8, OCONV: 8,
OCOPY: 8, OCOPY: 8,
ODELETE: 8, ODELETE: 8,
OGETG: 8, OGETG: 8,
OLEN: 8, OLEN: 8,
OLITERAL: 8, OLITERAL: 8,
OMAKESLICE: 8, OMAKESLICE: 8,
OMAKE: 8, OMAKE: 8,
OMAPLIT: 8, OMAPLIT: 8,
ONAME: 8, ONAME: 8,
ONEW: 8, ONEW: 8,
ONONAME: 8, ONONAME: 8,
OOFFSETOF: 8, OOFFSETOF: 8,
OPACK: 8, OPACK: 8,
OPANIC: 8, OPANIC: 8,
OPAREN: 8, OPAREN: 8,
OPRINTN: 8, OPRINTN: 8,
OPRINT: 8, OPRINT: 8,
ORUNESTR: 8, ORUNESTR: 8,
OSIZEOF: 8, OSIZEOF: 8,
OSTRARRAYBYTE: 8, OSTR2BYTES: 8,
OSTRARRAYRUNE: 8, OSTR2RUNES: 8,
OSTRUCTLIT: 8, OSTRUCTLIT: 8,
OTARRAY: 8, OTARRAY: 8,
OTCHAN: 8, OTCHAN: 8,
OTFUNC: 8, OTFUNC: 8,
OTINTER: 8, OTINTER: 8,
OTMAP: 8, OTMAP: 8,
OTSTRUCT: 8, OTSTRUCT: 8,
OINDEXMAP: 8, OINDEXMAP: 8,
OINDEX: 8, OINDEX: 8,
OSLICE: 8, OSLICE: 8,
OSLICESTR: 8, OSLICESTR: 8,
OSLICEARR: 8, OSLICEARR: 8,
OSLICE3: 8, OSLICE3: 8,
OSLICE3ARR: 8, OSLICE3ARR: 8,
OSLICEHEADER: 8, OSLICEHEADER: 8,
ODOTINTER: 8, ODOTINTER: 8,
ODOTMETH: 8, ODOTMETH: 8,
ODOTPTR: 8, ODOTPTR: 8,
ODOTTYPE2: 8, ODOTTYPE2: 8,
ODOTTYPE: 8, ODOTTYPE: 8,
ODOT: 8, ODOT: 8,
OXDOT: 8, OXDOT: 8,
OCALLPART: 8, OCALLPART: 8,
OPLUS: 7, OPLUS: 7,
ONOT: 7, ONOT: 7,
OCOM: 7, OBITNOT: 7,
OMINUS: 7, ONEG: 7,
OADDR: 7, OADDR: 7,
OIND: 7, ODEREF: 7,
ORECV: 7, ORECV: 7,
OMUL: 6, OMUL: 6,
ODIV: 6, ODIV: 6,
OMOD: 6, OMOD: 6,
OLSH: 6, OLSH: 6,
ORSH: 6, ORSH: 6,
OAND: 6, OAND: 6,
OANDNOT: 6, OANDNOT: 6,
OADD: 5, OADD: 5,
OSUB: 5, OSUB: 5,
OOR: 5, OOR: 5,
OXOR: 5, OXOR: 5,
OEQ: 4, OEQ: 4,
OLT: 4, OLT: 4,
OLE: 4, OLE: 4,
OGE: 4, OGE: 4,
OGT: 4, OGT: 4,
ONE: 4, ONE: 4,
OSEND: 3, OSEND: 3,
OANDAND: 2, OANDAND: 2,
OOROR: 1, OOROR: 1,
// Statements handled by stmtfmt // Statements handled by stmtfmt
OAS: -1, OAS: -1,
@ -1172,7 +1176,7 @@ var opprec = []int{
OGOTO: -1, OGOTO: -1,
OIF: -1, OIF: -1,
OLABEL: -1, OLABEL: -1,
OPROC: -1, OGO: -1,
ORANGE: -1, ORANGE: -1,
ORETURN: -1, ORETURN: -1,
OSELECT: -1, OSELECT: -1,
@ -1183,7 +1187,7 @@ var opprec = []int{
} }
func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
for n != nil && n.Implicit() && (n.Op == OIND || n.Op == OADDR) { for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) {
n = n.Left n = n.Left
} }
@ -1400,16 +1404,23 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
} }
mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second()) mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second())
case OCOPY, OCOMPLEX: case OCOPY:
mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right) mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
case OCOMPLEX:
if n.List.Len() == 1 {
mode.Fprintf(s, "%#v(%v)", n.Op, n.List.First())
} else {
mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
}
case OCONV, case OCONV,
OCONVIFACE, OCONVIFACE,
OCONVNOP, OCONVNOP,
OARRAYBYTESTR, OBYTES2STR,
OARRAYRUNESTR, ORUNES2STR,
OSTRARRAYBYTE, OSTR2BYTES,
OSTRARRAYRUNE, OSTR2RUNES,
ORUNESTR: ORUNESTR:
if n.Type == nil || n.Type.Sym == nil { if n.Type == nil || n.Type.Sym == nil {
mode.Fprintf(s, "(%v)", n.Type) mode.Fprintf(s, "(%v)", n.Type)
@ -1442,7 +1453,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
mode.Fprintf(s, "%#v(%v)", n.Op, n.Left) mode.Fprintf(s, "%#v(%v)", n.Op, n.Left)
return return
} }
if n.Isddd() { if n.IsDDD() {
mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List) mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
return return
} }
@ -1450,7 +1461,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG: case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
n.Left.exprfmt(s, nprec, mode) n.Left.exprfmt(s, nprec, mode)
if n.Isddd() { if n.IsDDD() {
mode.Fprintf(s, "(%.v...)", n.List) mode.Fprintf(s, "(%.v...)", n.List)
return return
} }
@ -1471,7 +1482,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
} }
mode.Fprintf(s, "make(%v)", n.Type) mode.Fprintf(s, "make(%v)", n.Type)
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV: case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
// Unary // Unary
mode.Fprintf(s, "%#v", n.Op) mode.Fprintf(s, "%#v", n.Op)
if n.Left != nil && n.Left.Op == n.Op { if n.Left != nil && n.Left.Op == n.Op {
@ -1694,7 +1705,7 @@ func fldconv(f *types.Field, flag FmtFlag, mode fmtMode, depth int, funarg types
} }
var typ string var typ string
if f.Isddd() { if f.IsDDD() {
var et *types.Type var et *types.Type
if f.Type != nil { if f.Type != nil {
et = f.Type.Elem() et = f.Type.Elem()
@ -1742,7 +1753,11 @@ func tconv(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
return t.FieldType(0).String() + "," + t.FieldType(1).String() return t.FieldType(0).String() + "," + t.FieldType(1).String()
} }
if depth > 100 { // Avoid endless recursion by setting an upper limit. This also
// limits the depths of valid composite types, but they are likely
// artificially created.
// TODO(gri) should have proper cycle detection here, eventually (issue #29312)
if depth > 250 {
return "<...>" return "<...>"
} }

View file

@ -11,7 +11,18 @@ import (
"strconv" "strconv"
) )
// sysfunc looks up Go function name in package runtime. This function
// must follow the internal calling convention.
func sysfunc(name string) *obj.LSym { func sysfunc(name string) *obj.LSym {
s := Runtimepkg.Lookup(name)
s.SetFunc(true)
return s.Linksym()
}
// sysvar looks up a variable (or assembly function) name in package
// runtime. If this is a function, it may have a special calling
// convention.
func sysvar(name string) *obj.LSym {
return Runtimepkg.Lookup(name).Linksym() return Runtimepkg.Lookup(name).Linksym()
} }

View file

@ -8,7 +8,6 @@ import (
"bytes" "bytes"
"internal/testenv" "internal/testenv"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -24,7 +23,7 @@ func TestScanfRemoval(t *testing.T) {
// Make a directory to work in. // Make a directory to work in.
dir, err := ioutil.TempDir("", "issue6853a-") dir, err := ioutil.TempDir("", "issue6853a-")
if err != nil { if err != nil {
log.Fatalf("could not create directory: %v", err) t.Fatalf("could not create directory: %v", err)
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
@ -32,7 +31,7 @@ func TestScanfRemoval(t *testing.T) {
src := filepath.Join(dir, "test.go") src := filepath.Join(dir, "test.go")
f, err := os.Create(src) f, err := os.Create(src)
if err != nil { if err != nil {
log.Fatalf("could not create source file: %v", err) t.Fatalf("could not create source file: %v", err)
} }
f.Write([]byte(` f.Write([]byte(`
package main package main
@ -50,17 +49,17 @@ func main() {
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src) cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Fatalf("could not build target: %v", err) t.Fatalf("could not build target: %v", err)
} }
// Check destination to see if scanf code was included. // Check destination to see if scanf code was included.
cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst) cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
out, err = cmd.CombinedOutput() out, err = cmd.CombinedOutput()
if err != nil { if err != nil {
log.Fatalf("could not read target: %v", err) t.Fatalf("could not read target: %v", err)
} }
if bytes.Contains(out, []byte("scanInt")) { if bytes.Contains(out, []byte("scanInt")) {
log.Fatalf("scanf code not removed from helloworld") t.Fatalf("scanf code not removed from helloworld")
} }
} }
@ -71,7 +70,7 @@ func TestDashS(t *testing.T) {
// Make a directory to work in. // Make a directory to work in.
dir, err := ioutil.TempDir("", "issue14515-") dir, err := ioutil.TempDir("", "issue14515-")
if err != nil { if err != nil {
log.Fatalf("could not create directory: %v", err) t.Fatalf("could not create directory: %v", err)
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
@ -79,7 +78,7 @@ func TestDashS(t *testing.T) {
src := filepath.Join(dir, "test.go") src := filepath.Join(dir, "test.go")
f, err := os.Create(src) f, err := os.Create(src)
if err != nil { if err != nil {
log.Fatalf("could not create source file: %v", err) t.Fatalf("could not create source file: %v", err)
} }
f.Write([]byte(` f.Write([]byte(`
package main package main
@ -94,7 +93,7 @@ func main() {
cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src) cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Fatalf("could not build target: %v", err) t.Fatalf("could not build target: %v", err)
} }
patterns := []string{ patterns := []string{

View file

@ -257,7 +257,7 @@ type Arch struct {
PadFrame func(int64) int64 PadFrame func(int64) int64
ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
Ginsnop func(*Progs) Ginsnop func(*Progs) *obj.Prog
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags. // SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
SSAMarkMoves func(*SSAGenState, *ssa.Block) SSAMarkMoves func(*SSAGenState, *ssa.Block)
@ -300,14 +300,15 @@ var (
panicdottypeI, panicdottypeI,
panicindex, panicindex,
panicnildottype, panicnildottype,
panicoverflow,
panicslice, panicslice,
raceread, raceread,
racereadrange, racereadrange,
racewrite, racewrite,
racewriterange, racewriterange,
supportPopcnt, x86HasPOPCNT,
supportSSE41, x86HasSSE41,
arm64SupportAtomics, arm64HasATOMICS,
typedmemclr, typedmemclr,
typedmemmove, typedmemmove,
Udiv, Udiv,

View file

@ -187,7 +187,13 @@ func (pp *Progs) settext(fn *Node) {
ptxt.From.Sym = fn.Func.lsym ptxt.From.Sym = fn.Func.lsym
} }
func (f *Func) initLSym() { // initLSym defines f's obj.LSym and initializes it based on the
// properties of f. This includes setting the symbol flags and ABI and
// creating and initializing related DWARF symbols.
//
// initLSym must be called exactly once per function and must be
// called for both functions with bodies and functions without bodies.
func (f *Func) initLSym(hasBody bool) {
if f.lsym != nil { if f.lsym != nil {
Fatalf("Func.initLSym called twice") Fatalf("Func.initLSym called twice")
} }
@ -197,6 +203,61 @@ func (f *Func) initLSym() {
if f.Pragma&Systemstack != 0 { if f.Pragma&Systemstack != 0 {
f.lsym.Set(obj.AttrCFunc, true) f.lsym.Set(obj.AttrCFunc, true)
} }
var aliasABI obj.ABI
needABIAlias := false
if abi, ok := symabiDefs[f.lsym.Name]; ok && abi == obj.ABI0 {
// Symbol is defined as ABI0. Create an
// Internal -> ABI0 wrapper.
f.lsym.SetABI(obj.ABI0)
needABIAlias, aliasABI = true, obj.ABIInternal
} else {
// No ABI override. Check that the symbol is
// using the expected ABI.
want := obj.ABIInternal
if f.lsym.ABI() != want {
Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
}
}
if abi, ok := symabiRefs[f.lsym.Name]; ok && abi == obj.ABI0 {
// Symbol is referenced as ABI0. Create an
// ABI0 -> Internal wrapper if necessary.
if f.lsym.ABI() != obj.ABI0 {
needABIAlias, aliasABI = true, obj.ABI0
}
}
if !needABIAlias && allABIs {
// The compiler was asked to produce ABI
// wrappers for everything.
switch f.lsym.ABI() {
case obj.ABI0:
needABIAlias, aliasABI = true, obj.ABIInternal
case obj.ABIInternal:
needABIAlias, aliasABI = true, obj.ABI0
}
}
if needABIAlias {
// These LSyms have the same name as the
// native function, so we create them directly
// rather than looking them up. The uniqueness
// of f.lsym ensures uniqueness of asym.
asym := &obj.LSym{
Name: f.lsym.Name,
Type: objabi.SABIALIAS,
R: []obj.Reloc{{Sym: f.lsym}}, // 0 size, so "informational"
}
asym.SetABI(aliasABI)
asym.Set(obj.AttrDuplicateOK, true)
Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
}
}
if !hasBody {
// For body-less functions, we only create the LSym.
return
} }
var flag int var flag int

View file

@ -439,7 +439,7 @@ func (p *iexporter) doDecl(n *Node) {
case OLITERAL: case OLITERAL:
// Constant. // Constant.
n = typecheck(n, Erv) n = typecheck(n, ctxExpr)
w.tag('C') w.tag('C')
w.pos(n.Pos) w.pos(n.Pos)
w.value(n.Type, n.Val()) w.value(n.Type, n.Val())
@ -707,7 +707,7 @@ func (w *exportWriter) signature(t *types.Type) {
w.paramList(t.Params().FieldSlice()) w.paramList(t.Params().FieldSlice())
w.paramList(t.Results().FieldSlice()) w.paramList(t.Results().FieldSlice())
if n := t.Params().NumFields(); n > 0 { if n := t.Params().NumFields(); n > 0 {
w.bool(t.Params().Field(n - 1).Isddd()) w.bool(t.Params().Field(n - 1).IsDDD())
} }
} }
@ -1047,7 +1047,7 @@ func (w *exportWriter) stmt(n *Node) {
// case ORETJMP: // case ORETJMP:
// unreachable - generated by compiler for trampolin routines // unreachable - generated by compiler for trampolin routines
case OPROC, ODEFER: case OGO, ODEFER:
w.op(op) w.op(op)
w.pos(n.Pos) w.pos(n.Pos)
w.expr(n.Left) w.expr(n.Left)
@ -1127,7 +1127,7 @@ func (w *exportWriter) expr(n *Node) {
// } // }
// from exprfmt (fmt.go) // from exprfmt (fmt.go)
for n.Op == OPAREN || n.Implicit() && (n.Op == OIND || n.Op == OADDR || n.Op == ODOT || n.Op == ODOTPTR) { for n.Op == OPAREN || n.Implicit() && (n.Op == ODEREF || n.Op == OADDR || n.Op == ODOT || n.Op == ODOTPTR) {
n = n.Left n = n.Left
} }
@ -1252,7 +1252,7 @@ func (w *exportWriter) expr(n *Node) {
w.expr(n.Right) w.expr(n.Right)
w.op(OEND) w.op(OEND)
case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR: case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
w.op(OCONV) w.op(OCONV)
w.pos(n.Pos) w.pos(n.Pos)
w.expr(n.Left) w.expr(n.Left)
@ -1269,8 +1269,8 @@ func (w *exportWriter) expr(n *Node) {
} }
// only append() calls may contain '...' arguments // only append() calls may contain '...' arguments
if op == OAPPEND { if op == OAPPEND {
w.bool(n.Isddd()) w.bool(n.IsDDD())
} else if n.Isddd() { } else if n.IsDDD() {
Fatalf("exporter: unexpected '...' with %v call", op) Fatalf("exporter: unexpected '...' with %v call", op)
} }
@ -1279,7 +1279,7 @@ func (w *exportWriter) expr(n *Node) {
w.pos(n.Pos) w.pos(n.Pos)
w.expr(n.Left) w.expr(n.Left)
w.exprList(n.List) w.exprList(n.List)
w.bool(n.Isddd()) w.bool(n.IsDDD())
case OMAKEMAP, OMAKECHAN, OMAKESLICE: case OMAKEMAP, OMAKECHAN, OMAKESLICE:
w.op(op) // must keep separate from OMAKE for importer w.op(op) // must keep separate from OMAKE for importer
@ -1301,7 +1301,7 @@ func (w *exportWriter) expr(n *Node) {
} }
// unary expressions // unary expressions
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV: case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
w.op(op) w.op(op)
w.pos(n.Pos) w.pos(n.Pos)
w.expr(n.Left) w.expr(n.Left)
@ -1325,7 +1325,7 @@ func (w *exportWriter) expr(n *Node) {
default: default:
Fatalf("cannot export %v (%d) node\n"+ Fatalf("cannot export %v (%d) node\n"+
"==> please file an issue and assign to gri@\n", n.Op, int(n.Op)) "\t==> please file an issue and assign to gri@", n.Op, int(n.Op))
} }
} }

View file

@ -334,6 +334,7 @@ func (r *importReader) doDecl(n *Node) {
m := newfuncnamel(mpos, methodSym(recv.Type, msym)) m := newfuncnamel(mpos, methodSym(recv.Type, msym))
m.Type = mtyp m.Type = mtyp
m.SetClass(PFUNC) m.SetClass(PFUNC)
// methodSym already marked m.Sym as a function.
// (comment from parser.go) // (comment from parser.go)
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
@ -607,7 +608,7 @@ func (r *importReader) signature(recv *types.Field) *types.Type {
params := r.paramList() params := r.paramList()
results := r.paramList() results := r.paramList()
if n := len(params); n > 0 { if n := len(params); n > 0 {
params[n-1].SetIsddd(r.bool()) params[n-1].SetIsDDD(r.bool())
} }
t := functypefield(recv, params, results) t := functypefield(recv, params, results)
t.SetPkg(r.currPkg) t.SetPkg(r.currPkg)
@ -819,7 +820,7 @@ func (r *importReader) node() *Node {
if !r.bool() /* !implicit, i.e. '&' operator */ { if !r.bool() /* !implicit, i.e. '&' operator */ {
if n.Op == OCOMPLIT { if n.Op == OCOMPLIT {
// Special case for &T{...}: turn into (*T){...}. // Special case for &T{...}: turn into (*T){...}.
n.Right = nodl(pos, OIND, n.Right, nil) n.Right = nodl(pos, ODEREF, n.Right, nil)
n.Right.SetImplicit(true) n.Right.SetImplicit(true)
} else { } else {
n = nodl(pos, OADDR, n, nil) n = nodl(pos, OADDR, n, nil)
@ -886,7 +887,7 @@ func (r *importReader) node() *Node {
n.SetSliceBounds(low, high, max) n.SetSliceBounds(low, high, max)
return n return n
// case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR: // case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
// unreachable - mapped to OCONV case below by exporter // unreachable - mapped to OCONV case below by exporter
case OCONV: case OCONV:
@ -898,7 +899,7 @@ func (r *importReader) node() *Node {
n := npos(r.pos(), builtinCall(op)) n := npos(r.pos(), builtinCall(op))
n.List.Set(r.exprList()) n.List.Set(r.exprList())
if op == OAPPEND { if op == OAPPEND {
n.SetIsddd(r.bool()) n.SetIsDDD(r.bool())
} }
return n return n
@ -908,7 +909,7 @@ func (r *importReader) node() *Node {
case OCALL: case OCALL:
n := nodl(r.pos(), OCALL, r.expr(), nil) n := nodl(r.pos(), OCALL, r.expr(), nil)
n.List.Set(r.exprList()) n.List.Set(r.exprList())
n.SetIsddd(r.bool()) n.SetIsDDD(r.bool())
return n return n
case OMAKEMAP, OMAKECHAN, OMAKESLICE: case OMAKEMAP, OMAKECHAN, OMAKESLICE:
@ -918,7 +919,7 @@ func (r *importReader) node() *Node {
return n return n
// unary expressions // unary expressions
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV: case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
return nodl(r.pos(), op, r.expr(), nil) return nodl(r.pos(), op, r.expr(), nil)
// binary expressions // binary expressions
@ -981,7 +982,7 @@ func (r *importReader) node() *Node {
// case ORETJMP: // case ORETJMP:
// unreachable - generated by compiler for trampolin routines (not exported) // unreachable - generated by compiler for trampolin routines (not exported)
case OPROC, ODEFER: case OGO, ODEFER:
return nodl(r.pos(), op, r.expr(), nil) return nodl(r.pos(), op, r.expr(), nil)
case OIF: case OIF:
@ -1052,7 +1053,7 @@ func (r *importReader) node() *Node {
default: default:
Fatalf("cannot import %v (%d) node\n"+ Fatalf("cannot import %v (%d) node\n"+
"==> please file an issue and assign to gri@\n", op, int(op)) "\t==> please file an issue and assign to gri@", op, int(op))
panic("unreachable") // satisfy compiler panic("unreachable") // satisfy compiler
} }
} }

View file

@ -57,6 +57,9 @@ func anyinit(n []*Node) bool {
// fninit hand-crafts package initialization code. // fninit hand-crafts package initialization code.
// //
// func init.ializers() { (0)
// <init stmts>
// }
// var initdone· uint8 (1) // var initdone· uint8 (1)
// func init() { (2) // func init() { (2)
// if initdone· > 1 { (3) // if initdone· > 1 { (3)
@ -68,7 +71,7 @@ func anyinit(n []*Node) bool {
// initdone· = 1 (5) // initdone· = 1 (5)
// // over all matching imported symbols // // over all matching imported symbols
// <pkg>.init() (6) // <pkg>.init() (6)
// { <init stmts> } (7) // init.ializers() (7)
// init.<n>() // if any (8) // init.<n>() // if any (8)
// initdone· = 2 (9) // initdone· = 2 (9)
// return (10) // return (10)
@ -80,6 +83,27 @@ func fninit(n []*Node) {
return return
} }
// (0)
// Make a function that contains all the initialization statements.
// This is a separate function because we want it to appear in
// stack traces, where the init function itself does not.
var initializers *types.Sym
if len(nf) > 0 {
lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
initializers = lookup("init.ializers")
disableExport(initializers)
fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
fn.Nbody.Set(nf)
funcbody()
fn = typecheck(fn, ctxStmt)
Curfn = fn
typecheckslice(nf, ctxStmt)
Curfn = nil
funccompile(fn)
lineno = autogeneratedPos
}
var r []*Node var r []*Node
// (1) // (1)
@ -130,7 +154,11 @@ func fninit(n []*Node) {
} }
// (7) // (7)
r = append(r, nf...) if initializers != nil {
n := newname(initializers)
addvar(n, functype(nil, nil, nil), PFUNC)
r = append(r, nod(OCALL, n, nil))
}
// (8) // (8)
@ -166,7 +194,7 @@ func fninit(n []*Node) {
rhs := asNode(s.Def) rhs := asNode(s.Def)
rhs.checkInitFuncSignature() rhs.checkInitFuncSignature()
as := nod(OAS, lhs, rhs) as := nod(OAS, lhs, rhs)
as = typecheck(as, Etop) as = typecheck(as, ctxStmt)
genAsStatic(as) genAsStatic(as)
} }
@ -187,7 +215,7 @@ func fninit(n []*Node) {
loop.Nbody.Set1(body) loop.Nbody.Set1(body)
loop.Ninit.Set1(zero) loop.Ninit.Set1(zero)
loop = typecheck(loop, Etop) loop = typecheck(loop, ctxStmt)
r = append(r, loop) r = append(r, loop)
} }
@ -206,8 +234,8 @@ func fninit(n []*Node) {
funcbody() funcbody()
Curfn = fn Curfn = fn
fn = typecheck(fn, Etop) fn = typecheck(fn, ctxStmt)
typecheckslice(r, Etop) typecheckslice(r, ctxStmt)
Curfn = nil Curfn = nil
funccompile(fn) funccompile(fn)
} }

View file

@ -39,7 +39,7 @@ const (
inlineMaxBudget = 80 inlineMaxBudget = 80
inlineExtraAppendCost = 0 inlineExtraAppendCost = 0
// default is to inline if there's at most one call. -l=4 overrides this by using 1 instead. // default is to inline if there's at most one call. -l=4 overrides this by using 1 instead.
inlineExtraCallCost = inlineMaxBudget * 3 / 4 inlineExtraCallCost = 57 // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742
inlineExtraPanicCost = 1 // do not penalize inlining panics. inlineExtraPanicCost = 1 // do not penalize inlining panics.
inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help. inlineExtraThrowCost = inlineMaxBudget // with current (2018-05/1.11) code, inlining runtime.throw does not help.
@ -90,7 +90,7 @@ func typecheckinl(fn *Node) {
savefn := Curfn savefn := Curfn
Curfn = fn Curfn = fn
typecheckslice(fn.Func.Inl.Body, Etop) typecheckslice(fn.Func.Inl.Body, ctxStmt)
Curfn = savefn Curfn = savefn
// During typechecking, declarations are added to // During typechecking, declarations are added to
@ -377,7 +377,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
OFORUNTIL, OFORUNTIL,
OSELECT, OSELECT,
OTYPESW, OTYPESW,
OPROC, OGO,
ODEFER, ODEFER,
ODCLTYPE, // can't print yet ODCLTYPE, // can't print yet
OBREAK, OBREAK,
@ -552,7 +552,7 @@ func inlnode(n *Node, maxCost int32) *Node {
switch n.Op { switch n.Op {
// inhibit inlining of their argument // inhibit inlining of their argument
case ODEFER, OPROC: case ODEFER, OGO:
switch n.Left.Op { switch n.Left.Op {
case OCALLFUNC, OCALLMETH: case OCALLFUNC, OCALLMETH:
n.Left.SetNoInline(true) n.Left.SetNoInline(true)
@ -620,7 +620,7 @@ func inlnode(n *Node, maxCost int32) *Node {
n.Rlist.Set(inlconv2list(n.Rlist.First())) n.Rlist.Set(inlconv2list(n.Rlist.First()))
n.Op = OAS2 n.Op = OAS2
n.SetTypecheck(0) n.SetTypecheck(0)
n = typecheck(n, Etop) n = typecheck(n, ctxStmt)
} else { } else {
s := n.Rlist.Slice() s := n.Rlist.Slice()
for i1, n1 := range s { for i1, n1 := range s {
@ -815,7 +815,7 @@ func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node {
return inlvar return inlvar
} }
return typecheck(nblank, Erv|Easgn) return typecheck(nblank, ctxExpr|ctxAssign)
} }
var inlgen int var inlgen int
@ -897,21 +897,21 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
} }
if v.Name.Byval() { if v.Name.Byval() {
iv := typecheck(inlvar(v), Erv) iv := typecheck(inlvar(v), ctxExpr)
ninit.Append(nod(ODCL, iv, nil)) ninit.Append(nod(ODCL, iv, nil))
ninit.Append(typecheck(nod(OAS, iv, o), Etop)) ninit.Append(typecheck(nod(OAS, iv, o), ctxStmt))
inlvars[v] = iv inlvars[v] = iv
} else { } else {
addr := newname(lookup("&" + v.Sym.Name)) addr := newname(lookup("&" + v.Sym.Name))
addr.Type = types.NewPtr(v.Type) addr.Type = types.NewPtr(v.Type)
ia := typecheck(inlvar(addr), Erv) ia := typecheck(inlvar(addr), ctxExpr)
ninit.Append(nod(ODCL, ia, nil)) ninit.Append(nod(ODCL, ia, nil))
ninit.Append(typecheck(nod(OAS, ia, nod(OADDR, o, nil)), Etop)) ninit.Append(typecheck(nod(OAS, ia, nod(OADDR, o, nil)), ctxStmt))
inlvars[addr] = ia inlvars[addr] = ia
// When capturing by reference, all occurrence of the captured var // When capturing by reference, all occurrence of the captured var
// must be substituted with dereference of the temporary address // must be substituted with dereference of the temporary address
inlvars[v] = typecheck(nod(OIND, ia, nil), Erv) inlvars[v] = typecheck(nod(ODEREF, ia, nil), ctxExpr)
} }
} }
} }
@ -927,7 +927,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
if ln.isParamStackCopy() { // ignore the on-stack copy of a parameter that moved to the heap if ln.isParamStackCopy() { // ignore the on-stack copy of a parameter that moved to the heap
continue continue
} }
inlvars[ln] = typecheck(inlvar(ln), Erv) inlvars[ln] = typecheck(inlvar(ln), ctxExpr)
if ln.Class() == PPARAM || ln.Name.Param.Stackcopy != nil && ln.Name.Param.Stackcopy.Class() == PPARAM { if ln.Class() == PPARAM || ln.Name.Param.Stackcopy != nil && ln.Name.Param.Stackcopy.Class() == PPARAM {
ninit.Append(nod(ODCL, inlvars[ln], nil)) ninit.Append(nod(ODCL, inlvars[ln], nil))
} }
@ -950,7 +950,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
mpos := t.Pos mpos := t.Pos
if n := asNode(t.Nname); n != nil && !n.isBlank() { if n := asNode(t.Nname); n != nil && !n.isBlank() {
m = inlvar(n) m = inlvar(n)
m = typecheck(m, Erv) m = typecheck(m, ctxExpr)
inlvars[n] = m inlvars[n] = m
} else { } else {
// anonymous return values, synthesize names for use in assignment that replaces return // anonymous return values, synthesize names for use in assignment that replaces return
@ -990,7 +990,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
Fatalf("method call without receiver: %+v", n) Fatalf("method call without receiver: %+v", n)
} }
ras := nod(OAS, tinlvar(rcv, inlvars), n.Left.Left) ras := nod(OAS, tinlvar(rcv, inlvars), n.Left.Left)
ras = typecheck(ras, Etop) ras = typecheck(ras, ctxStmt)
ninit.Append(ras) ninit.Append(ras)
} else { } else {
// For T.M(...), add the receiver parameter to // For T.M(...), add the receiver parameter to
@ -1007,7 +1007,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
// For ordinary parameters or variadic parameters in // For ordinary parameters or variadic parameters in
// dotted calls, just add the variable to the // dotted calls, just add the variable to the
// assignment list, and we're done. // assignment list, and we're done.
if !param.Isddd() || n.Isddd() { if !param.IsDDD() || n.IsDDD() {
as.List.Append(tinlvar(param, inlvars)) as.List.Append(tinlvar(param, inlvars))
continue continue
} }
@ -1037,19 +1037,19 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
} }
if as.Rlist.Len() != 0 { if as.Rlist.Len() != 0 {
as = typecheck(as, Etop) as = typecheck(as, ctxStmt)
ninit.Append(as) ninit.Append(as)
} }
if vas != nil { if vas != nil {
vas = typecheck(vas, Etop) vas = typecheck(vas, ctxStmt)
ninit.Append(vas) ninit.Append(vas)
} }
// Zero the return parameters. // Zero the return parameters.
for _, n := range retvars { for _, n := range retvars {
ras := nod(OAS, n, nil) ras := nod(OAS, n, nil)
ras = typecheck(ras, Etop) ras = typecheck(ras, ctxStmt)
ninit.Append(ras) ninit.Append(ras)
} }
@ -1063,6 +1063,15 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
} }
newIndex := Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym()) newIndex := Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym())
// Add a inline mark just before the inlined body.
// This mark is inline in the code so that it's a reasonable spot
// to put a breakpoint. Not sure if that's really necessary or not
// (in which case it could go at the end of the function instead).
inlMark := nod(OINLMARK, nil, nil)
inlMark.Pos = n.Pos
inlMark.Xoffset = int64(newIndex)
ninit.Append(inlMark)
if genDwarfInline > 0 { if genDwarfInline > 0 {
if !fn.Sym.Linksym().WasInlined() { if !fn.Sym.Linksym().WasInlined() {
Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn) Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn)
@ -1083,7 +1092,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
lab := nodSym(OLABEL, nil, retlabel) lab := nodSym(OLABEL, nil, retlabel)
body = append(body, lab) body = append(body, lab)
typecheckslice(body, Etop) typecheckslice(body, ctxStmt)
if genDwarfInline > 0 { if genDwarfInline > 0 {
for _, v := range inlfvars { for _, v := range inlfvars {
@ -1239,12 +1248,12 @@ func (subst *inlsubst) node(n *Node) *Node {
as.List.Append(n) as.List.Append(n)
} }
as.Rlist.Set(subst.list(n.List)) as.Rlist.Set(subst.list(n.List))
as = typecheck(as, Etop) as = typecheck(as, ctxStmt)
m.Ninit.Append(as) m.Ninit.Append(as)
} }
typecheckslice(m.Ninit.Slice(), Etop) typecheckslice(m.Ninit.Slice(), ctxStmt)
m = typecheck(m, Etop) m = typecheck(m, ctxStmt)
// dump("Return after substitution", m); // dump("Return after substitution", m);
return m return m

View file

@ -85,7 +85,7 @@ func TestIntendedInlining(t *testing.T) {
"puintptr.ptr", "puintptr.ptr",
"spanOf", "spanOf",
"spanOfUnchecked", "spanOfUnchecked",
"(*gcWork).putFast", //"(*gcWork).putFast", // TODO(austin): For debugging #27993
"(*gcWork).tryGetFast", "(*gcWork).tryGetFast",
"(*guintptr).set", "(*guintptr).set",
"(*markBits).advance", "(*markBits).advance",
@ -104,6 +104,7 @@ func TestIntendedInlining(t *testing.T) {
"(*Buffer).Bytes", "(*Buffer).Bytes",
"(*Buffer).Cap", "(*Buffer).Cap",
"(*Buffer).Len", "(*Buffer).Len",
"(*Buffer).Grow",
"(*Buffer).Next", "(*Buffer).Next",
"(*Buffer).Read", "(*Buffer).Read",
"(*Buffer).ReadByte", "(*Buffer).ReadByte",

View file

@ -41,6 +41,11 @@ func TestInvalidLang(t *testing.T) {
t.Error("compilation with -lang=go9.99 succeeded unexpectedly") t.Error("compilation with -lang=go9.99 succeeded unexpectedly")
} }
// This test will have to be adjusted if we ever reach 1.99 or 2.0.
if testLang(t, "go1.99", src, outfile) == nil {
t.Error("compilation with -lang=go1.99 succeeded unexpectedly")
}
if testLang(t, "go1.8", src, outfile) == nil { if testLang(t, "go1.8", src, outfile) == nil {
t.Error("compilation with -lang=go1.8 succeeded unexpectedly") t.Error("compilation with -lang=go1.8 succeeded unexpectedly")
} }

View file

@ -39,7 +39,6 @@ var (
var ( var (
Debug_append int Debug_append int
Debug_asm bool
Debug_closure int Debug_closure int
Debug_compilelater int Debug_compilelater int
debug_dclstack int debug_dclstack int
@ -195,7 +194,7 @@ func Main(archInit func(*Arch)) {
objabi.Flagcount("K", "debug missing line numbers", &Debug['K']) objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
objabi.Flagcount("L", "show full file names in error messages", &Debug['L']) objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
objabi.Flagcount("N", "disable optimizations", &Debug['N']) objabi.Flagcount("N", "disable optimizations", &Debug['N'])
flag.BoolVar(&Debug_asm, "S", false, "print assembly listing") objabi.Flagcount("S", "print assembly listing", &Debug['S'])
objabi.AddVersionFlag() // -V objabi.AddVersionFlag() // -V
objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W']) objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`") flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`")
@ -247,6 +246,9 @@ func Main(archInit func(*Arch)) {
flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`") flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
var goversion string var goversion string
flag.StringVar(&goversion, "goversion", "", "required version of the runtime") flag.StringVar(&goversion, "goversion", "", "required version of the runtime")
var symabisPath string
flag.StringVar(&symabisPath, "symabis", "", "read symbol ABIs from `file`")
flag.BoolVar(&allABIs, "allabis", false, "generate ABI wrappers for all symbols (for bootstrap)")
flag.StringVar(&traceprofile, "traceprofile", "", "write an execution trace to `file`") flag.StringVar(&traceprofile, "traceprofile", "", "write an execution trace to `file`")
flag.StringVar(&blockprofile, "blockprofile", "", "write block profile to `file`") flag.StringVar(&blockprofile, "blockprofile", "", "write block profile to `file`")
flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`") flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`")
@ -262,7 +264,7 @@ func Main(archInit func(*Arch)) {
Ctxt.Flag_dynlink = flag_dynlink Ctxt.Flag_dynlink = flag_dynlink
Ctxt.Flag_optimize = Debug['N'] == 0 Ctxt.Flag_optimize = Debug['N'] == 0
Ctxt.Debugasm = Debug_asm Ctxt.Debugasm = Debug['S']
Ctxt.Debugvlog = Debug_vlog Ctxt.Debugvlog = Debug_vlog
if flagDWARF { if flagDWARF {
Ctxt.DebugInfo = debuginfo Ctxt.DebugInfo = debuginfo
@ -285,6 +287,10 @@ func Main(archInit func(*Arch)) {
checkLang() checkLang()
if symabisPath != "" {
readSymABIs(symabisPath, myimportpath)
}
thearch.LinkArch.Init(Ctxt) thearch.LinkArch.Init(Ctxt)
if outfile == "" { if outfile == "" {
@ -431,9 +437,16 @@ func Main(archInit func(*Arch)) {
} }
ssaDump = os.Getenv("GOSSAFUNC") ssaDump = os.Getenv("GOSSAFUNC")
if strings.HasSuffix(ssaDump, "+") { if ssaDump != "" {
ssaDump = ssaDump[:len(ssaDump)-1] if strings.HasSuffix(ssaDump, "+") {
ssaDumpStdout = true ssaDump = ssaDump[:len(ssaDump)-1]
ssaDumpStdout = true
}
spl := strings.Split(ssaDump, ":")
if len(spl) > 1 {
ssaDump = spl[0]
ssaDumpCFG = spl[1]
}
} }
trackScopes = flagDWARF trackScopes = flagDWARF
@ -502,7 +515,7 @@ func Main(archInit func(*Arch)) {
for i := 0; i < len(xtop); i++ { for i := 0; i < len(xtop); i++ {
n := xtop[i] n := xtop[i]
if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias) { if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias) {
xtop[i] = typecheck(n, Etop) xtop[i] = typecheck(n, ctxStmt)
} }
} }
@ -514,7 +527,7 @@ func Main(archInit func(*Arch)) {
for i := 0; i < len(xtop); i++ { for i := 0; i < len(xtop); i++ {
n := xtop[i] n := xtop[i]
if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias { if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias {
xtop[i] = typecheck(n, Etop) xtop[i] = typecheck(n, ctxStmt)
} }
} }
resumecheckwidth() resumecheckwidth()
@ -529,7 +542,7 @@ func Main(archInit func(*Arch)) {
Curfn = n Curfn = n
decldepth = 1 decldepth = 1
saveerrors() saveerrors()
typecheckslice(Curfn.Nbody.Slice(), Etop) typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
checkreturn(Curfn) checkreturn(Curfn)
if nerrors != 0 { if nerrors != 0 {
Curfn.Nbody.Set(nil) // type errors; do not compile Curfn.Nbody.Set(nil) // type errors; do not compile
@ -681,7 +694,7 @@ func Main(archInit func(*Arch)) {
timings.Start("be", "externaldcls") timings.Start("be", "externaldcls")
for i, n := range externdcl { for i, n := range externdcl {
if n.Op == ONAME { if n.Op == ONAME {
externdcl[i] = typecheck(externdcl[i], Erv) externdcl[i] = typecheck(externdcl[i], ctxExpr)
} }
} }
// Check the map keys again, since we typechecked the external // Check the map keys again, since we typechecked the external
@ -810,6 +823,81 @@ func readImportCfg(file string) {
} }
} }
// symabiDefs and symabiRefs record the defined and referenced ABIs of
// symbols required by non-Go code. These are keyed by link symbol
// name, where the local package prefix is always `"".`
var symabiDefs, symabiRefs map[string]obj.ABI
// allABIs indicates that all symbol definitions should have ABI
// wrappers. This is used during toolchain bootstrapping to avoid
// having to find cross-package references.
var allABIs bool
// readSymABIs reads a symabis file that specifies definitions and
// references of text symbols by ABI.
//
// The symabis format is a set of lines, where each line is a sequence
// of whitespace-separated fields. The first field is a verb and is
// either "def" for defining a symbol ABI or "ref" for referencing a
// symbol using an ABI. For both "def" and "ref", the second field is
// the symbol name and the third field is the ABI name, as one of the
// named cmd/internal/obj.ABI constants.
func readSymABIs(file, myimportpath string) {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("-symabis: %v", err)
}
symabiDefs = make(map[string]obj.ABI)
symabiRefs = make(map[string]obj.ABI)
localPrefix := ""
if myimportpath != "" {
// Symbols in this package may be written either as
// "".X or with the package's import path already in
// the symbol.
localPrefix = objabi.PathToPrefix(myimportpath) + "."
}
for lineNum, line := range strings.Split(string(data), "\n") {
lineNum++ // 1-based
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
parts := strings.Fields(line)
switch parts[0] {
case "def", "ref":
// Parse line.
if len(parts) != 3 {
log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0])
}
sym, abi := parts[1], parts[2]
if abi != "ABI0" { // Only supported external ABI right now
log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abi)
}
// If the symbol is already prefixed with
// myimportpath, rewrite it to start with ""
// so it matches the compiler's internal
// symbol names.
if localPrefix != "" && strings.HasPrefix(sym, localPrefix) {
sym = `"".` + sym[len(localPrefix):]
}
// Record for later.
if parts[0] == "def" {
symabiDefs[sym] = obj.ABI0
} else {
symabiRefs[sym] = obj.ABI0
}
default:
log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0])
}
}
}
func saveerrors() { func saveerrors() {
nsavederrors += nerrors nsavederrors += nerrors
nerrors = 0 nerrors = 0
@ -1236,6 +1324,7 @@ var concurrentFlagOK = [256]bool{
'l': true, // disable inlining 'l': true, // disable inlining
'w': true, // all printing happens before compilation 'w': true, // all printing happens before compilation
'W': true, // all printing happens before compilation 'W': true, // all printing happens before compilation
'S': true, // printing disassembly happens at the end (but see concurrentBackendAllowed below)
} }
func concurrentBackendAllowed() bool { func concurrentBackendAllowed() bool {
@ -1244,15 +1333,15 @@ func concurrentBackendAllowed() bool {
return false return false
} }
} }
// Debug_asm by itself is ok, because all printing occurs // Debug['S'] by itself is ok, because all printing occurs
// while writing the object file, and that is non-concurrent. // while writing the object file, and that is non-concurrent.
// Adding Debug_vlog, however, causes Debug_asm to also print // Adding Debug_vlog, however, causes Debug['S'] to also print
// while flushing the plist, which happens concurrently. // while flushing the plist, which happens concurrently.
if Debug_vlog || debugstr != "" || debuglive > 0 { if Debug_vlog || debugstr != "" || debuglive > 0 {
return false return false
} }
// TODO: Test and delete these conditions. // TODO: Test and delete this condition.
if objabi.Fieldtrack_enabled != 0 || objabi.Clobberdead_enabled != 0 { if objabi.Fieldtrack_enabled != 0 {
return false return false
} }
// TODO: fix races and enable the following flags // TODO: fix races and enable the following flags
@ -1366,7 +1455,7 @@ func checkLang() {
if err != nil { if err != nil {
log.Fatalf("internal error parsing default lang %q: %v", def, err) log.Fatalf("internal error parsing default lang %q: %v", def, err)
} }
if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.major > defVers.minor) { if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
log.Fatalf("invalid value %q for -lang: max known version is %q", flag_lang, def) log.Fatalf("invalid value %q for -lang: max known version is %q", flag_lang, def)
} }
} }

View file

@ -15,6 +15,7 @@ import (
"cmd/compile/internal/syntax" "cmd/compile/internal/syntax"
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/src" "cmd/internal/src"
) )
@ -250,6 +251,18 @@ func (p *noder) node() {
} }
} }
// The linker expects an ABI0 wrapper for all cgo-exported
// functions.
for _, prag := range p.pragcgobuf {
switch prag[0] {
case "cgo_export_static", "cgo_export_dynamic":
if symabiRefs == nil {
symabiRefs = make(map[string]obj.ABI)
}
symabiRefs[prag[1]] = obj.ABI0
}
}
pragcgobuf = append(pragcgobuf, p.pragcgobuf...) pragcgobuf = append(pragcgobuf, p.pragcgobuf...)
lineno = src.NoXPos lineno = src.NoXPos
clearImports() clearImports()
@ -484,7 +497,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
} }
} else { } else {
if pure_go || strings.HasPrefix(f.funcname(), "init.") { if pure_go || strings.HasPrefix(f.funcname(), "init.") {
yyerrorl(f.Pos, "missing function body") // Linknamed functions are allowed to have no body. Hopefully
// the linkname target has a body. See issue 23311.
isLinknamed := false
for _, n := range p.linknames {
if f.funcname() == n.local {
isLinknamed = true
break
}
}
if !isLinknamed {
yyerrorl(f.Pos, "missing function body")
}
} }
} }
@ -522,16 +546,22 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
// rewrite ...T parameter // rewrite ...T parameter
if typ.Op == ODDD { if typ.Op == ODDD {
if !dddOk { if !dddOk {
yyerror("cannot use ... in receiver or result parameter list") // We mark these as syntax errors to get automatic elimination
// of multiple such errors per line (see yyerrorl in subr.go).
yyerror("syntax error: cannot use ... in receiver or result parameter list")
} else if !final { } else if !final {
yyerror("can only use ... with final parameter in list") if param.Name == nil {
yyerror("syntax error: cannot use ... with non-final parameter")
} else {
p.yyerrorpos(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
}
} }
typ.Op = OTARRAY typ.Op = OTARRAY
typ.Right = typ.Left typ.Right = typ.Left
typ.Left = nil typ.Left = nil
n.SetIsddd(true) n.SetIsDDD(true)
if n.Left != nil { if n.Left != nil {
n.Left.SetIsddd(true) n.Left.SetIsDDD(true)
} }
} }
@ -619,7 +649,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
x = unparen(x) // TODO(mdempsky): Needed? x = unparen(x) // TODO(mdempsky): Needed?
if x.Op == OCOMPLIT { if x.Op == OCOMPLIT {
// Special case for &T{...}: turn into (*T){...}. // Special case for &T{...}: turn into (*T){...}.
x.Right = p.nod(expr, OIND, x.Right, nil) x.Right = p.nod(expr, ODEREF, x.Right, nil)
x.Right.SetImplicit(true) x.Right.SetImplicit(true)
return x return x
} }
@ -630,7 +660,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
case *syntax.CallExpr: case *syntax.CallExpr:
n := p.nod(expr, OCALL, p.expr(expr.Fun), nil) n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
n.List.Set(p.exprs(expr.ArgList)) n.List.Set(p.exprs(expr.ArgList))
n.SetIsddd(expr.HasDots) n.SetIsDDD(expr.HasDots)
return n return n
case *syntax.ArrayType: case *syntax.ArrayType:
@ -857,7 +887,7 @@ func (p *noder) embedded(typ syntax.Expr) *Node {
n.SetEmbedded(true) n.SetEmbedded(true)
if isStar { if isStar {
n.Left = p.nod(op, OIND, n.Left, nil) n.Left = p.nod(op, ODEREF, n.Left, nil)
} }
return n return n
} }
@ -956,7 +986,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
case syntax.Defer: case syntax.Defer:
op = ODEFER op = ODEFER
case syntax.Go: case syntax.Go:
op = OPROC op = OGO
default: default:
panic("unhandled CallStmt") panic("unhandled CallStmt")
} }
@ -1232,13 +1262,13 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
var unOps = [...]Op{ var unOps = [...]Op{
syntax.Recv: ORECV, syntax.Recv: ORECV,
syntax.Mul: OIND, syntax.Mul: ODEREF,
syntax.And: OADDR, syntax.And: OADDR,
syntax.Not: ONOT, syntax.Not: ONOT,
syntax.Xor: OCOM, syntax.Xor: OBITNOT,
syntax.Add: OPLUS, syntax.Add: OPLUS,
syntax.Sub: OMINUS, syntax.Sub: ONEG,
} }
func (p *noder) unOp(op syntax.Operator) Op { func (p *noder) unOp(op syntax.Operator) Op {

View file

@ -4,9 +4,9 @@ package gc
import "strconv" import "strconv"
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDARRAYBYTESTRARRAYBYTESTRTMPARRAYRUNESTRSTRARRAYBYTESTRARRAYBYTETMPSTRARRAYRUNEASAS2AS2FUNCAS2RECVAS2MAPRAS2DOTTYPEASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTINDINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNOTCOMPLUSMINUSORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASEXCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELPROCRANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDDDDARGINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVEINDREGSPRETJMPGETGEND" const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2FUNCAS2RECVAS2MAPRAS2DOTTYPEASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASEXCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDDDDARGINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVEINDREGSPRETJMPGETGEND"
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 73, 88, 100, 112, 127, 139, 141, 144, 151, 158, 165, 175, 179, 183, 191, 199, 208, 216, 219, 224, 231, 238, 244, 253, 261, 269, 275, 279, 288, 295, 299, 302, 309, 317, 325, 332, 338, 341, 347, 354, 362, 366, 373, 381, 383, 385, 387, 389, 391, 393, 396, 401, 409, 412, 421, 424, 428, 436, 443, 452, 455, 458, 461, 464, 467, 470, 476, 479, 482, 485, 489, 494, 498, 503, 508, 514, 519, 523, 528, 536, 544, 550, 559, 570, 577, 581, 588, 595, 603, 607, 611, 615, 622, 629, 637, 643, 648, 653, 657, 662, 670, 675, 680, 684, 687, 695, 699, 701, 706, 710, 715, 721, 727, 733, 739, 744, 748, 755, 761, 766, 772, 775, 781, 788, 793, 797, 802, 806, 816, 821, 829, 835, 842, 849, 857, 863, 867, 870} var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 133, 140, 147, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 439, 442, 445, 448, 451, 454, 460, 463, 466, 472, 476, 479, 483, 488, 493, 499, 504, 508, 513, 521, 529, 535, 544, 555, 562, 566, 573, 580, 588, 592, 596, 600, 607, 614, 622, 628, 633, 638, 642, 647, 655, 660, 665, 669, 672, 680, 684, 686, 691, 693, 698, 704, 710, 716, 722, 727, 731, 738, 744, 749, 755, 758, 764, 771, 776, 780, 785, 789, 799, 804, 812, 818, 825, 832, 840, 846, 850, 853}
func (i Op) String() string { func (i Op) String() string {
if i >= Op(len(_Op_index)-1) { if i >= Op(len(_Op_index)-1) {

View file

@ -81,7 +81,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
} }
if clear { if clear {
a := nod(OAS, v, nil) a := nod(OAS, v, nil)
a = typecheck(a, Etop) a = typecheck(a, ctxStmt)
o.out = append(o.out, a) o.out = append(o.out, a)
} }
@ -104,7 +104,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
func (o *Order) copyExpr(n *Node, t *types.Type, clear bool) *Node { func (o *Order) copyExpr(n *Node, t *types.Type, clear bool) *Node {
v := o.newTemp(t, clear) v := o.newTemp(t, clear)
a := nod(OAS, v, n) a := nod(OAS, v, n)
a = typecheck(a, Etop) a = typecheck(a, ctxStmt)
o.out = append(o.out, a) o.out = append(o.out, a)
return v return v
} }
@ -128,7 +128,7 @@ func (o *Order) cheapExpr(n *Node) *Node {
} }
a := n.sepcopy() a := n.sepcopy()
a.Left = l a.Left = l
return typecheck(a, Erv) return typecheck(a, ctxExpr)
} }
return o.copyExpr(n, n.Type, false) return o.copyExpr(n, n.Type, false)
@ -153,16 +153,16 @@ func (o *Order) safeExpr(n *Node) *Node {
} }
a := n.sepcopy() a := n.sepcopy()
a.Left = l a.Left = l
return typecheck(a, Erv) return typecheck(a, ctxExpr)
case ODOTPTR, OIND: case ODOTPTR, ODEREF:
l := o.cheapExpr(n.Left) l := o.cheapExpr(n.Left)
if l == n.Left { if l == n.Left {
return n return n
} }
a := n.sepcopy() a := n.sepcopy()
a.Left = l a.Left = l
return typecheck(a, Erv) return typecheck(a, ctxExpr)
case OINDEX, OINDEXMAP: case OINDEX, OINDEXMAP:
var l *Node var l *Node
@ -178,7 +178,7 @@ func (o *Order) safeExpr(n *Node) *Node {
a := n.sepcopy() a := n.sepcopy()
a.Left = l a.Left = l
a.Right = r a.Right = r
return typecheck(a, Erv) return typecheck(a, ctxExpr)
default: default:
Fatalf("ordersafeexpr %v", n.Op) Fatalf("ordersafeexpr %v", n.Op)
@ -213,7 +213,7 @@ func (o *Order) addrTemp(n *Node) *Node {
if out != nil { if out != nil {
Fatalf("staticassign of const generated code: %+v", n) Fatalf("staticassign of const generated code: %+v", n)
} }
vstat = typecheck(vstat, Erv) vstat = typecheck(vstat, ctxExpr)
return vstat return vstat
} }
if isaddrokay(n) { if isaddrokay(n) {
@ -233,7 +233,7 @@ func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
return n return n
} }
// mapKeyReplaceStrConv replaces OARRAYBYTESTR by OARRAYBYTESTRTMP // mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
// in n to avoid string allocations for keys in map lookups. // in n to avoid string allocations for keys in map lookups.
// Returns a bool that signals if a modification was made. // Returns a bool that signals if a modification was made.
// //
@ -250,8 +250,8 @@ func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
func mapKeyReplaceStrConv(n *Node) bool { func mapKeyReplaceStrConv(n *Node) bool {
var replaced bool var replaced bool
switch n.Op { switch n.Op {
case OARRAYBYTESTR: case OBYTES2STR:
n.Op = OARRAYBYTESTRTMP n.Op = OBYTES2STRTMP
replaced = true replaced = true
case OSTRUCTLIT: case OSTRUCTLIT:
for _, elem := range n.List.Slice() { for _, elem := range n.List.Slice() {
@ -300,11 +300,11 @@ func (o *Order) cleanTempNoPop(mark ordermarker) []*Node {
n.Name.SetKeepalive(false) n.Name.SetKeepalive(false)
n.SetAddrtaken(true) // ensure SSA keeps the n variable n.SetAddrtaken(true) // ensure SSA keeps the n variable
live := nod(OVARLIVE, n, nil) live := nod(OVARLIVE, n, nil)
live = typecheck(live, Etop) live = typecheck(live, ctxStmt)
out = append(out, live) out = append(out, live)
} }
kill := nod(OVARKILL, n, nil) kill := nod(OVARKILL, n, nil)
kill = typecheck(kill, Etop) kill = typecheck(kill, ctxStmt)
out = append(out, kill) out = append(out, kill)
} }
return out return out
@ -418,7 +418,7 @@ func (o *Order) copyRet(n *Node) []*Node {
as := nod(OAS2, nil, nil) as := nod(OAS2, nil, nil)
as.List.Set(l1) as.List.Set(l1)
as.Rlist.Set1(n) as.Rlist.Set1(n)
as = typecheck(as, Etop) as = typecheck(as, ctxStmt)
o.stmt(as) o.stmt(as)
return l2 return l2
@ -463,7 +463,7 @@ func (o *Order) call(n *Node) {
for i, t := range n.Left.Type.Params().FieldSlice() { for i, t := range n.Left.Type.Params().FieldSlice() {
// Check for "unsafe-uintptr" tag provided by escape analysis. // Check for "unsafe-uintptr" tag provided by escape analysis.
if t.Isddd() && !n.Isddd() { if t.IsDDD() && !n.IsDDD() {
if t.Note == uintptrEscapesTag { if t.Note == uintptrEscapesTag {
for ; i < n.List.Len(); i++ { for ; i < n.List.Len(); i++ {
keepAlive(i) keepAlive(i)
@ -528,7 +528,7 @@ func (o *Order) mapAssign(n *Node) {
t := o.newTemp(m.Type, false) t := o.newTemp(m.Type, false)
n.List.SetIndex(i, t) n.List.SetIndex(i, t)
a := nod(OAS, m, t) a := nod(OAS, m, t)
a = typecheck(a, Etop) a = typecheck(a, ctxStmt)
post = append(post, a) post = append(post, a)
} }
} }
@ -553,7 +553,7 @@ func (o *Order) stmt(n *Node) {
default: default:
Fatalf("orderstmt %v", n.Op) Fatalf("orderstmt %v", n.Op)
case OVARKILL, OVARLIVE: case OVARKILL, OVARLIVE, OINLMARK:
o.out = append(o.out, n) o.out = append(o.out, n)
case OAS: case OAS:
@ -602,7 +602,7 @@ func (o *Order) stmt(n *Node) {
} }
l = o.copyExpr(l, n.Left.Type, false) l = o.copyExpr(l, n.Left.Type, false)
n.Right = nod(n.SubOp(), l, n.Right) n.Right = nod(n.SubOp(), l, n.Right)
n.Right = typecheck(n.Right, Erv) n.Right = typecheck(n.Right, ctxExpr)
n.Right = o.expr(n.Right, nil) n.Right = o.expr(n.Right, nil)
n.Op = OAS n.Op = OAS
@ -657,10 +657,10 @@ func (o *Order) stmt(n *Node) {
tmp2 := o.newTemp(types.Types[TBOOL], false) tmp2 := o.newTemp(types.Types[TBOOL], false)
o.out = append(o.out, n) o.out = append(o.out, n)
r := nod(OAS, n.List.First(), tmp1) r := nod(OAS, n.List.First(), tmp1)
r = typecheck(r, Etop) r = typecheck(r, ctxStmt)
o.mapAssign(r) o.mapAssign(r)
r = okas(n.List.Second(), tmp2) r = okas(n.List.Second(), tmp2)
r = typecheck(r, Etop) r = typecheck(r, ctxStmt)
o.mapAssign(r) o.mapAssign(r)
n.List.Set2(tmp1, tmp2) n.List.Set2(tmp1, tmp2)
o.cleanTemp(t) o.cleanTemp(t)
@ -689,7 +689,7 @@ func (o *Order) stmt(n *Node) {
o.cleanTemp(t) o.cleanTemp(t)
// Special: order arguments to inner call but not call itself. // Special: order arguments to inner call but not call itself.
case ODEFER, OPROC: case ODEFER, OGO:
t := o.markTemp() t := o.markTemp()
o.call(n.Left) o.call(n.Left)
o.out = append(o.out, n) o.out = append(o.out, n)
@ -751,8 +751,8 @@ func (o *Order) stmt(n *Node) {
// Mark []byte(str) range expression to reuse string backing storage. // Mark []byte(str) range expression to reuse string backing storage.
// It is safe because the storage cannot be mutated. // It is safe because the storage cannot be mutated.
if n.Right.Op == OSTRARRAYBYTE { if n.Right.Op == OSTR2BYTES {
n.Right.Op = OSTRARRAYBYTETMP n.Right.Op = OSTR2BYTESTMP
} }
t := o.markTemp() t := o.markTemp()
@ -779,7 +779,7 @@ func (o *Order) stmt(n *Node) {
if r.Type.IsString() && r.Type != types.Types[TSTRING] { if r.Type.IsString() && r.Type != types.Types[TSTRING] {
r = nod(OCONV, r, nil) r = nod(OCONV, r, nil)
r.Type = types.Types[TSTRING] r.Type = types.Types[TSTRING]
r = typecheck(r, Erv) r = typecheck(r, ctxExpr)
} }
n.Right = o.copyExpr(r, r.Type, false) n.Right = o.copyExpr(r, r.Type, false)
@ -897,13 +897,13 @@ func (o *Order) stmt(n *Node) {
if r.Colas() { if r.Colas() {
tmp2 := nod(ODCL, tmp1, nil) tmp2 := nod(ODCL, tmp1, nil)
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, ctxStmt)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
} }
r.Left = o.newTemp(r.Right.Left.Type.Elem(), types.Haspointers(r.Right.Left.Type.Elem())) r.Left = o.newTemp(r.Right.Left.Type.Elem(), types.Haspointers(r.Right.Left.Type.Elem()))
tmp2 := nod(OAS, tmp1, r.Left) tmp2 := nod(OAS, tmp1, r.Left)
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, ctxStmt)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
} }
@ -914,13 +914,13 @@ func (o *Order) stmt(n *Node) {
tmp1 := r.List.First() tmp1 := r.List.First()
if r.Colas() { if r.Colas() {
tmp2 := nod(ODCL, tmp1, nil) tmp2 := nod(ODCL, tmp1, nil)
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, ctxStmt)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
} }
r.List.Set1(o.newTemp(types.Types[TBOOL], false)) r.List.Set1(o.newTemp(types.Types[TBOOL], false))
tmp2 := okas(tmp1, r.List.First()) tmp2 := okas(tmp1, r.List.First())
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, ctxStmt)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
} }
orderBlock(&n2.Ninit, o.free) orderBlock(&n2.Ninit, o.free)
@ -1064,14 +1064,14 @@ func (o *Order) expr(n, lhs *Node) *Node {
haslit := false haslit := false
for _, n1 := range n.List.Slice() { for _, n1 := range n.List.Slice() {
hasbyte = hasbyte || n1.Op == OARRAYBYTESTR hasbyte = hasbyte || n1.Op == OBYTES2STR
haslit = haslit || n1.Op == OLITERAL && len(n1.Val().U.(string)) != 0 haslit = haslit || n1.Op == OLITERAL && len(n1.Val().U.(string)) != 0
} }
if haslit && hasbyte { if haslit && hasbyte {
for _, n2 := range n.List.Slice() { for _, n2 := range n.List.Slice() {
if n2.Op == OARRAYBYTESTR { if n2.Op == OBYTES2STR {
n2.Op = OARRAYBYTESTRTMP n2.Op = OBYTES2STRTMP
} }
} }
} }
@ -1153,9 +1153,9 @@ func (o *Order) expr(n, lhs *Node) *Node {
ONEW, ONEW,
OREAL, OREAL,
ORECOVER, ORECOVER,
OSTRARRAYBYTE, OSTR2BYTES,
OSTRARRAYBYTETMP, OSTR2BYTESTMP,
OSTRARRAYRUNE: OSTR2RUNES:
if isRuneCount(n) { if isRuneCount(n) {
// len([]rune(s)) is rewritten to runtime.countrunes(s) later. // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
@ -1248,11 +1248,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
// Mark string(byteSlice) arguments to reuse byteSlice backing // Mark string(byteSlice) arguments to reuse byteSlice backing
// buffer during conversion. String comparison does not // buffer during conversion. String comparison does not
// memorize the strings for later use, so it is safe. // memorize the strings for later use, so it is safe.
if n.Left.Op == OARRAYBYTESTR { if n.Left.Op == OBYTES2STR {
n.Left.Op = OARRAYBYTESTRTMP n.Left.Op = OBYTES2STRTMP
} }
if n.Right.Op == OARRAYBYTESTR { if n.Right.Op == OBYTES2STR {
n.Right.Op = OARRAYBYTESTRTMP n.Right.Op = OBYTES2STRTMP
} }
case t.IsStruct() || t.IsArray(): case t.IsStruct() || t.IsArray():
@ -1301,7 +1301,7 @@ func (o *Order) as2(n *Node) {
as := nod(OAS2, nil, nil) as := nod(OAS2, nil, nil)
as.List.Set(left) as.List.Set(left)
as.Rlist.Set(tmplist) as.Rlist.Set(tmplist)
as = typecheck(as, Etop) as = typecheck(as, ctxStmt)
o.stmt(as) o.stmt(as)
} }
@ -1322,13 +1322,13 @@ func (o *Order) okAs2(n *Node) {
if tmp1 != nil { if tmp1 != nil {
r := nod(OAS, n.List.First(), tmp1) r := nod(OAS, n.List.First(), tmp1)
r = typecheck(r, Etop) r = typecheck(r, ctxStmt)
o.mapAssign(r) o.mapAssign(r)
n.List.SetFirst(tmp1) n.List.SetFirst(tmp1)
} }
if tmp2 != nil { if tmp2 != nil {
r := okas(n.List.Second(), tmp2) r := okas(n.List.Second(), tmp2)
r = typecheck(r, Etop) r = typecheck(r, ctxStmt)
o.mapAssign(r) o.mapAssign(r)
n.List.SetSecond(tmp2) n.List.SetSecond(tmp2)
} }

Some files were not shown because too many files have changed in this diff Show more