mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.boringcrypto] all: merge master into dev.boringcrypto
Change-Id: I9246c8228d38559c40e69fa403fa946ac1b31dbe
This commit is contained in:
commit
4ed8ad4d69
1404 changed files with 82120 additions and 33756 deletions
3
AUTHORS
3
AUTHORS
|
|
@ -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>
|
||||||
|
|
|
||||||
183
CONTRIBUTORS
183
CONTRIBUTORS
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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
228
api/go1.12.txt
Normal 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
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -1710,7 +1710,7 @@ prints
|
||||||
&{7 -2.35 abc def}
|
&{7 -2.35 abc def}
|
||||||
&{a:7 b:-2.35 c:abc def}
|
&{a:7 b:-2.35 c:abc def}
|
||||||
&main.T{a:7, b:-2.35, c:"abc\tdef"}
|
&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("%T\n", 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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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> <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> <code>run</code> <code>pkg</code> or <code>go</code> <code>run</code> <code>dir</code>, most importantly <code>go</code> <code>run</code> <code>.</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="runtime">Runtime</h2>
|
<h2 id="runtime">Runtime</h2>
|
||||||
|
|
||||||
<p><!-- CL 85887 -->
|
<p><!-- CL 85887 -->
|
||||||
|
|
|
||||||
784
doc/go1.12.html
784
doc/go1.12.html
|
|
@ -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><nil></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 "hurd" 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'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 "undefined"
|
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 -->
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>&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" "<-" | "<-" "chan" ) ElementType .
|
||||||
The optional <code><-</code> operator specifies the channel <i>direction</i>,
|
The optional <code><-</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><<</code> may legally
|
<code>-</code>, <code>*</code>, <code>/</code>, and <code><<</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 < x + 1</code> is always true.
|
not occur. For instance, it may not assume that <code>x < x + 1</code> is always true.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 += " "
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
misc/cgo/errors/src/issue26745.go
Normal file
17
misc/cgo/errors/src/issue26745.go
Normal 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
|
||||||
|
}
|
||||||
26
misc/cgo/errors/src/issue28069.go
Normal file
26
misc/cgo/errors/src/issue28069.go
Normal 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() {}
|
||||||
29
misc/cgo/errors/src/issue28721.go
Normal file
29
misc/cgo/errors/src/issue28721.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
|
|
|
||||||
7
misc/cgo/test/issue27054/egl.h
Normal file
7
misc/cgo/test/issue27054/egl.h
Normal 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;
|
||||||
17
misc/cgo/test/issue27054/test27054.go
Normal file
17
misc/cgo/test/issue27054/test27054.go
Normal 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.
|
||||||
|
}
|
||||||
12
misc/cgo/test/issue27340.go
Normal file
12
misc/cgo/test/issue27340.go
Normal 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
|
||||||
42
misc/cgo/test/issue27340/a.go
Normal file
42
misc/cgo/test/issue27340/a.go
Normal 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))
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
misc/cgo/test/issue28772.go
Normal file
12
misc/cgo/test/issue28772.go
Normal 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
|
||||||
83
misc/cgo/test/issue28896.go
Normal file
83
misc/cgo/test/issue28896.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
misc/cgo/test/issue29383.go
Normal file
19
misc/cgo/test/issue29383.go
Normal 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
|
||||||
|
}
|
||||||
22
misc/cgo/test/issue29748.go
Normal file
22
misc/cgo/test/issue29748.go
Normal 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,
|
||||||
|
})
|
||||||
|
}
|
||||||
17
misc/cgo/test/issue29781.go
Normal file
17
misc/cgo/test/issue29781.go
Normal 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)
|
||||||
|
}
|
||||||
38
misc/cgo/test/issue30065.go
Normal file
38
misc/cgo/test/issue30065.go
Normal 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')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
||||||
12
misc/cgo/testcshared/src/go2c2go/go/shlib.go
Normal file
12
misc/cgo/testcshared/src/go2c2go/go/shlib.go
Normal 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() {}
|
||||||
9
misc/cgo/testcshared/src/go2c2go/m1/c.c
Normal file
9
misc/cgo/testcshared/src/go2c2go/m1/c.c
Normal 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;
|
||||||
|
}
|
||||||
22
misc/cgo/testcshared/src/go2c2go/m1/main.go
Normal file
22
misc/cgo/testcshared/src/go2c2go/m1/main.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
22
misc/cgo/testcshared/src/go2c2go/m2/main.go
Normal file
22
misc/cgo/testcshared/src/go2c2go/m2/main.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
|
||||||
20
misc/cgo/testshared/src/issue25065/a.go
Normal file
20
misc/cgo/testshared/src/issue25065/a.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
}
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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})
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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).
|
||||||
|
|
|
||||||
1
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
1
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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": "",
|
|
||||||
}
|
|
||||||
|
|
|
||||||
204
src/cmd/compile/fmtmap_test.go
Normal file
204
src/cmd/compile/fmtmap_test.go
Normal 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": "",
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 "<...>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue