mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
[dev.boringcrypto] all: merge master into dev.boringcrypto
Change-Id: I9246c8228d38559c40e69fa403fa946ac1b31dbe
This commit is contained in:
commit
4ed8ad4d69
3
AUTHORS
3
AUTHORS
|
@ -418,7 +418,7 @@ Eivind Uggedal <eivind@uggedal.com>
|
|||
Elbert Fliek <efliek@gmail.com>
|
||||
Eldar Rakhimberdin <ibeono@gmail.com>
|
||||
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>
|
||||
Emerson Lin <linyintor@gmail.com>
|
||||
Emil Hessman <emil@hessman.se>
|
||||
|
@ -1304,6 +1304,7 @@ Sven Almgren <sven@tras.se>
|
|||
Sylvain Zimmer <sylvain@sylvainzimmer.com>
|
||||
Syohei YOSHIDA <syohex@gmail.com>
|
||||
Szabolcs Nagy <nsz@port70.net>
|
||||
Taavi Kivisik <taavi.kivisik@gmail.com>
|
||||
Tad Fisher <tadfisher@gmail.com>
|
||||
Tad Glines <tad.glines@gmail.com>
|
||||
Taj Khattra <taj.khattra@gmail.com>
|
||||
|
|
183
CONTRIBUTORS
183
CONTRIBUTORS
|
@ -25,6 +25,7 @@
|
|||
# Please keep the list sorted.
|
||||
|
||||
Aamir Khan <syst3m.w0rm@gmail.com>
|
||||
Aaron Cannon <cannona@fireantproductions.com>
|
||||
Aaron France <aaron.l.france@gmail.com>
|
||||
Aaron Jacobs <jacobsa@google.com>
|
||||
Aaron Kemp <kemp.aaron@gmail.com>
|
||||
|
@ -32,6 +33,7 @@ Aaron Stein <aaronstein12@gmail.com>
|
|||
Aaron Torres <tcboox@gmail.com>
|
||||
Aaron Zinman <aaron@azinman.com>
|
||||
Aarti Parikh <aarti.parikh@gmail.com>
|
||||
Abdullah Al Maruf <mymail.maruf@gmail.com>
|
||||
Abe Haskins <abeisgreat@abeisgreat.com>
|
||||
Abhinav Gupta <abhinav.g90@gmail.com>
|
||||
Adam Azarchs <adam.azarchs@10xgenomics.com>
|
||||
|
@ -66,6 +68,7 @@ Aishraj Dahal <aishraj@users.noreply.github.com>
|
|||
Akhil Indurti <contact@akhilindurti.com>
|
||||
Akihiro Suda <suda.kyoto@gmail.com>
|
||||
Akshat Kumar <seed@mail.nanosouffle.net>
|
||||
Alan Braithwaite <alan@ipaddr.org>
|
||||
Alan Donovan <adonovan@google.com>
|
||||
Alan Shreve <alan@inconshreveable.com>
|
||||
Albert Nigmatzianov <albertnigma@gmail.com>
|
||||
|
@ -74,8 +77,10 @@ Albert Yu <yukinying@gmail.com>
|
|||
Alberto Bertogli <albertito@blitiri.com.ar>
|
||||
Alberto Donizetti <alb.donizetti@gmail.com>
|
||||
Alberto García Hierro <alberto@garciahierro.com> <alberto.garcia.hierro@gmail.com>
|
||||
Aleksa Sarai <cyphar@cyphar.com>
|
||||
Aleksandar Dezelin <dezelin@gmail.com>
|
||||
Aleksandr Lukinykh <a.lukinykh@xsolla.com>
|
||||
Aleksandr Razumov <ar@cydev.ru>
|
||||
Alekseev Artem <a.artem060@gmail.com>
|
||||
Alessandro Arzilli <alessandro.arzilli@gmail.com>
|
||||
Alessandro Baffa <alessandro.baffa@gmail.com>
|
||||
|
@ -85,6 +90,7 @@ Alex Bramley <abramley@google.com>
|
|||
Alex Browne <stephenalexbrowne@gmail.com>
|
||||
Alex Carol <alex.carol.c@gmail.com>
|
||||
Alex Jin <toalexjin@gmail.com>
|
||||
Alex Kohler <alexjohnkohler@gmail.com>
|
||||
Alex Myasoedov <msoedov@gmail.com>
|
||||
Alex Plugaru <alex@plugaru.org> <alexandru.plugaru@gmail.com>
|
||||
Alex Schroeder <alex@gnu.org>
|
||||
|
@ -106,15 +112,19 @@ Alexander Polcyn <apolcyn@google.com>
|
|||
Alexander Reece <awreece@gmail.com>
|
||||
Alexander Surma <surma@surmair.de>
|
||||
Alexander Zhavnerchik <alex.vizor@gmail.com>
|
||||
Alexander Zillion <alex@alexzillion.com>
|
||||
Alexander Zolotov <goldifit@gmail.com>
|
||||
Alexandre Cesaro <alexandre.cesaro@gmail.com>
|
||||
Alexandre Fiori <fiorix@gmail.com>
|
||||
Alexandre Maari <draeron@gmail.com>
|
||||
Alexandre Normand <alexandre.normand@gmail.com>
|
||||
Alexandre Parentea <aubonbeurre@gmail.com>
|
||||
Alexandre Viau <alexandre@alexandreviau.net>
|
||||
Alexandru Moșoi <brtzsnr@gmail.com>
|
||||
Alexei Sholik <alcosholik@gmail.com>
|
||||
Alexey Alexandrov <aalexand@google.com>
|
||||
Alexey Borzenkov <snaury@gmail.com>
|
||||
Alexey Naidonov <alexey.naidyonov@gmail.com>
|
||||
Alexey Neganov <neganovalexey@gmail.com>
|
||||
Alexey Palazhchenko <alexey.palazhchenko@gmail.com>
|
||||
Alexis Hildebrandt <surryhill@gmail.com>
|
||||
|
@ -133,14 +143,17 @@ Anand K. Mistry <anand@mistry.ninja>
|
|||
Anders Pearson <anders@columbia.edu>
|
||||
André Carvalho <asantostc@gmail.com>
|
||||
Andre Nathan <andrenth@gmail.com>
|
||||
Andrea Nodari <andrea.nodari91@gmail.com>
|
||||
Andrea Spadaccini <spadaccio@google.com>
|
||||
Andreas Auernhammer <aead@mail.de>
|
||||
Andreas Jellinghaus <andreas@ionisiert.de> <anj@google.com>
|
||||
Andreas Litt <andreas.litt@gmail.com>
|
||||
Andrei Gherzan <andrei@resin.io>
|
||||
Andrei Korzhevskii <a.korzhevskiy@gmail.com>
|
||||
Andrei Tudor Călin <mail@acln.ro>
|
||||
Andrei Vieru <euvieru@gmail.com>
|
||||
Andres Erbsen <andreser@google.com>
|
||||
Andres Lowrie <andres.lowrie@gmail.com>
|
||||
Andrew Austin <andrewaclt@gmail.com>
|
||||
Andrew Balholm <andybalholm@gmail.com>
|
||||
Andrew Benton <andrewmbenton@gmail.com>
|
||||
|
@ -155,9 +168,11 @@ Andrew Jackura <ajackura@google.com>
|
|||
Andrew Lutomirski <andy@luto.us>
|
||||
Andrew Pilloud <andrewpilloud@igneoussystems.com>
|
||||
Andrew Pogrebnoy <absourd.noise@gmail.com>
|
||||
Andrew Poydence <apoydence@pivotal.io>
|
||||
Andrew Pritchard <awpritchard@gmail.com>
|
||||
Andrew Radev <andrey.radev@gmail.com>
|
||||
Andrew Skiba <skibaa@gmail.com>
|
||||
Andrew Stribblehill <ads@wompom.org>
|
||||
Andrew Szeto <andrew@jabagawee.com>
|
||||
Andrew Werner <andrew@upthere.com> <awerner32@gmail.com>
|
||||
Andrew Wilkins <axwalk@gmail.com>
|
||||
|
@ -174,21 +189,26 @@ Andy Finkenstadt <afinkenstadt@zynga.com>
|
|||
Andy Lindeman <andy@lindeman.io>
|
||||
Andy Maloney <asmaloney@gmail.com>
|
||||
Andy Walker <walkeraj@gmail.com>
|
||||
Andzej Maciusovic <andzej.maciusovic@gmail.com>
|
||||
Anfernee Yongkun Gui <anfernee.gui@gmail.com>
|
||||
Angelo Bulfone <mbulfone@gmail.com>
|
||||
Anh Hai Trinh <anh.hai.trinh@gmail.com>
|
||||
Anit Gandhi <anitgandhi@gmail.com>
|
||||
Ankit Goyal <ankit3goyal@gmail.com>
|
||||
Anmol Sethi <anmol@aubble.com>
|
||||
Anschel Schaffer-Cohen <anschelsc@gmail.com>
|
||||
Anthony Alves <cvballa3g0@gmail.com>
|
||||
Anthony Canino <anthony.canino1@gmail.com>
|
||||
Anthony Eufemio <anthony.eufemio@gmail.com>
|
||||
Anthony Fok <foka@debian.org>
|
||||
Anthony Martin <ality@pbrane.org>
|
||||
Anthony Sottile <asottile@umich.edu>
|
||||
Anthony Starks <ajstarks@gmail.com>
|
||||
Anthony Voutas <voutasaurus@gmail.com>
|
||||
Anthony Woods <awoods@raintank.io>
|
||||
Antoine GIRARD <sapk@sapk.fr>
|
||||
Antoine Martin <antoine97.martin@gmail.com>
|
||||
Anton Gyllenberg <anton@iki.fi>
|
||||
Antonin Amand <antonin.amand@gmail.com>
|
||||
Antonio Antelo <aantelov87@gmail.com>
|
||||
Antonio Bibiano <antbbn@gmail.com>
|
||||
|
@ -204,6 +224,7 @@ Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
|||
Arne Hormann <arnehormann@gmail.com>
|
||||
Arnout Engelen <arnout@bzzt.net>
|
||||
Aron Nopanen <aron.nopanen@gmail.com>
|
||||
Arthur Fabre <arthur@arthurfabre.com>
|
||||
Arthur Khashaev <arthur@khashaev.ru>
|
||||
Artyom Pervukhin <artyom.pervukhin@gmail.com>
|
||||
Arvindh Rajesh Tamilmani <art@a-30.net>
|
||||
|
@ -217,6 +238,7 @@ Augusto Roman <aroman@gmail.com>
|
|||
Aulus Egnatius Varialus <varialus@gmail.com>
|
||||
Aurélien Rainone <aurelien.rainone@gmail.com>
|
||||
Austin Clements <austin@google.com> <aclements@csail.mit.edu>
|
||||
Avi Flax <avi@timehop.com>
|
||||
awaw fumin <awawfumin@gmail.com>
|
||||
Awn Umar <awn@cryptolosophy.io>
|
||||
Axel Wagner <axel.wagner.hh@googlemail.com>
|
||||
|
@ -224,6 +246,7 @@ Ayanamist Yang <ayanamist@gmail.com>
|
|||
Aymerick Jéhanne <aymerick@jehanne.org>
|
||||
Azat Kaumov <kaumov.a.r@gmail.com>
|
||||
Baiju Muthukadan <baiju.m.mail@gmail.com>
|
||||
Balaram Makam <bmakam.qdt@qualcommdatacenter.com>
|
||||
Balazs Lecz <leczb@google.com>
|
||||
Baokun Lee <nototon@gmail.com>
|
||||
Bartosz Grzybowski <melkorm@gmail.com>
|
||||
|
@ -233,6 +256,7 @@ Ben Burkert <ben@benburkert.com>
|
|||
Ben Eitzen <eitzenb@golang.org>
|
||||
Ben Fried <ben.fried@gmail.com>
|
||||
Ben Haines <bhainesva@gmail.com>
|
||||
Ben Hoyt <benhoyt@gmail.com>
|
||||
Ben Laurie <ben@links.org> <benl@google.com>
|
||||
Ben Lubar <ben.lubar@gmail.com>
|
||||
Ben Lynn <benlynn@gmail.com>
|
||||
|
@ -263,6 +287,7 @@ Blake Mizerany <blake.mizerany@gmail.com>
|
|||
Blixt <me@blixt.nyc>
|
||||
Bob Briski <rbriski@gmail.com>
|
||||
Bob Potter <bobby.potter@gmail.com>
|
||||
Bobby DeSimone <bobbydesimone@gmail.com>
|
||||
Bobby Powers <bobbypowers@gmail.com>
|
||||
Boris Nagaev <nagaev@google.com>
|
||||
Borja Clemente <borja.clemente@gmail.com>
|
||||
|
@ -313,6 +338,7 @@ Carlo Alberto Ferraris <cafxx@strayorange.com>
|
|||
Carlos Castillo <cookieo9@gmail.com>
|
||||
Carlos Cirello <uldericofilho@gmail.com>
|
||||
Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
|
||||
Carlos Souza <carloshrsouza@gmail.com>
|
||||
Carolyn Van Slyck <me@carolynvanslyck.com>
|
||||
Cary Hull <chull@google.com>
|
||||
Case Nelson <case.nelson@gmail.com>
|
||||
|
@ -324,7 +350,9 @@ Cedric Staub <cs@squareup.com>
|
|||
Cezar Sá Espinola <cezarsa@gmail.com>
|
||||
Chad Rosier <mrosier.qdt@qualcommdatacenter.com>
|
||||
ChaiShushan <chaishushan@gmail.com>
|
||||
Channing Kimble-Brown <channing@golang.org>
|
||||
Charles Fenwick Elliott <Charles@FenwickElliott.io>
|
||||
Charles Kenney <charlesc.kenney@gmail.com>
|
||||
Charles L. Dorian <cldorian@gmail.com>
|
||||
Charles Lee <zombie.fml@gmail.com>
|
||||
Charles Weill <weill@google.com>
|
||||
|
@ -355,6 +383,7 @@ Christian Alexander <christian@linux.com>
|
|||
Christian Couder <chriscool@tuxfamily.org>
|
||||
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
|
||||
Christian Pellegrin <chri@evolware.org>
|
||||
Christian R. Petrin <christianpetrin@gmail.com>
|
||||
Christine Hansmann <chhansmann@gmail.com>
|
||||
Christoffer Buchholz <christoffer.buchholz@gmail.com>
|
||||
Christoph Blecker <admin@toph.ca>
|
||||
|
@ -371,12 +400,14 @@ Christopher Wedgwood <cw@f00f.org>
|
|||
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
|
||||
Christy Perez <christy@linux.vnet.ibm.com>
|
||||
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
|
||||
Clément Chigot <clement.chigot@atos.net>
|
||||
Clement Skau <clementskau@gmail.com>
|
||||
Cody Oss <the.cody.oss@gmail.com>
|
||||
Colby Ranger <cranger@google.com>
|
||||
Colin Cross <ccross@android.com>
|
||||
Colin Edwards <colin@recursivepenguin.com>
|
||||
Colin Kennedy <moshen.colin@gmail.com>
|
||||
Colin Nelson <colnnelson@google.com>
|
||||
Colin Rice <clr@google.com>
|
||||
Conrad Irwin <conrad.irwin@gmail.com>
|
||||
Conrad Meyer <cemeyer@cs.washington.edu>
|
||||
|
@ -401,10 +432,13 @@ Dan Caddigan <goldcaddy77@gmail.com>
|
|||
Dan Callahan <dan.callahan@gmail.com>
|
||||
Dan Harrington <harringtond@google.com>
|
||||
Dan Jacques <dnj@google.com>
|
||||
Dan Johnson <computerdruid@google.com>
|
||||
Dan Peterson <dpiddy@gmail.com>
|
||||
Dan Pupius <dan@medium.com>
|
||||
Dan Sinclair <dan.sinclair@gmail.com>
|
||||
Daniël de Kok <me@danieldk.eu>
|
||||
Daniel Fleischman <danielfleischman@gmail.com>
|
||||
Daniel Ingram <ingramds@appstate.edu>
|
||||
Daniel Johansson <dajo2002@gmail.com>
|
||||
Daniel Kerwin <d.kerwin@gini.net>
|
||||
Daniel Krech <eikeon@eikeon.com>
|
||||
|
@ -421,6 +455,7 @@ Daniel Upton <daniel@floppy.co>
|
|||
Daniela Petruzalek <daniela.petruzalek@gmail.com>
|
||||
Danny Rosseau <daniel.rosseau@gmail.com>
|
||||
Daria Kolistratova <daria.kolistratova@intel.com>
|
||||
Darien Raymond <admin@v2ray.com>
|
||||
Darren Elwood <darren@textnode.com>
|
||||
Darshan Parajuli <parajulidarshan@gmail.com>
|
||||
Datong Sun <dndx@idndx.com>
|
||||
|
@ -445,12 +480,15 @@ David du Colombier <0intro@gmail.com>
|
|||
David Forsythe <dforsythe@gmail.com>
|
||||
David G. Andersen <dave.andersen@gmail.com>
|
||||
David Glasser <glasser@meteor.com>
|
||||
David Heuschmann <heuschmann.d@gmail.com>
|
||||
David Howden <dhowden@gmail.com>
|
||||
David Hubbard <dsp@google.com>
|
||||
David Jakob Fritz <david.jakob.fritz@gmail.com>
|
||||
David Jones <dxjones@gmail.com>
|
||||
David Lazar <lazard@golang.org>
|
||||
David Leon Gil <coruus@gmail.com>
|
||||
David McLeish <davemc@google.com>
|
||||
David Ndungu <dnjuguna@gmail.com>
|
||||
David NewHamlet <david@newhamlet.com>
|
||||
David Presotto <presotto@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 Symonds <dsymonds@golang.org>
|
||||
David Thomas <davidthomas426@gmail.com>
|
||||
David Timm <dtimm@pivotal.io>
|
||||
David Titarenco <david.titarenco@gmail.com>
|
||||
David Tolpin <david.tolpin@gmail.com>
|
||||
David Url <david@urld.io>
|
||||
David Volquartz Lebech <david@lebech.info>
|
||||
David Wimmer <davidlwimmer@gmail.com>
|
||||
|
@ -471,6 +511,7 @@ Denis Brandolini <denis.brandolini@gmail.com>
|
|||
Denis Nagorny <denis.nagorny@intel.com>
|
||||
Dennis Kuhnert <mail.kuhnert@gmail.com>
|
||||
Denys Honsiorovskyi <honsiorovskyi@gmail.com>
|
||||
Denys Smirnov <denis.smirnov.91@gmail.com>
|
||||
Derek Buitenhuis <derek.buitenhuis@gmail.com>
|
||||
Derek Che <drc@yahoo-inc.com>
|
||||
Derek McGowan <derek@mcgstyle.net>
|
||||
|
@ -485,9 +526,11 @@ Dhiru Kholia <dhiru.kholia@gmail.com>
|
|||
Dhruvdutt Jadhav <dhruvdutt.jadhav@gmail.com>
|
||||
Di Xiao <dixiao@google.com>
|
||||
Didier Spezia <didier.06@gmail.com>
|
||||
Diego Siqueira <diego9889@gmail.com>
|
||||
Dieter Plaetinck <dieter@raintank.io>
|
||||
Dimitri Sokolyuk <sokolyuk@gmail.com>
|
||||
Dimitri Tcaciuc <dtcaciuc@gmail.com>
|
||||
Dina Garmash <dgrmsh@gmail.com>
|
||||
Diogo Pinela <diogoid7400@gmail.com>
|
||||
Dirk Gadsden <dirk@esherido.com>
|
||||
Diwaker Gupta <diwakergupta@gmail.com>
|
||||
|
@ -499,16 +542,21 @@ Dmitriy Shelenin <deemok@googlemail.com> <deemok@gmail.com>
|
|||
Dmitriy Vyukov <dvyukov@google.com>
|
||||
Dmitry Chestnykh <dchest@gmail.com>
|
||||
Dmitry Doroginin <doroginin@gmail.com>
|
||||
Dmitry Neverov <dmitry.neverov@gmail.com>
|
||||
Dmitry Savintsev <dsavints@gmail.com>
|
||||
Dmitry Yakunin <nonamezeil@gmail.com>
|
||||
Domen Ipavec <domen@ipavec.net>
|
||||
Dominic Green <dominicgreen1@gmail.com>
|
||||
Dominik Honnef <dominik.honnef@gmail.com>
|
||||
Dominik Vogt <vogt@linux.vnet.ibm.com>
|
||||
Don Byington <don@dbyington.com>
|
||||
Donald Huang <don.hcd@gmail.com>
|
||||
Dong-hee Na <donghee.na92@gmail.com>
|
||||
Donovan Hide <donovanhide@gmail.com>
|
||||
Doug Anderson <douga@google.com>
|
||||
Doug Fawley <dfawley@google.com>
|
||||
Douglas Danger Manley <doug.manley@gmail.com>
|
||||
Drew Flower <drewvanstone@gmail.com>
|
||||
Drew Hintz <adhintz@google.com>
|
||||
Duncan Holm <mail@frou.org>
|
||||
Dustin Carlino <dcarlino@google.com>
|
||||
|
@ -520,6 +568,7 @@ Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
|||
Dylan Waits <dylan@waits.io>
|
||||
Edan Bedrik <3d4nb3@gmail.com>
|
||||
Eden Li <eden.li@gmail.com>
|
||||
Eduard Urbach <e.urbach@gmail.com>
|
||||
Eduardo Ramalho <eduardo.ramalho@gmail.com>
|
||||
Edward Muller <edwardam@interlix.com>
|
||||
Egon Elbre <egonelbre@gmail.com>
|
||||
|
@ -529,7 +578,7 @@ Eivind Uggedal <eivind@uggedal.com>
|
|||
Elbert Fliek <efliek@gmail.com>
|
||||
Eldar Rakhimberdin <ibeono@gmail.com>
|
||||
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>
|
||||
Emerson Lin <linyintor@gmail.com>
|
||||
Emil Hessman <emil@hessman.se>
|
||||
|
@ -547,6 +596,7 @@ Eric Koleda <ekoleda+devrel@google.com>
|
|||
Eric Lagergren <ericscottlagergren@gmail.com>
|
||||
Eric Milliken <emilliken@gmail.com>
|
||||
Eric Pauley <eric@pauley.me>
|
||||
Eric Ponce <tricokun@gmail.com>
|
||||
Eric Rescorla <ekr@rtfm.com>
|
||||
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
|
||||
Eric Rykwalder <e.rykwalder@gmail.com>
|
||||
|
@ -555,6 +605,7 @@ Erik Dubbelboer <erik@dubbelboer.com>
|
|||
Erik St. Martin <alakriti@gmail.com>
|
||||
Erik Staab <estaab@google.com>
|
||||
Erik Westrup <erik.westrup@gmail.com>
|
||||
Erin Masatsugu <erin.masatsugu@gmail.com>
|
||||
Ernest Chiang <ernest_chiang@htc.com>
|
||||
Erwin Oegema <blablaechthema@hotmail.com>
|
||||
Esko Luontola <esko.luontola@gmail.com>
|
||||
|
@ -566,6 +617,7 @@ Evan Broder <evan@stripe.com>
|
|||
Evan Brown <evanbrown@google.com>
|
||||
Evan Hicks <evan.hicks2@gmail.com>
|
||||
Evan Jones <ej@evanjones.ca>
|
||||
Evan Klitzke <evan@eklitzke.org>
|
||||
Evan Kroske <evankroske@google.com>
|
||||
Evan Martin <evan.martin@gmail.com>
|
||||
Evan Phoenix <evan@phx.io>
|
||||
|
@ -584,6 +636,7 @@ Fannie Zhang <fannie.zhang@arm.com>
|
|||
Fatih Arslan <fatih@arslan.io>
|
||||
Fazal Majid <majid@apsalar.com>
|
||||
Fazlul Shahriar <fshahriar@gmail.com>
|
||||
Federico Bond <federicobond@gmail.com>
|
||||
Federico Simoncelli <fsimonce@redhat.com>
|
||||
Fedor Indutny <fedor@indutny.com>
|
||||
Felipe Oliveira <felipeweb.programador@gmail.com>
|
||||
|
@ -591,8 +644,10 @@ Felix Geisendörfer <haimuiba@gmail.com>
|
|||
Felix Kollmann <fk@konsorten.de>
|
||||
Filip Gruszczyński <gruszczy@gmail.com>
|
||||
Filip Haglund <drathier@users.noreply.github.com>
|
||||
Filip Stanis <fstanis@google.com>
|
||||
Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io>
|
||||
Firmansyah Adiputra <frm.adiputra@gmail.com>
|
||||
Florian Forster <octo@google.com>
|
||||
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
|
||||
Florian Weimer <fw@deneb.enyo.de>
|
||||
Florin Patan <florinpatan@gmail.com>
|
||||
|
@ -610,9 +665,11 @@ Frederik Ring <frederik.ring@gmail.com>
|
|||
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
|
||||
Fredrik Forsmo <fredrik.forsmo@gmail.com>
|
||||
Fredrik Wallgren <fredrik.wallgren@gmail.com>
|
||||
Frew Schmidt <github@frew.co>
|
||||
Frithjof Schulze <schulze@math.uni-hannover.de> <sfrithjof@gmail.com>
|
||||
Frits van Bommel <fvbommel@gmail.com>
|
||||
Fumitoshi Ukai <ukai@google.com>
|
||||
G. Hussain Chinoy <ghchinoy@gmail.com>
|
||||
Gaal Yahas <gaal@google.com>
|
||||
Gabríel Arthúr Pétursson <gabriel@system.is>
|
||||
Gabriel Aszalos <gabriel.aszalos@gmail.com>
|
||||
|
@ -627,6 +684,7 @@ Gaurish Sharma <contact@gaurishsharma.com>
|
|||
Gautham Thambidorai <gautham.dorai@gmail.com>
|
||||
Gauthier Jolly <gauthier.jolly@gmail.com>
|
||||
Geert-Johan Riemer <gjr19912@gmail.com>
|
||||
Genevieve Luyt <genevieve.luyt@gmail.com>
|
||||
Gengliang Wang <ltnwgl@gmail.com>
|
||||
Geoff Berry <gberry.qdt@qualcommdatacenter.com>
|
||||
Geoffroy Lorieux <lorieux.g@gmail.com>
|
||||
|
@ -634,24 +692,41 @@ Geon Kim <geon0250@gmail.com>
|
|||
Georg Reinke <guelfey@gmail.com>
|
||||
George Gkirtsou <ggirtsou@gmail.com>
|
||||
George Shammas <george@shamm.as> <georgyo@gmail.com>
|
||||
Gerasimos (Makis) Maropoulos <kataras2006@hotmail.com>
|
||||
Gerasimos Dimitriadis <gedimitr@gmail.com>
|
||||
Gergely Brautigam <skarlso777@gmail.com>
|
||||
Getulio Sánchez <valentin2507@gmail.com>
|
||||
Gianguido Sora` <g.sora4@gmail.com>
|
||||
Gideon Jan-Wessel Redelinghuys <gjredelinghuys@gmail.com>
|
||||
Giles Lean <giles.lean@pobox.com>
|
||||
Giovanni Bajo <rasky@develer.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 @bgadrian (830001) <aditza8@gmail.com>
|
||||
GitHub User @bontequero (2674999) <bontequero@gmail.com>
|
||||
GitHub User @cch123 (384546) <buaa.cch@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 @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 @LotusFenn (13775899) <fenn.lotus@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 @pytimer (17105586) <lixin20101023@gmail.com>
|
||||
GitHub User @saitarunreddy (21041941) <saitarunreddypalla@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 Micheloni <giulio.micheloni@gmail.com>
|
||||
Giuseppe Valente <gvalente@arista.com>
|
||||
Gleb Stepanov <glebstepanov1992@gmail.com>
|
||||
Glenn Brown <glennb@google.com>
|
||||
Glenn Lewis <gmlewis@google.com>
|
||||
|
@ -660,14 +735,17 @@ Graham King <graham4king@gmail.com>
|
|||
Graham Miller <graham.miller@gmail.com>
|
||||
Grant Griffiths <ggp493@gmail.com>
|
||||
Greg Poirier <greg.istehbest@gmail.com>
|
||||
Greg Steuck <gnezdo+github@google.com>
|
||||
Greg Ward <greg@gerg.ca>
|
||||
Grégoire Delattre <gregoire.delattre@gmail.com>
|
||||
Gregory Man <man.gregory@gmail.com>
|
||||
Guilherme Caruso <gui.martinscaruso@gmail.com>
|
||||
Guilherme Garnier <guilherme.garnier@gmail.com>
|
||||
Guilherme Goncalves <guilhermeaugustosg@gmail.com>
|
||||
Guilherme Rezende <guilhermebr@gmail.com>
|
||||
Guillaume J. Charmes <guillaume@charmes.net>
|
||||
Guobiao Mei <meiguobiao@gmail.com>
|
||||
Guoliang Wang <iamwgliang@gmail.com>
|
||||
Gustav Paul <gustav.paul@gmail.com>
|
||||
Gustav Westling <gustav@westling.xyz>
|
||||
Gustavo Franco <gustavorfranco@gmail.com>
|
||||
|
@ -702,6 +780,7 @@ Henry Clifford <h.a.clifford@gmail.com>
|
|||
Herbert Georg Fischer <herbert.fischer@gmail.com>
|
||||
Herbie Ong <herbie@google.com>
|
||||
Heschi Kreinick <heschi@google.com>
|
||||
Hidetatsu Yaginuma <ygnmhdtt@gmail.com>
|
||||
Hilko Bengen <bengen@hilluzination.de>
|
||||
Hiroaki Nakamura <hnakamur@gmail.com>
|
||||
Hironao OTSUBO <motemen@gmail.com>
|
||||
|
@ -715,11 +794,16 @@ Hsin Tsao <tsao@google.com>
|
|||
Hsin-Ho Yeh <yhh92u@gmail.com>
|
||||
Hu Keping <hukeping@huawei.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>
|
||||
Ian Cottrell <iancottrell@google.com>
|
||||
Ian Davis <nospam@iandavis.com>
|
||||
Ian Gudger <ian@loosescre.ws>
|
||||
Ian Haken <ihaken@netflix.com>
|
||||
Ian Kent <iankent85@gmail.com>
|
||||
Ian Lance Taylor <iant@golang.org>
|
||||
Ian Leue <ian@appboy.com>
|
||||
Ian Zapolsky <ianzapolsky@gmail.com>
|
||||
Ibrahim AshShohail <ibra.sho@gmail.com>
|
||||
Icarus Sparry <golang@icarus.freeuk.com>
|
||||
Iccha Sethi <icchasethi@gmail.com>
|
||||
|
@ -727,6 +811,7 @@ Idora Shinatose <idora.shinatose@gmail.com>
|
|||
Igor Bernstein <igorbernstein@google.com>
|
||||
Igor Dolzhikov <bluesriverz@gmail.com>
|
||||
Igor Vashyst <ivashyst@gmail.com>
|
||||
Igor Zhilianin <igor.zhilianin@gmail.com>
|
||||
Ilya Tocar <ilya.tocar@intel.com>
|
||||
INADA Naoki <songofacandy@gmail.com>
|
||||
Inanc Gumus <m@inanc.io>
|
||||
|
@ -743,9 +828,12 @@ Issac Trotts <issactrotts@google.com>
|
|||
Ivan Babrou <ivan@cloudflare.com>
|
||||
Ivan Bertona <ivan.bertona@gmail.com>
|
||||
Ivan Krasin <krasin@golang.org>
|
||||
Ivan Kutuzov <arbrix@gmail.com>
|
||||
Ivan Markin <sw@nogoegst.net>
|
||||
Ivan Moscoso <moscoso@gmail.com>
|
||||
Ivan Sharavuev <shpiwan@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>
|
||||
Jack Britton <jackxbritton@gmail.com>
|
||||
Jack Lindamood <jlindamo@justin.tv>
|
||||
|
@ -753,6 +841,7 @@ Jacob Baskin <jbaskin@google.com>
|
|||
Jacob H. Haven <jacob@cloudflare.com>
|
||||
Jacob Hoffman-Andrews <github@hoffman-andrews.com>
|
||||
Jae Kwon <jae@tendermint.com>
|
||||
Jake B <doogie1012@gmail.com>
|
||||
Jakob Borg <jakob@nym.se>
|
||||
Jakob Weisblat <jakobw@mit.edu>
|
||||
Jakub Čajka <jcajka@redhat.com>
|
||||
|
@ -762,6 +851,7 @@ James Bardin <j.bardin@gmail.com>
|
|||
James Chacon <jchacon@google.com>
|
||||
James Clarke <jrtc27@jrtc27.com>
|
||||
James Cowgill <James.Cowgill@imgtec.com>
|
||||
James Craig Burley <james-github@burleyarch.com>
|
||||
James David Chalfant <james.chalfant@gmail.com>
|
||||
James Fysh <james.fysh@gmail.com>
|
||||
James Gray <james@james4k.com>
|
||||
|
@ -804,12 +894,15 @@ Jason Buberel <jbuberel@google.com>
|
|||
Jason Chu <jasonchujc@gmail.com>
|
||||
Jason Del Ponte <delpontej@gmail.com>
|
||||
Jason Hall <jasonhall@google.com>
|
||||
Jason Keene <jasonkeene@gmail.com>
|
||||
Jason LeBrun <jblebrun@gmail.com>
|
||||
Jason Smale <jsmale@zendesk.com>
|
||||
Jason Travis <infomaniac7@gmail.com>
|
||||
Jason Wangsadinata <jwangsadinata@gmail.com>
|
||||
Javier Kohen <jkohen@google.com>
|
||||
Javier Segura <javism@gmail.com>
|
||||
Jay Conrod <jayconrod@google.com>
|
||||
Jay Taylor <outtatime@gmail.com>
|
||||
Jay Weisskopf <jay@jayschwa.net>
|
||||
Jean de Klerk <deklerk@google.com>
|
||||
Jean-André Santoni <jean.andre.santoni@gmail.com>
|
||||
|
@ -831,6 +924,8 @@ Jeffrey H <jeffreyh192@gmail.com>
|
|||
Jelte Fennema <github-tech@jeltef.nl>
|
||||
Jens Frederich <jfrederich@gmail.com>
|
||||
Jeremiah Harmsen <jeremiah@google.com>
|
||||
Jeremy Banks <_@jeremy.ca>
|
||||
Jeremy Canady <jcanady@gmail.com>
|
||||
Jeremy Jackins <jeremyjackins@gmail.com>
|
||||
Jeremy Schlatter <jeremy.schlatter@gmail.com>
|
||||
Jeroen Bobbeldijk <jerbob92@gmail.com>
|
||||
|
@ -854,6 +949,7 @@ Jiong Du <londevil@gmail.com>
|
|||
Jirka Daněk <dnk@mail.muni.cz>
|
||||
Jiulong Wang <jiulongw@gmail.com>
|
||||
Joakim Sernbrant <serbaut@gmail.com>
|
||||
Joe Bowbeer <joe.bowbeer@gmail.com>
|
||||
Joe Cortopassi <joe@joecortopassi.com>
|
||||
Joe Farrell <joe2farrell@gmail.com>
|
||||
Joe Harrison <joehazzers@gmail.com>
|
||||
|
@ -877,6 +973,7 @@ John C Barstow <jbowtie@amathaine.com>
|
|||
John DeNero <denero@google.com>
|
||||
John Dethridge <jcd@golang.org>
|
||||
John Gibb <johngibb@gmail.com>
|
||||
John Gilik <john@jgilik.com>
|
||||
John Graham-Cumming <jgc@jgc.org> <jgrahamc@gmail.com>
|
||||
John Howard Palevich <jack.palevich@gmail.com>
|
||||
John Jeffery <jjeffery@sp.com.au>
|
||||
|
@ -910,6 +1007,7 @@ Joonas Kuorilehto <joneskoo@derbian.fi>
|
|||
Joop Kiefte <ikojba@gmail.com> <joop@kiefte.net>
|
||||
Jordan Krage <jmank88@gmail.com>
|
||||
Jordan Lewis <jordanthelewis@gmail.com>
|
||||
Jordan Rhee <jordanrh@microsoft.com>
|
||||
Jos Visser <josv@google.com>
|
||||
Jose Luis Vázquez González <josvazg@gmail.com>
|
||||
Joseph Bonneau <jcb@google.com>
|
||||
|
@ -930,12 +1028,15 @@ Jostein Stuhaug <js@solidsystem.no>
|
|||
JP Sugarbroad <jpsugar@google.com>
|
||||
JT Olds <jtolds@xnet5.com>
|
||||
Juan Carlos <juanjcsr@gmail.com>
|
||||
Juan Pablo Civile <elementohb@gmail.com>
|
||||
Jude Pereira <judebpereira@gmail.com>
|
||||
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
|
||||
Julia Hansbrough <flowerhack@google.com>
|
||||
Julian Kornberger <jk+github@digineo.de>
|
||||
Julian Pastarmov <pastarmovj@google.com>
|
||||
Julian Phillips <julian@quantumfyre.co.uk>
|
||||
Julie Qiu <julie@golang.org>
|
||||
Julien Kauffmann <julien.kauffmann@freelan.org>
|
||||
Julien Salleyron <julien.salleyron@gmail.com>
|
||||
Julien Schmidt <google@julienschmidt.com>
|
||||
Julio Montes <julio.montes@intel.com>
|
||||
|
@ -961,10 +1062,12 @@ Karoly Negyesi <chx1975@gmail.com>
|
|||
Karsten Köhler <karsten.koehler95@gmail.com>
|
||||
Kashav Madan <kshvmdn@gmail.com>
|
||||
Kate Manson <kate.manson@izettle.com>
|
||||
Katie Hockman <katie@golang.org>
|
||||
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||
Katrina Owen <katrina.owen@gmail.com>
|
||||
Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com>
|
||||
Kay Zhu <kayzhu@google.com>
|
||||
Kazuhiro Sera <seratch@gmail.com>
|
||||
KB Sriram <kbsriram@google.com>
|
||||
Keegan Carruthers-Smith <keegan.csmith@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 Ruffin <kruffin@gmail.com>
|
||||
Kevin Vu <kevin.m.vu@gmail.com>
|
||||
Kevin Zita <bleedgreenandgold@gmail.com>
|
||||
Kieran Colford <kieran@kcolford.com>
|
||||
Kim Shrier <kshrier@racktopsystems.com>
|
||||
Kim Yongbin <kybinz@gmail.com>
|
||||
|
@ -1000,6 +1104,7 @@ Klaus Post <klauspost@gmail.com>
|
|||
Kodie Goodwin <kodiegoodwin@gmail.com>
|
||||
Koichi Shiraishi <zchee.io@gmail.com>
|
||||
Koki Ide <niconegoto@yahoo.co.jp>
|
||||
Komu Wairagu <komuw05@gmail.com>
|
||||
Konstantin <konstantin8105@gmail.com>
|
||||
Konstantin Shaposhnikov <k.shaposhnikov@gmail.com>
|
||||
Kris Kwiatkowski <kris@cloudflare.com>
|
||||
|
@ -1015,13 +1120,16 @@ Kyle Jones <kyle@kyledj.com>
|
|||
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
|
||||
Kyle Shannon <kyle@pobox.com>
|
||||
Kyle Spiers <eiais@google.com>
|
||||
Kyle Wood <kyle@kylewood.cc>
|
||||
Kyohei Kadota <lufia@lufia.org>
|
||||
Kyrylo Silin <silin@kyrylo.org>
|
||||
L Campbell <unpantsu@gmail.com>
|
||||
Lai Jiangshan <eag0628@gmail.com>
|
||||
Lajos Papp <lalyos@yahoo.com>
|
||||
Lakshay Garg <lakshay.garg.1996@gmail.com>
|
||||
Lann Martin <lannm@google.com>
|
||||
Lanre Adelowo <yo@lanre.wtf>
|
||||
Larry Clapp <larry@theclapp.org>
|
||||
Larry Hosken <lahosken@golang.org>
|
||||
Lars Jeppesen <jeppesen.lars@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>
|
||||
Lynn Boger <laboger@linux.vnet.ibm.com>
|
||||
Ma Peiqi <mapeiqi2017@gmail.com>
|
||||
Maarten Bezemer <maarten.bezemer@gmail.com>
|
||||
Maciej Dębski <maciejd@google.com>
|
||||
Magnus Hiie <magnus.hiie@gmail.com>
|
||||
Maicon Costa <maiconscosta@gmail.com>
|
||||
Mak Kolybabi <mak@kolybabi.com>
|
||||
Maksym Trykur <maksym.trykur@gmail.com>
|
||||
Mal Curtis <mal@mal.co.nz>
|
||||
Manfred Touron <m@42.am>
|
||||
|
@ -1086,6 +1196,7 @@ Marcel van Lohuizen <mpvl@golang.org>
|
|||
Marcelo Cantos <marcelo.cantos@gmail.com>
|
||||
Marcelo E. Magallon <marcelo.magallon@gmail.com>
|
||||
Marco Hennings <marco.hennings@freiheit.com>
|
||||
Marcus Willock <crazcalm@gmail.com>
|
||||
Marga Manterola <marga@google.com>
|
||||
Marin Bašić <marin.basic02@gmail.com>
|
||||
Mario Arranz <marioarranzr@gmail.com>
|
||||
|
@ -1102,12 +1213,14 @@ Mark Theunissen <mark.theunissen@gmail.com>
|
|||
Mark Wolfe <mark@wolfe.id.au>
|
||||
Mark Zavislak <zavislak@google.com>
|
||||
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
|
||||
Marko Kevac <marko@kevac.org>
|
||||
Marko Mikulicic <mkm@google.com>
|
||||
Marko Mudrinic <mudrinic.mare@gmail.com>
|
||||
Marko Tiikkaja <marko@joh.to>
|
||||
Markus Duft <markus.duft@salomon.at>
|
||||
Markus Sonderegger <marraison@gmail.com>
|
||||
Markus Zimmermann <zimmski@gmail.com>
|
||||
Marten Seemann <martenseemann@gmail.com>
|
||||
Martin Bertschler <mbertschler@gmail.com>
|
||||
Martin Garton <garton@gmail.com>
|
||||
Martin Habbecke <marhab@google.com>
|
||||
|
@ -1122,6 +1235,7 @@ Martin Olsen <github.com@martinolsen.net>
|
|||
Martin Olsson <martin@minimum.se>
|
||||
Martin Probst <martin@probst.io>
|
||||
Martin Sucha <anty.sk+git@gmail.com>
|
||||
Martin Tournoij <martin@arp242.net>
|
||||
Martins Sipenko <martins.sipenko@gmail.com>
|
||||
Martynas Budriūnas <mabu@google.com>
|
||||
Marvin Stenger <marvin.stenger94@gmail.com>
|
||||
|
@ -1165,31 +1279,37 @@ Matthew Dempsky <mdempsky@google.com>
|
|||
Matthew Denton <mdenton@skyportsystems.com>
|
||||
Matthew Holt <Matthew.Holt+git@gmail.com>
|
||||
Matthew Horsnell <matthew.horsnell@gmail.com>
|
||||
Matthew Waters <mwwaters@gmail.com>
|
||||
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
||||
Matthieu Olivier <olivier.matthieu@gmail.com>
|
||||
Matthijs Kooijman <matthijs@stdin.nl>
|
||||
Max Riveiro <kavu13@gmail.com>
|
||||
Max Schmitt <max@schmitt.mx>
|
||||
Max Ushakov <ushmax@gmail.com>
|
||||
Maxim Khitrov <max@mxcrypt.com>
|
||||
Maxim Pimenov <mpimenov@google.com>
|
||||
Maxim Ushakov <ushakov@google.com>
|
||||
Maxime de Roucy <maxime.deroucy@gmail.com>
|
||||
Máximo Cuadros Ortiz <mcuadros@gmail.com>
|
||||
Maxwell Krohn <themax@gmail.com>
|
||||
Maya Rashish <maya@NetBSD.org>
|
||||
Mayank Kumar <krmayankk@gmail.com>
|
||||
Meir Fischer <meirfischer@gmail.com>
|
||||
Meng Zhuo <mengzhuo1203@gmail.com>
|
||||
Mhd Sulhan <m.shulhan@gmail.com>
|
||||
Micah Stetson <micah.stetson@gmail.com>
|
||||
Michael Anthony Knyszek <mknyszek@google.com>
|
||||
Michael Brandenburg <mbrandenburg@bolste.com>
|
||||
Michael Chaten <mchaten@gmail.com>
|
||||
Michael Darakananda <pongad@google.com>
|
||||
Michael Dorner <mail@michaeldorner.de>
|
||||
Michael Edwards <medwards@walledcity.ca>
|
||||
Michael Elkins <michael.elkins@gmail.com>
|
||||
Michael Ellis <micellis@justin.tv>
|
||||
Michael Fraenkel <michael.fraenkel@gmail.com>
|
||||
Michael Fromberger <michael.j.fromberger@gmail.com>
|
||||
Michael Gehring <mg@ebfe.org> <gnirheg.leahcim@gmail.com>
|
||||
Michael Henderson <mdhender@users.noreply.github.com>
|
||||
Michael Hendricks <michael@ndrix.org>
|
||||
Michael Hoisie <hoisie@gmail.com>
|
||||
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 T. Jones <mtj@google.com> <michael.jones@gmail.com>
|
||||
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
|
||||
Michael Traver <mtraver@google.com>
|
||||
Michael Vetter <g.bluehut@gmail.com>
|
||||
Michal Bohuslávek <mbohuslavek@gmail.com>
|
||||
Michal Cierniak <cierniak@google.com>
|
||||
Michał Derkacz <ziutek@lnet.pl>
|
||||
Michal Franc <lam.michal.franc@gmail.com>
|
||||
Michal Pristas <michal.pristas@gmail.com>
|
||||
Michal Rostecki <mrostecki@suse.de>
|
||||
Michalis Kargakis <michaliskargakis@gmail.com>
|
||||
Michel Lespinasse <walken@google.com>
|
||||
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
|
||||
Miguel Mendez <stxmendez@gmail.com>
|
||||
Miguel Molina <hi@mvader.me>
|
||||
Mihai Borobocea <MihaiBorobocea@gmail.com>
|
||||
Mihai Todor <todormihai@gmail.com>
|
||||
Mihail Minaev <minaev.mike@gmail.com>
|
||||
Mikael Tillenius <mikti42@gmail.com>
|
||||
Mike Andrews <mra@xoba.com>
|
||||
|
@ -1244,6 +1367,7 @@ Mikhail Panchenko <m@mihasya.com>
|
|||
Miki Tebeka <miki.tebeka@gmail.com>
|
||||
Mikio Hara <mikioh.mikioh@gmail.com>
|
||||
Mikkel Krautz <mikkel@krautz.dk> <krautz@gmail.com>
|
||||
Mikołaj Baranowski <mikolajb@gmail.com>
|
||||
Milan Knezevic <milan.knezevic@mips.com>
|
||||
Milutin Jovanović <jovanovic.milutin@gmail.com>
|
||||
MinJae Kwon <mingrammer@gmail.com>
|
||||
|
@ -1286,6 +1410,7 @@ Niall Sheridan <nsheridan@gmail.com>
|
|||
Nic Day <nic.day@me.com>
|
||||
Nicholas Katsaros <nick@nickkatsaros.com>
|
||||
Nicholas Maniscalco <nicholas@maniscalco.com>
|
||||
Nicholas Ng <nickng@nickng.io>
|
||||
Nicholas Presta <nick@nickpresta.ca> <nick1presta@gmail.com>
|
||||
Nicholas Sullivan <nicholas.sullivan@gmail.com>
|
||||
Nicholas Waples <nwaples@gmail.com>
|
||||
|
@ -1326,12 +1451,15 @@ Oleg Vakheta <helginet@gmail.com>
|
|||
Oleku Konko <oleku.konko@gmail.com>
|
||||
Oling Cat <olingcat@gmail.com>
|
||||
Oliver Hookins <ohookins@gmail.com>
|
||||
Oliver Stenbom <ostenbom@pivotal.io>
|
||||
Oliver Tonnhofer <olt@bogosoft.com>
|
||||
Olivier Antoine <olivier.antoine@gmail.com>
|
||||
Olivier Duperray <duperray.olivier@gmail.com>
|
||||
Olivier Poitrey <rs@dailymotion.com>
|
||||
Olivier Saingre <osaingre@gmail.com>
|
||||
Omar Jarjur <ojarjur@google.com>
|
||||
Oryan Moshe <iamoryanmoshe@gmail.com>
|
||||
Osamu TONOMORI <osamingo@gmail.com>
|
||||
Özgür Kesim <oec-go@kesim.org>
|
||||
Pablo Lalloni <plalloni@gmail.com>
|
||||
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 Martini <mrtnpaolo@gmail.com>
|
||||
Parker Moore <parkrmoore@gmail.com>
|
||||
Parminder Singh <parmsingh101@gmail.com>
|
||||
Pascal S. de Kloe <pascal@quies.net>
|
||||
Pat Moroney <pat@pat.email>
|
||||
Patrick Crosby <patrick@stathat.com>
|
||||
|
@ -1360,6 +1489,7 @@ Paul Hammond <paul@paulhammond.org>
|
|||
Paul Hankin <paulhankin@google.com>
|
||||
Paul Jolly <paul@myitcv.org.uk>
|
||||
Paul Lalonde <paul.a.lalonde@gmail.com>
|
||||
Paul M Furley <paul@paulfurley.com>
|
||||
Paul Marks <pmarks@google.com>
|
||||
Paul Meyer <paul.meyer@microsoft.com>
|
||||
Paul Nasrat <pnasrat@google.com>
|
||||
|
@ -1386,8 +1516,10 @@ Peter Armitage <peter.armitage@gmail.com>
|
|||
Peter Bourgon <peter@bourgon.org>
|
||||
Peter Collingbourne <pcc@google.com>
|
||||
Peter Conerly <pconerly@gmail.com>
|
||||
Peter Dotchev <dotchev@gmail.com>
|
||||
Peter Froehlich <peter.hans.froehlich@gmail.com>
|
||||
Peter Gonda <pgonda@google.com>
|
||||
Peter Hoyes <pahoyes@gmail.com>
|
||||
Peter Kleiweg <pkleiweg@xs4all.nl>
|
||||
Peter McKenzie <petermck@google.com>
|
||||
Peter Moody <pmoody@uber.com>
|
||||
|
@ -1421,11 +1553,13 @@ Piers <google@hellopiers.pro>
|
|||
Pieter Droogendijk <pieter@binky.org.uk>
|
||||
Pietro Gagliardi <pietro10@mac.com>
|
||||
Piyush Mishra <piyush@codeitout.com>
|
||||
Plekhanov Maxim <kishtatix@gmail.com>
|
||||
Pontus Leitzler <leitzler@gmail.com>
|
||||
Prasanna Swaminathan <prasanna@mediamath.com>
|
||||
Prashant Varanasi <prashant@prashantv.com>
|
||||
Pravendra Singh <hackpravj@gmail.com>
|
||||
Preetam Jinka <pj@preet.am>
|
||||
Qais Patankar <qaisjp@gmail.com>
|
||||
Qiuxuan Zhu <ilsh1022@gmail.com>
|
||||
Quan Tran <qeed.quan@gmail.com>
|
||||
Quan Yong Zhai <qyzhai@gmail.com>
|
||||
|
@ -1433,10 +1567,12 @@ Quentin Perez <qperez@ocs.online.net>
|
|||
Quentin Renard <contact@asticode.com>
|
||||
Quentin Smith <quentin@golang.org>
|
||||
Quinn Slack <sqs@sourcegraph.com>
|
||||
Quinten Yearsley <qyearsley@chromium.org>
|
||||
Quoc-Viet Nguyen <afelion@gmail.com>
|
||||
Radek Sohlich <sohlich@gmail.com>
|
||||
Radu Berinde <radu@cockroachlabs.com>
|
||||
Rafal Jeczalik <rjeczalik@gmail.com>
|
||||
Raghavendra Nagaraj <jamdagni86@gmail.com>
|
||||
Rahul Chaudhry <rahulchaudhry@chromium.org>
|
||||
Raif S. Naffah <go@naffah-raif.name>
|
||||
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 Hudson <rlh@golang.org>
|
||||
Rick Sayre <whorfin@gmail.com>
|
||||
Rijnard van Tonder <rvantonder@gmail.com>
|
||||
Riku Voipio <riku.voipio@linaro.org>
|
||||
Risto Jaakko Saarelma <rsaarelm@gmail.com>
|
||||
Rob Earhart <earhart@google.com>
|
||||
|
@ -1488,22 +1625,28 @@ Robert Snedegar <roberts@google.com>
|
|||
Robert Stepanek <robert.stepanek@gmail.com>
|
||||
Robert-André Mauchin <zebob.m@gmail.com>
|
||||
Roberto Clapis <robclap8@gmail.com>
|
||||
Roberto Selbach <roberto@selbach.ca>
|
||||
Robin Eklind <r.eklind.87@gmail.com>
|
||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
||||
Rodolfo Rodriguez <rodolfobgibson@gmail.com>
|
||||
Rodrigo Moraes de Oliveira <rodrigo.moraes@gmail.com>
|
||||
Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
|
||||
Roger Pau Monné <royger@gmail.com>
|
||||
Roger Peppe <rogpeppe@gmail.com>
|
||||
Roland Illig <roland.illig@gmx.de>
|
||||
Roland Shoemaker <rolandshoemaker@gmail.com>
|
||||
Roman Budnikov <romanyx90@yandex.ru>
|
||||
Roman Shchekin <mrqtros@gmail.com>
|
||||
Ron Hashimoto <mail@h2so5.net>
|
||||
Ron Minnich <rminnich@gmail.com>
|
||||
Ross Chater <rdchater@gmail.com>
|
||||
Ross Light <light@google.com> <rlight2@gmail.com>
|
||||
Ross Smith II <ross@smithii.com>
|
||||
Rowan Marshall <rowanajmarshall@gmail.com>
|
||||
Rowan Worth <sqweek@gmail.com>
|
||||
Rudi Kramer <rudi.kramer@gmail.com>
|
||||
Rui Ueyama <ruiu@google.com>
|
||||
Ruslan Nigmatullin <elessar@dropbox.com>
|
||||
Russ Cox <rsc@golang.org>
|
||||
Russell Haering <russellhaering@gmail.com>
|
||||
Ryan Bagwell <ryanbagwell@outlook.com>
|
||||
|
@ -1511,6 +1654,7 @@ Ryan Barrett <ryanb@google.com>
|
|||
Ryan Boehning <ryan.boehning@apcera.com>
|
||||
Ryan Brown <ribrdb@google.com>
|
||||
Ryan Canty <jrcanty@gmail.com>
|
||||
Ryan Dahl <ry@tinyclouds.org>
|
||||
Ryan Hitchman <hitchmanr@gmail.com>
|
||||
Ryan Lower <rpjlower@gmail.com>
|
||||
Ryan Roden-Corrent <ryan@rcorre.net>
|
||||
|
@ -1534,9 +1678,11 @@ Sam Whited <sam@samwhited.com>
|
|||
Sameer Ajmani <sameer@golang.org> <ajmani@gmail.com>
|
||||
Sami Commerot <samic@google.com>
|
||||
Sami Pönkänen <sami.ponkanen@gmail.com>
|
||||
Samuel Kelemen <SCKelemen@users.noreply.github.com>
|
||||
Samuel Tan <samueltan@google.com>
|
||||
Samuele Pedroni <pedronis@lucediurna.net>
|
||||
Sanjay Menakuru <balasanjay@gmail.com>
|
||||
Santhosh Kumar Tekuri <santhosh.tekuri@gmail.com>
|
||||
Sarah Adams <shadams@google.com>
|
||||
Sascha Brawer <sascha@brawer.ch>
|
||||
Sasha Lionheart <lionhearts@google.com>
|
||||
|
@ -1550,13 +1696,17 @@ Scott Mansfield <smansfield@netflix.com>
|
|||
Scott Schwartz <scotts@golang.org>
|
||||
Scott Van Woudenberg <scottvw@google.com>
|
||||
Sean Burford <sburford@google.com>
|
||||
Sean Chen <oohcode@gmail.com>
|
||||
Sean Chittenden <seanc@joyent.com>
|
||||
Sean Christopherson <sean.j.christopherson@intel.com>
|
||||
Sean Dolphin <Sean.Dolphin@kpcompass.com>
|
||||
Sean Harger <sharger@google.com>
|
||||
Sean Rees <sean@erifax.org>
|
||||
Sebastiaan van Stijn <github@gone.nl>
|
||||
Sebastian Schmidt <yath@google.com>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
||||
Sébastien Paolacci <sebastien.paolacci@gmail.com>
|
||||
Sebastien Williams-Wynn <sebastien@cytora.com>
|
||||
Seiji Takahashi <timaki.st@gmail.com>
|
||||
Sergei Skorobogatov <skorobo@rambler.ru>
|
||||
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
||||
|
@ -1568,6 +1718,7 @@ Sergey Mudrik <sergey.mudrik@gmail.com>
|
|||
Sergey Semin <gray12511@gmail.com>
|
||||
Sergio Luis O. B. Correia <sergio@correia.cc>
|
||||
Sergiusz Bazanski <bazanski@gmail.com>
|
||||
Serhii Aheienko <serhii.aheienko@gmail.com>
|
||||
Seth Hoenig <seth.a.hoenig@gmail.com>
|
||||
Seth Vargo <sethvargo@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>
|
||||
Shengyu Zhang <shengyu.zhang@chaitin.com>
|
||||
Shi Han Ng <shihanng@gmail.com>
|
||||
Shijie Hao <haormj@gmail.com>
|
||||
Shinji Tanaka <shinji.tanaka@gmail.com>
|
||||
Shintaro Kaneko <kaneshin0120@gmail.com>
|
||||
Shivakumar GN <shivakumar.gn@gmail.com>
|
||||
Shivansh Rai <shivansh@freebsd.org>
|
||||
Shun Fan <sfan@google.com>
|
||||
Silvan Jegen <s.jegen@gmail.com>
|
||||
Simon Jefford <simon.jefford@gmail.com>
|
||||
|
@ -1603,6 +1756,7 @@ Stan Schwertly <stan@schwertly.com>
|
|||
Stanislav Afanasev <php.progger@gmail.com>
|
||||
Steeve Morin <steeve.morin@gmail.com>
|
||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||
Stepan Shabalin <neverliberty@gmail.com>
|
||||
Stephan Renatus <srenatus@chef.io>
|
||||
Stéphane Travostino <stephane.travostino@gmail.com>
|
||||
Stephen Lewis <stephen@sock.org.uk>
|
||||
|
@ -1613,6 +1767,7 @@ Stephen Searles <stephens2424@gmail.com>
|
|||
Stephen Weinberg <stephen@q5comm.com>
|
||||
Steve Francia <spf@golang.org>
|
||||
Steve Gilbert <stevegilbert23@gmail.com>
|
||||
Steve LoFurno <slofurno@gmail.com>
|
||||
Steve McCoy <mccoyst@gmail.com>
|
||||
Steve Newman <snewman@google.com>
|
||||
Steve Phillips <elimisteve@gmail.com>
|
||||
|
@ -1621,7 +1776,10 @@ Steven Buss <sbuss@google.com>
|
|||
Steven Elliot Harris <seharris@gmail.com>
|
||||
Steven Erenst <stevenerenst@gmail.com>
|
||||
Steven Hartland <steven.hartland@multiplay.co.uk>
|
||||
Steven Littiebrant <imgroxx@gmail.com>
|
||||
Steven Wilkin <stevenwilkin@gmail.com>
|
||||
Stuart Jansen <sjansen@buscaluz.org>
|
||||
Sue Spence <virtuallysue@gmail.com>
|
||||
Sugu Sougoumarane <ssougou@gmail.com>
|
||||
Suharsh Sivakumar <suharshs@google.com>
|
||||
Sukrit Handa <sukrit.handa@utoronto.ca>
|
||||
|
@ -1634,8 +1792,11 @@ Sven Blumenstein <svbl@google.com>
|
|||
Sylvain Zimmer <sylvain@sylvainzimmer.com>
|
||||
Syohei YOSHIDA <syohex@gmail.com>
|
||||
Szabolcs Nagy <nsz@port70.net>
|
||||
Taavi Kivisik <taavi.kivisik@gmail.com>
|
||||
Tad Fisher <tadfisher@gmail.com>
|
||||
Tad Glines <tad.glines@gmail.com>
|
||||
Tadas Valiukas <tadovas@gmail.com>
|
||||
Taesu Pyo <pyotaesu@gmail.com>
|
||||
Taj Khattra <taj.khattra@gmail.com>
|
||||
Takashi Matsuo <tmatsuo@google.com>
|
||||
Takayoshi Nishida <takayoshi.nishida@gmail.com>
|
||||
|
@ -1644,11 +1805,14 @@ Takuto Ikuta <tikuta@google.com>
|
|||
Takuya Ueda <uedatakuya@gmail.com>
|
||||
Tal Shprecher <tshprecher@gmail.com>
|
||||
Tamir Duberstein <tamird@gmail.com>
|
||||
Tao Shen <shentaoskyking@gmail.com>
|
||||
Tao Wang <twang2218@gmail.com>
|
||||
Tarmigan Casebolt <tarmigan@gmail.com>
|
||||
Taro Aoki <aizu.s1230022@gmail.com>
|
||||
Taru Karttunen <taruti@taruti.net>
|
||||
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
|
||||
Tatsuya Kaneko <m.ddotx.f@gmail.com>
|
||||
Taufiq Rahman <taufiqrx8@gmail.com>
|
||||
Teague Cole <tnc1443@gmail.com>
|
||||
Ted Kornish <golang@tedkornish.com>
|
||||
Tejasvi Nareddy <tejunareddy@gmail.com>
|
||||
|
@ -1664,6 +1828,7 @@ Thomas Alan Copeland <talan.copeland@gmail.com>
|
|||
Thomas Bonfort <thomas.bonfort@gmail.com>
|
||||
Thomas Bouldin <inlined@google.com>
|
||||
Thomas Bruyelle <thomas.bruyelle@gmail.com>
|
||||
Thomas Bushnell, BSG <tbushnell@google.com>
|
||||
Thomas de Zeeuw <thomasdezeeuw@gmail.com>
|
||||
Thomas Desrosiers <thomasdesr@gmail.com>
|
||||
Thomas Habets <habets@google.com>
|
||||
|
@ -1682,6 +1847,7 @@ Tim Henderson <tim.tadh@gmail.com>
|
|||
Tim Hockin <thockin@google.com>
|
||||
Tim Swast <swast@google.com>
|
||||
Tim Wright <tenortim@gmail.com>
|
||||
Tim Xu <xiaoxubeii@gmail.com>
|
||||
Timo Savola <timo.savola@gmail.com>
|
||||
Timo Truyts <alkaloid.btx@gmail.com>
|
||||
Timothy Studd <tim@timstudd.com>
|
||||
|
@ -1705,6 +1871,7 @@ Tom Wilkie <tom@weave.works>
|
|||
Tommy Schaefer <tommy.schaefer@teecom.com>
|
||||
Tomoya Ishizaki <zaq1tomo@gmail.com>
|
||||
Tonis Tiigi <tonistiigi@gmail.com>
|
||||
Tony Reix <tony.reix@bull.net>
|
||||
Tony Walker <walkert.uk@gmail.com>
|
||||
Tor Andersson <tor.andersson@gmail.com>
|
||||
Tormod Erevik Lea <tormodlea@gmail.com>
|
||||
|
@ -1732,7 +1899,9 @@ Tzu-Jung Lee <roylee17@currant.com>
|
|||
Ugorji Nwoke <ugorji@gmail.com>
|
||||
Ulf Holm Nielsen <doktor@dyregod.dk>
|
||||
Ulrich Kunitz <uli.kunitz@gmail.com>
|
||||
Umang Parmar <umangjparmar@gmail.com>
|
||||
Uriel Mangado <uriel@berlinblue.org>
|
||||
Urvil Patel <patelurvil38@gmail.com>
|
||||
Uttam C Pawar <uttam.c.pawar@intel.com>
|
||||
Vadim Grek <vadimprog@gmail.com>
|
||||
Vadim Vygonets <unixdj@gmail.com>
|
||||
|
@ -1740,6 +1909,7 @@ Val Polouchkine <vpolouch@justin.tv>
|
|||
Vega Garcia Luis Alfonso <vegacom@gmail.com>
|
||||
Venil Noronha <veniln@vmware.com>
|
||||
Veselkov Konstantin <kostozyb@gmail.com>
|
||||
Viacheslav Poturaev <vearutop@gmail.com>
|
||||
Victor Chudnovsky <vchudnov@google.com>
|
||||
Victor Vrantchan <vrancean+github@gmail.com>
|
||||
Vignesh Ramachandra <vickyramachandra@gmail.com>
|
||||
|
@ -1750,8 +1920,10 @@ Vincent Vanackere <vincent.vanackere@gmail.com>
|
|||
Vinu Rajashekhar <vinutheraj@gmail.com>
|
||||
Vish Subramanian <vish@google.com>
|
||||
Vishvananda Ishaya <vishvananda@gmail.com>
|
||||
Visweswara R <r.visweswara@gmail.com>
|
||||
Vitor De Mario <vitordemario@gmail.com>
|
||||
Vlad Krasnov <vlad@cloudflare.com>
|
||||
Vladimir Kovpak <cn007b@gmail.com>
|
||||
Vladimir Kuzmin <vkuzmin@uber.com>
|
||||
Vladimir Mihailenco <vladimir.webdev@gmail.com>
|
||||
Vladimir Nikishenko <vova616@gmail.com>
|
||||
|
@ -1763,17 +1935,22 @@ W. Trevor King <wking@tremily.us>
|
|||
Wade Simmons <wade@wades.im>
|
||||
Walter Poupore <wpoupore@google.com>
|
||||
Wander Lairson Costa <wcosta@mozilla.com>
|
||||
Warren Fernandes <warren.f.fernandes@gmail.com>
|
||||
Wayne Ashley Berry <wayneashleyberry@gmail.com>
|
||||
Wedson Almeida Filho <wedsonaf@google.com>
|
||||
Weerasak Chongnguluam <singpor@gmail.com>
|
||||
Wèi Cōngruì <crvv.mail@gmail.com>
|
||||
Wei Fu <fhfuwei@163.com>
|
||||
Wei Guangjing <vcc.163@gmail.com>
|
||||
Wei Xiao <wei.xiao@arm.com>
|
||||
Weichao Tang <tevic.tt@gmail.com>
|
||||
Wembley G. Leach, Jr <wembley.gl@gmail.com>
|
||||
Wil Selwood <wselwood@gmail.com>
|
||||
Wilfried Teiken <wteiken@google.com>
|
||||
Will Beason <willbeason@gmail.com>
|
||||
Will Chan <willchan@google.com>
|
||||
Will Faught <will.faught@gmail.com>
|
||||
Will Morrow <wmorrow.qdt@qualcommdatacenter.com>
|
||||
Will Norris <willnorris@google.com>
|
||||
Will Storey <will@summercat.com>
|
||||
Willem van der Schyff <willemvds@gmail.com>
|
||||
|
@ -1806,6 +1983,7 @@ Yestin Sun <ylh@pdx.edu>
|
|||
Yesudeep Mangalapilly <yesudeep@google.com>
|
||||
Yissakhar Z. Beck <yissakhar.beck@gmail.com>
|
||||
Yo-An Lin <yoanlin93@gmail.com>
|
||||
Yohei Takeda <yo.tak0812@gmail.com>
|
||||
Yongjian Xu <i3dmaster@gmail.com>
|
||||
Yorman Arias <cixtords@gmail.com>
|
||||
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 Xuan Zhang <zyxsh@cn.ibm.com>
|
||||
Yuji Yaginuma <yuuji.yaginuma@gmail.com>
|
||||
Yuki OKUSHI <huyuumi.dev@gmail.com>
|
||||
Yuki Yugui Sonoda <yugui@google.com>
|
||||
Yukihiro Nishinaka <6elpinal@gmail.com>
|
||||
Yury Smolsky <yury@smolsky.by>
|
||||
|
@ -1824,12 +2003,14 @@ Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
|
|||
Zac Bergquist <zbergquist99@gmail.com>
|
||||
Zach Bintliff <zbintliff@gmail.com>
|
||||
Zach Gershman <zachgersh@gmail.com>
|
||||
Zachary Amsden <zach@thundertoken.com>
|
||||
Zachary Gershman <zgershman@pivotal.io>
|
||||
Zak <zrjknill@gmail.com>
|
||||
Zakatell Kanda <hi@zkanda.io>
|
||||
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
|
||||
Zev Goldstein <zev.goldstein@gmail.com>
|
||||
Zheng Dayu <davidzheng23@gmail.com>
|
||||
Zheng Xu <zheng.xu@arm.com>
|
||||
Zhengyu He <hzy@google.com>
|
||||
Zhongpeng Lin <zplin@uber.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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Pad_cgo_0 [8]uint8
|
||||
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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Pad_cgo_0 [8]uint8
|
||||
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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Rdev uint32
|
||||
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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Rdev uint32
|
||||
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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Rdev uint32
|
||||
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), type Dirent struct, Fileno uint32
|
||||
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, Ctimespec Timespec
|
||||
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, Ino uint32
|
||||
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, Rdev uint32
|
||||
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
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
|
|
@ -922,13 +922,13 @@ New files that you contribute should use the standard copyright header:
|
|||
</p>
|
||||
|
||||
<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
|
||||
// license that can be found in the LICENSE file.
|
||||
</pre>
|
||||
|
||||
<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.
|
||||
Do not update the copyright year on files that you change.
|
||||
</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.
|
||||
</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>
|
||||
|
||||
<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.
|
||||
</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>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -456,3 +456,15 @@ each collection, summarizing the amount of memory collected
|
|||
and the length of the pause.</li>
|
||||
<li>GODEBUG=schedtrace=X prints scheduling events every X milliseconds.</li>
|
||||
</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}
|
||||
&{a:7 b:-2.35 c:abc def}
|
||||
&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>
|
||||
<p>
|
||||
(Note the ampersands.)
|
||||
|
@ -1733,7 +1733,7 @@ fmt.Printf("%T\n", timeZone)
|
|||
prints
|
||||
</p>
|
||||
<pre>
|
||||
map[string] int
|
||||
map[string]int
|
||||
</pre>
|
||||
<p>
|
||||
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>
|
||||
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
|
||||
effort if we convert the <code>Sequence</code> to a plain
|
||||
work that <code>Sprint</code> already does for slices.
|
||||
(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>.
|
||||
</p>
|
||||
<pre>
|
||||
func (s Sequence) String() string {
|
||||
s = s.Copy()
|
||||
sort.Sort(s)
|
||||
return fmt.Sprint([]int(s))
|
||||
}
|
||||
|
@ -2138,6 +2140,7 @@ type Sequence []int
|
|||
|
||||
// Method for printing - sorts the elements before printing
|
||||
func (s Sequence) String() string {
|
||||
s = s.Copy()
|
||||
sort.IntSlice(s).Sort()
|
||||
return fmt.Sprint([]int(s))
|
||||
}
|
||||
|
|
|
@ -400,6 +400,16 @@ details. <!-- CL 126275, CL 127156, CL 122217, CL 122575, CL 123177 -->
|
|||
information.
|
||||
</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>
|
||||
|
||||
<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>
|
||||
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.
|
||||
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
|
||||
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">promise of compatibility</a>.
|
||||
We expect almost all Go programs to continue to compile and run as before.
|
||||
</p>
|
||||
|
||||
|
@ -37,19 +37,268 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
There are no changes to the language specification.
|
||||
</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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>GOCACHE=off</code> to disable the
|
||||
<a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a>
|
||||
has no effect in Go 1.12.
|
||||
<code>GOCACHE=off</code> will cause <code>go</code> commands that write to the
|
||||
cache to fail.
|
||||
</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>
|
||||
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.
|
||||
</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>
|
||||
|
||||
<h3 id="tls_1_3">TLS 1.3</h3>
|
||||
|
||||
<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>
|
||||
|
||||
<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.
|
||||
</p>
|
||||
|
||||
<!-- CL 142717: https://golang.org/cl/142717: cmd/compile: remove obsolete "safe" mode -->
|
||||
<!-- 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 -->
|
||||
<!-- 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>
|
||||
<!-- TODO: CL 115677: https://golang.org/cl/115677: cmd/vet: check embedded field tags too -->
|
||||
|
||||
<dl id="bufio"><dt><a href="/pkg/bufio/">bufio</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 61511 -->
|
||||
TODO: <a href="https://golang.org/cl/61511">https://golang.org/cl/61511</a>: support frame-pointer for arm64
|
||||
<p><!-- CL 149297 -->
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<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><!-- 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>
|
||||
|
||||
</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>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<p><!-- CL 141397 -->
|
||||
TODO: <a href="https://golang.org/cl/141397">https://golang.org/cl/141397</a>: remove CLI support
|
||||
<p><!-- CL 134075 -->
|
||||
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>
|
||||
|
||||
</dl><!-- godoc, cmd/godoc -->
|
||||
</dl><!-- go/token -->
|
||||
|
||||
<dl id="image"><dt><a href="/pkg/image/">image</a></dt>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</dl><!-- math/bits -->
|
||||
|
||||
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 113997 -->
|
||||
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
|
||||
<p><!-- CL 146659 -->
|
||||
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><!-- 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 id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
|
||||
<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 -->
|
||||
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><!-- 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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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><!-- 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><!-- 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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<p><!-- CL 135395 -->
|
||||
TODO: <a href="https://golang.org/cl/135395">https://golang.org/cl/135395</a>: use MADV_FREE on Linux if available
|
||||
<p><!-- CL 139784 -->
|
||||
<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>
|
||||
|
||||
</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>
|
||||
<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 -->
|
||||
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>
|
||||
|
||||
</dl><!-- strings -->
|
||||
|
||||
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 125456 -->
|
||||
TODO: <a href="https://golang.org/cl/125456">https://golang.org/cl/125456</a>: implement Unix Socket for Windows
|
||||
<p><!-- CL 138595 -->
|
||||
64-bit inodes are now supported on FreeBSD 12. Some types have been adjusted accordingly.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 138595 -->
|
||||
TODO: <a href="https://golang.org/cl/138595">https://golang.org/cl/138595</a>: FreeBSD 12 ino64 support
|
||||
<p><!-- CL 125456 -->
|
||||
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>
|
||||
|
||||
</dl><!-- syscall -->
|
||||
|
||||
<dl id="syscall/js"><dt><a href="/pkg/syscall/js/">syscall/js</a></dt>
|
||||
<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 -->
|
||||
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><!-- 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><!-- 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>
|
||||
|
||||
</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>
|
||||
<dd>
|
||||
<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>
|
||||
|
||||
</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
|
||||
<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.
|
||||
</p>
|
||||
|
||||
|
|
|
@ -418,8 +418,12 @@ func twoprint() {
|
|||
</pre>
|
||||
|
||||
<p>
|
||||
calling <code>twoprint</code> causes <code>"hello, world"</code> to be printed twice.
|
||||
The first call to <code>doprint</code> runs <code>setup</code> once.
|
||||
calling <code>twoprint</code> will call <code>setup</code> exactly
|
||||
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>
|
||||
|
||||
<h2>Incorrect synchronization</h2>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!--{
|
||||
"Title": "The Go Programming Language Specification",
|
||||
"Subtitle": "Version of October 23, 2018",
|
||||
"Subtitle": "Version of November 16, 2018",
|
||||
"Path": "/ref/spec"
|
||||
}-->
|
||||
|
||||
|
@ -823,6 +823,7 @@ particular architecture.
|
|||
<p>
|
||||
A <i>string type</i> represents the set of string values.
|
||||
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,
|
||||
it is impossible to change the contents of a string.
|
||||
The predeclared string type is <code>string</code>;
|
||||
|
@ -830,7 +831,7 @@ it is a <a href="#Type_definitions">defined type</a>.
|
|||
</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 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>
|
||||
|
@ -846,8 +847,7 @@ string, <code>&s[i]</code> is invalid.
|
|||
<p>
|
||||
An array is a numbered sequence of elements of a single
|
||||
type, called the element type.
|
||||
The number of elements is called the length and is never
|
||||
negative.
|
||||
The number of elements is called the length of the array and is never negative.
|
||||
</p>
|
||||
|
||||
<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
|
||||
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.
|
||||
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>.
|
||||
</p>
|
||||
|
||||
|
@ -891,8 +892,7 @@ SliceType = "[" "]" ElementType .
|
|||
</pre>
|
||||
|
||||
<p>
|
||||
Like arrays, slices are indexable and have a length. The length of a
|
||||
slice <code>s</code> can be discovered by the built-in function
|
||||
The length of a 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
|
||||
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
|
||||
|
@ -1348,8 +1348,9 @@ ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
|
|||
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>bidirectional</i>.
|
||||
A channel may be constrained only to send or only to receive by explicit
|
||||
<a href="#Conversions">conversion</a> or <a href="#Assignments">assignment</a>.
|
||||
A channel may be constrained only to send or only to receive by
|
||||
<a href="#Assignments">assignment</a> or
|
||||
explicit <a href="#Conversions">conversion</a>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
@ -3624,7 +3625,7 @@ For signed integers, the operations <code>+</code>,
|
|||
<code>-</code>, <code>*</code>, <code>/</code>, and <code><<</code> may legally
|
||||
overflow and the resulting value exists and is deterministically defined
|
||||
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
|
||||
not occur. For instance, it may not assume that <code>x < x + 1</code> is always true.
|
||||
</p>
|
||||
|
|
|
@ -271,6 +271,39 @@ which describes some essential concepts about using the Go tools.
|
|||
</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>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -28,11 +28,18 @@ func (s Sequence) Swap(i, j int) {
|
|||
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.
|
||||
func (s Sequence) String() string {
|
||||
s = s.Copy() // Make a copy; don't overwrite argument.
|
||||
sort.Sort(s)
|
||||
str := "["
|
||||
for i, elem := range s {
|
||||
for i, elem := range s { // Loop is O(N²); will fix that in next example.
|
||||
if i > 0 {
|
||||
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>If it is determined, in consultation with the submitter, that a CVE-ID is
|
||||
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
|
||||
revision. These fixes are not yet committed to the public repository.</li>
|
||||
<li>A notification is sent to the
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
# Consult https://www.iana.org/time-zones for the latest versions.
|
||||
|
||||
# Versions to use.
|
||||
CODE=2018e
|
||||
DATA=2018e
|
||||
CODE=2018i
|
||||
DATA=2018i
|
||||
|
||||
set -e
|
||||
rm -rf work
|
||||
|
|
Binary file not shown.
|
@ -121,12 +121,19 @@ func TestReportsTypeErrors(t *testing.T) {
|
|||
"issue16591.go",
|
||||
"issue18452.go",
|
||||
"issue18889.go",
|
||||
"issue26745.go",
|
||||
"issue28721.go",
|
||||
} {
|
||||
check(t, file)
|
||||
}
|
||||
|
||||
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]))`,
|
||||
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) {
|
||||
|
@ -478,7 +496,7 @@ func testOne(t *testing.T, pt ptrTest) {
|
|||
|
||||
cmd := exec.Command("go", "build")
|
||||
cmd.Dir = src
|
||||
cmd.Env = addEnv("GOPATH", gopath)
|
||||
cmd.Env = append(os.Environ(), "GOPATH="+gopath)
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
|
@ -550,16 +568,5 @@ func testOne(t *testing.T, pt ptrTest) {
|
|||
}
|
||||
|
||||
func cgocheckEnv(val string) []string {
|
||||
return addEnv("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
|
||||
return append(os.Environ(), "GODEBUG=cgocheck="+val)
|
||||
}
|
||||
|
|
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)
|
||||
n := 0
|
||||
name := []string{
|
||||
"runtime.call16",
|
||||
"runtime.cgocallbackg1",
|
||||
"runtime.cgocallbackg",
|
||||
"runtime.cgocallback_gofunc",
|
||||
|
@ -193,9 +192,6 @@ func testCallbackCallers(t *testing.T) {
|
|||
"testing.tRunner",
|
||||
"runtime.goexit",
|
||||
}
|
||||
if unsafe.Sizeof((*byte)(nil)) == 8 {
|
||||
name[0] = "runtime.call32"
|
||||
}
|
||||
nestedCall(func() {
|
||||
n = runtime.Callers(4, pc)
|
||||
})
|
||||
|
|
|
@ -93,6 +93,8 @@ func Test23356(t *testing.T) { test23356(t) }
|
|||
func Test26066(t *testing.T) { test26066(t) }
|
||||
func Test26213(t *testing.T) { test26213(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 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.
|
||||
|
||||
// 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.
|
||||
|
||||
package cgotest
|
||||
|
@ -10,11 +11,16 @@ package cgotest
|
|||
/*
|
||||
#include <complex.h>
|
||||
|
||||
#define issue28772Constant 1
|
||||
|
||||
static void issue28545F(char **p, int n, complex double a) {}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const issue28772Constant = C.issue28772Constant
|
||||
|
||||
func issue28545G(p **C.char) {
|
||||
C.issue28545F(p, -1, (0))
|
||||
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
|
||||
|
||||
/*
|
||||
#include "issue4339.h"
|
||||
// We've historically permitted #include <>, so test it here. Issue 29333.
|
||||
#include <issue4339.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ func Test(t *testing.T) {
|
|||
// Brittle: the assertion may fail spuriously when the algorithm
|
||||
// changes, but should remain stable otherwise.
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func TestTSAN(t *testing.T) {
|
||||
|
|
|
@ -911,3 +911,9 @@ func TestGlobal(t *testing.T) {
|
|||
func TestTestInstalledShared(t *testing.T) {
|
||||
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
|
||||
testdata
|
||||
+
|
||||
xcoff
|
||||
testdata
|
||||
+
|
||||
gofmt
|
||||
gofmt.go
|
||||
gofmt_test.go
|
||||
|
@ -157,7 +154,7 @@ go src=..
|
|||
trace
|
||||
testdata
|
||||
+
|
||||
traceparser
|
||||
xcoff
|
||||
testdata
|
||||
+
|
||||
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";
|
||||
callback(err);
|
||||
},
|
||||
read(fd, buffer, offset, length, position, callback) {
|
||||
const err = new Error("not implemented");
|
||||
err.code = "ENOSYS";
|
||||
callback(err);
|
||||
},
|
||||
fsync(fd, callback) {
|
||||
callback(null);
|
||||
},
|
||||
|
@ -82,8 +87,8 @@
|
|||
this._exitPromise = new Promise((resolve) => {
|
||||
this._resolveExitPromise = resolve;
|
||||
});
|
||||
this._pendingCallback = null;
|
||||
this._callbackTimeouts = new Map();
|
||||
this._pendingEvent = null;
|
||||
this._scheduledTimeouts = new Map();
|
||||
this._nextCallbackTimeoutID = 1;
|
||||
|
||||
const mem = () => {
|
||||
|
@ -199,7 +204,7 @@
|
|||
this.importObject = {
|
||||
go: {
|
||||
// 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).
|
||||
// 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);
|
||||
},
|
||||
|
||||
// func scheduleCallback(delay int64) int32
|
||||
"runtime.scheduleCallback": (sp) => {
|
||||
// func scheduleTimeoutEvent(delay int64) int32
|
||||
"runtime.scheduleTimeoutEvent": (sp) => {
|
||||
const id = this._nextCallbackTimeoutID;
|
||||
this._nextCallbackTimeoutID++;
|
||||
this._callbackTimeouts.set(id, setTimeout(
|
||||
this._scheduledTimeouts.set(id, setTimeout(
|
||||
() => { this._resume(); },
|
||||
getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
|
||||
));
|
||||
mem().setInt32(sp + 16, id, true);
|
||||
},
|
||||
|
||||
// func clearScheduledCallback(id int32)
|
||||
"runtime.clearScheduledCallback": (sp) => {
|
||||
// func clearTimeoutEvent(id int32)
|
||||
"runtime.clearTimeoutEvent": (sp) => {
|
||||
const id = mem().getInt32(sp + 8, true);
|
||||
clearTimeout(this._callbackTimeouts.get(id));
|
||||
this._callbackTimeouts.delete(id);
|
||||
clearTimeout(this._scheduledTimeouts.get(id));
|
||||
this._scheduledTimeouts.delete(id);
|
||||
},
|
||||
|
||||
// func getRandomData(r []byte)
|
||||
|
@ -415,7 +420,7 @@
|
|||
|
||||
_resume() {
|
||||
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();
|
||||
if (this.exited) {
|
||||
|
@ -423,13 +428,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
_makeCallbackHelper(id) {
|
||||
_makeFuncWrapper(id) {
|
||||
const go = this;
|
||||
return function () {
|
||||
const cb = { id: id, this: this, args: arguments };
|
||||
go._pendingCallback = cb;
|
||||
const event = { id: id, this: this, args: arguments };
|
||||
go._pendingEvent = event;
|
||||
go._resume();
|
||||
return cb.result;
|
||||
return event.result;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -442,13 +447,13 @@
|
|||
|
||||
const go = new Go();
|
||||
go.argv = process.argv.slice(2);
|
||||
go.env = process.env;
|
||||
go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env);
|
||||
go.exit = process.exit;
|
||||
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) {
|
||||
// deadlock, make Go print error and stack traces
|
||||
go._pendingCallback = { id: 0 };
|
||||
go._pendingEvent = { id: 0 };
|
||||
go._resume();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux dragonfly freebsd openbsd solaris
|
||||
// +build linux dragonfly openbsd solaris
|
||||
|
||||
package tar
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin netbsd
|
||||
// +build darwin freebsd netbsd
|
||||
|
||||
package tar
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
|
|||
return len(p), nil
|
||||
}
|
||||
|
||||
func min(x, y int) int {
|
||||
func min(x, y int64) int64 {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
|||
if len(parts) > 0 {
|
||||
skipBytes := off - parts[0].off
|
||||
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)
|
||||
n += repeat
|
||||
if n == len(p) {
|
||||
|
|
|
@ -33,8 +33,8 @@ type Reader struct {
|
|||
rd io.Reader // reader provided by the client
|
||||
r, w int // buf read and write positions
|
||||
err error
|
||||
lastByte int
|
||||
lastRuneSize int
|
||||
lastByte int // last byte read for UnreadByte; -1 means invalid
|
||||
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
|
||||
}
|
||||
|
||||
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
|
||||
// also returns an error explaining why the read is short. The error is
|
||||
// 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) {
|
||||
if n < 0 {
|
||||
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 {
|
||||
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.
|
||||
// The bytes are taken from at most one Read on the underlying Reader,
|
||||
// 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).
|
||||
// At EOF, the count will be zero and err will be io.EOF.
|
||||
func (b *Reader) Read(p []byte) (n int, err error) {
|
||||
n = len(p)
|
||||
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 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 {
|
||||
if b.lastByte < 0 || b.r == 0 && b.w > 0 {
|
||||
return ErrInvalidUnreadByte
|
||||
|
@ -288,8 +297,8 @@ func (b *Reader) ReadRune() (r rune, size int, err error) {
|
|||
return r, size, nil
|
||||
}
|
||||
|
||||
// UnreadRune unreads the last rune. If the most recent read operation on
|
||||
// the buffer was not a ReadRune, UnreadRune returns an error. (In this
|
||||
// UnreadRune unreads the last rune. If the most recent method called on
|
||||
// the Reader was not a ReadRune, UnreadRune returns an error. (In this
|
||||
// regard it is stricter than UnreadByte, which will unread the last byte
|
||||
// from any read operation.)
|
||||
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) {
|
||||
segments := []string{"Hello, ", "world"}
|
||||
r := NewReader(&StringReader{data: segments})
|
||||
|
|
|
@ -68,7 +68,7 @@ func (b *Buffer) String() string {
|
|||
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 }
|
||||
|
||||
// Len returns the number of bytes of the unread portion of the buffer;
|
||||
|
|
|
@ -298,6 +298,12 @@ func ExampleReplace() {
|
|||
// 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() {
|
||||
rs := bytes.Runes([]byte("go gopher"))
|
||||
for _, r := range rs {
|
||||
|
|
|
@ -442,13 +442,8 @@ func (w *Walker) Import(name string) (*types.Package, error) {
|
|||
}
|
||||
w.imported[name] = &importing
|
||||
|
||||
root := w.root
|
||||
if strings.HasPrefix(name, "golang_org/x/") {
|
||||
root = filepath.Join(root, "vendor")
|
||||
}
|
||||
|
||||
// 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() {
|
||||
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.
|
||||
-trimpath prefix
|
||||
Remove prefix from recorded source file paths.
|
||||
-gensymabis
|
||||
Write symbol ABI information to output file. Don't assemble.
|
||||
Input language:
|
||||
|
||||
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)
|
||||
|
||||
err := tryParse(t, func() {
|
||||
parser.start(lex.Tokenize(test.input))
|
||||
parser.line()
|
||||
parser.Parse()
|
||||
})
|
||||
|
||||
switch {
|
||||
|
|
|
@ -122,6 +122,49 @@ func TestS390XOperandParser(t *testing.T) {
|
|||
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 {
|
||||
input, output string
|
||||
}
|
||||
|
|
|
@ -91,7 +91,23 @@ func (p *Parser) pos() src.XPos {
|
|||
}
|
||||
|
||||
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 {
|
||||
return nil, false
|
||||
|
@ -100,8 +116,33 @@ func (p *Parser) Parse() (*obj.Prog, bool) {
|
|||
return p.firstProg, true
|
||||
}
|
||||
|
||||
// WORD [ arg {, arg} ] (';' | '\n')
|
||||
func (p *Parser) line() bool {
|
||||
// ParseSymABIs parses p's assembly code to find text symbol
|
||||
// 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.
|
||||
var tok lex.ScanToken
|
||||
for {
|
||||
|
@ -114,24 +155,29 @@ func (p *Parser) line() bool {
|
|||
case '\n', ';':
|
||||
continue
|
||||
case scanner.EOF:
|
||||
return false
|
||||
return "", "", nil, false
|
||||
}
|
||||
break
|
||||
}
|
||||
// First item must be an identifier.
|
||||
if tok != scanner.Ident {
|
||||
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()
|
||||
var cond string
|
||||
operands := make([][]lex.Token, 0, 3)
|
||||
word, cond = p.lex.Text(), ""
|
||||
operands = scratch[:0]
|
||||
// Zero or more comma-separated operands, one per loop.
|
||||
nesting := 0
|
||||
colon := -1
|
||||
for tok != '\n' && tok != ';' {
|
||||
// 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 {
|
||||
tok = p.lex.Next()
|
||||
if len(operands) == 0 && len(items) == 0 {
|
||||
|
@ -148,12 +194,12 @@ func (p *Parser) line() bool {
|
|||
if tok == ':' {
|
||||
// Labels.
|
||||
p.pendingLabels = append(p.pendingLabels, word)
|
||||
return true
|
||||
goto next
|
||||
}
|
||||
}
|
||||
if tok == scanner.EOF {
|
||||
p.errorf("unexpected EOF")
|
||||
return false
|
||||
return "", "", nil, false
|
||||
}
|
||||
// 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.
|
||||
|
@ -162,7 +208,7 @@ func (p *Parser) line() bool {
|
|||
// Remember this location so we can swap the operands below.
|
||||
if colon >= 0 {
|
||||
p.errorf("invalid ':' in operand")
|
||||
return true
|
||||
return word, cond, operands, true
|
||||
}
|
||||
colon = len(operands)
|
||||
}
|
||||
|
@ -188,16 +234,7 @@ func (p *Parser) line() bool {
|
|||
p.errorf("missing operand")
|
||||
}
|
||||
}
|
||||
if p.pseudo(word, operands) {
|
||||
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
|
||||
return word, cond, operands, true
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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) {
|
||||
p.input = operand
|
||||
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.
|
||||
// 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).
|
||||
|
|
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> VRT,VRA,VRB,VRC
|
||||
VPERM V3, V2, V1, V0
|
||||
VPERMXOR V3, V2, V1, V0
|
||||
|
||||
// Vector bit permute, VX-form
|
||||
// <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")
|
||||
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")
|
||||
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -36,7 +36,7 @@ func main() {
|
|||
|
||||
ctxt := obj.Linknew(architecture.LinkArch)
|
||||
if *flags.PrintOut {
|
||||
ctxt.Debugasm = true
|
||||
ctxt.Debugasm = 1
|
||||
}
|
||||
ctxt.Flag_dynlink = *flags.Dynlink
|
||||
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
|
||||
|
@ -53,8 +53,10 @@ func main() {
|
|||
defer bio.MustClose(out)
|
||||
buf := bufio.NewWriter(bio.MustWriter(out))
|
||||
|
||||
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
|
||||
fmt.Fprintf(buf, "!\n")
|
||||
if !*flags.SymABIs {
|
||||
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
|
||||
fmt.Fprintf(buf, "!\n")
|
||||
}
|
||||
|
||||
var ok, diag bool
|
||||
var failedFile string
|
||||
|
@ -65,16 +67,22 @@ func main() {
|
|||
diag = true
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
pList := new(obj.Plist)
|
||||
pList.Firstpc, ok = parser.Parse()
|
||||
if *flags.SymABIs {
|
||||
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 {
|
||||
failedFile = f
|
||||
break
|
||||
}
|
||||
// reports errors to parser.Errorf
|
||||
obj.Flushplist(ctxt, pList, nil, "")
|
||||
}
|
||||
if ok {
|
||||
if ok && !*flags.SymABIs {
|
||||
obj.WriteObjFile(ctxt, buf)
|
||||
}
|
||||
if !ok || diag {
|
||||
|
|
|
@ -145,6 +145,7 @@ func (f *File) ParseGo(name string, src []byte) {
|
|||
if f.Ref == nil {
|
||||
f.Ref = make([]*Ref, 0, 8)
|
||||
}
|
||||
f.walk(ast2, ctxProg, (*File).validateIdents)
|
||||
f.walk(ast2, ctxProg, (*File).saveExprs)
|
||||
|
||||
// Accumulate exported functions.
|
||||
|
@ -181,6 +182,14 @@ func commentText(g *ast.CommentGroup) string {
|
|||
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.
|
||||
func (f *File) saveExprs(x interface{}, context astContext) {
|
||||
switch x := x.(type) {
|
||||
|
@ -191,6 +200,18 @@ func (f *File) saveExprs(x interface{}, context astContext) {
|
|||
}
|
||||
case *ast.CallExpr:
|
||||
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
|
||||
jweak
|
||||
|
||||
3. The EGLDisplay type from the EGL API.
|
||||
|
||||
These types are uintptr on the Go side because they would otherwise
|
||||
confuse the Go garbage collector; they are sometimes not really
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
Usage:
|
||||
|
|
|
@ -9,7 +9,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/xcoff"
|
||||
"debug/dwarf"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
|
@ -21,6 +20,7 @@ import (
|
|||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"internal/xcoff"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -91,7 +91,13 @@ func (p *Package) addToFlag(flag string, args []string) {
|
|||
p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
|
||||
if flag == "CFLAGS" {
|
||||
// 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.
|
||||
cref.Name.C = cname(cref.Name.Go)
|
||||
}
|
||||
|
||||
var conv typeConv
|
||||
conv.Init(p.PtrSize, p.IntSize)
|
||||
|
||||
p.loadDefines(f)
|
||||
p.typedefs = map[string]bool{}
|
||||
p.typedefList = nil
|
||||
|
@ -171,15 +181,17 @@ func (p *Package) Translate(f *File) {
|
|||
for len(p.typedefs) > numTypedefs {
|
||||
numTypedefs = len(p.typedefs)
|
||||
// Also ask about any typedefs we've seen so far.
|
||||
for _, a := range p.typedefList {
|
||||
f.Name[a] = &Name{
|
||||
Go: a,
|
||||
C: a,
|
||||
for _, info := range p.typedefList {
|
||||
n := &Name{
|
||||
Go: info.typedef,
|
||||
C: info.typedef,
|
||||
}
|
||||
f.Name[info.typedef] = n
|
||||
f.NamePos[n] = info.pos
|
||||
}
|
||||
needType := p.guessKinds(f)
|
||||
if len(needType) > 0 {
|
||||
p.loadDWARF(f, needType)
|
||||
p.loadDWARF(f, &conv, needType)
|
||||
}
|
||||
|
||||
// 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
|
||||
// by gcc to learn the details of the constants, variables, and types
|
||||
// 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
|
||||
// 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
|
||||
|
@ -573,7 +585,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
|
|||
fatalf("malformed __cgo__ name: %s", name)
|
||||
}
|
||||
types[i] = t.Type
|
||||
p.recordTypedefs(t.Type)
|
||||
p.recordTypedefs(t.Type, f.NamePos[names[i]])
|
||||
}
|
||||
if e.Tag != dwarf.TagCompileUnit {
|
||||
r.SkipChildren()
|
||||
|
@ -581,8 +593,6 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
|
|||
}
|
||||
|
||||
// Record types and typedef information.
|
||||
var conv typeConv
|
||||
conv.Init(p.PtrSize, p.IntSize)
|
||||
for i, n := range names {
|
||||
if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
|
||||
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.
|
||||
func (p *Package) recordTypedefs(dtype dwarf.Type) {
|
||||
p.recordTypedefs1(dtype, map[dwarf.Type]bool{})
|
||||
func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
@ -660,23 +671,23 @@ func (p *Package) recordTypedefs1(dtype dwarf.Type, visited map[dwarf.Type]bool)
|
|||
}
|
||||
if !p.typedefs[dt.Name] {
|
||||
p.typedefs[dt.Name] = true
|
||||
p.typedefList = append(p.typedefList, dt.Name)
|
||||
p.recordTypedefs1(dt.Type, visited)
|
||||
p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
|
||||
p.recordTypedefs1(dt.Type, pos, visited)
|
||||
}
|
||||
case *dwarf.PtrType:
|
||||
p.recordTypedefs1(dt.Type, visited)
|
||||
p.recordTypedefs1(dt.Type, pos, visited)
|
||||
case *dwarf.ArrayType:
|
||||
p.recordTypedefs1(dt.Type, visited)
|
||||
p.recordTypedefs1(dt.Type, pos, visited)
|
||||
case *dwarf.QualType:
|
||||
p.recordTypedefs1(dt.Type, visited)
|
||||
p.recordTypedefs1(dt.Type, pos, visited)
|
||||
case *dwarf.FuncType:
|
||||
p.recordTypedefs1(dt.ReturnType, visited)
|
||||
p.recordTypedefs1(dt.ReturnType, pos, visited)
|
||||
for _, a := range dt.ParamType {
|
||||
p.recordTypedefs1(a, visited)
|
||||
p.recordTypedefs1(a, pos, visited)
|
||||
}
|
||||
case *dwarf.StructType:
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
// 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 {
|
||||
needsUnsafe := false
|
||||
// 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.
|
||||
var sbCheck bytes.Buffer
|
||||
for i, param := range params {
|
||||
origArg := args[i]
|
||||
arg, nu := p.mangle(f, &args[i])
|
||||
if nu {
|
||||
needsUnsafe = true
|
||||
|
@ -886,7 +911,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -900,7 +925,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
|||
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)
|
||||
}
|
||||
|
||||
|
@ -941,7 +966,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
|||
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
|
||||
// might contain a pointer.
|
||||
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
|
||||
// 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.
|
||||
func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
|
||||
switch t := t.(type) {
|
||||
|
@ -1095,15 +1120,20 @@ func (p *Package) mangle(f *File, arg *ast.Expr) (ast.Expr, bool) {
|
|||
return *arg, needsUnsafe
|
||||
}
|
||||
|
||||
// checkIndex checks whether arg the form &a[i], possibly inside type
|
||||
// conversions. If so, it writes
|
||||
// checkIndex checks whether arg has the form &a[i], possibly inside
|
||||
// type conversions. If so, then in the general case it writes
|
||||
// _cgoIndexNN := a
|
||||
// _cgoNN := &cgoIndexNN[i] // with type conversions, if any
|
||||
// to sb, and writes
|
||||
// _cgoCheckPointer(_cgoNN, _cgoIndexNN)
|
||||
// to sbCheck, and returns true. This tells _cgoCheckPointer to check
|
||||
// the complete contents of the slice or array being indexed, but no
|
||||
// other part of the memory allocation.
|
||||
// to sbCheck, and returns true. If a is a simple variable or field reference,
|
||||
// it writes
|
||||
// _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 {
|
||||
// Strip type conversions.
|
||||
x := arg
|
||||
|
@ -1123,19 +1153,29 @@ func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) boo
|
|||
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
|
||||
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
|
||||
|
||||
fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, _cgoIndex%d); ", i, i)
|
||||
fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// checkAddr checks whether arg has the form &x, possibly inside type
|
||||
// conversions. If so it writes
|
||||
// conversions. If so, it writes
|
||||
// _cgoBaseNN := &x
|
||||
// _cgoNN := _cgoBaseNN // with type conversions, if any
|
||||
// to sb, and writes
|
||||
|
@ -1158,11 +1198,11 @@ func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool
|
|||
return false
|
||||
}
|
||||
|
||||
fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtLine(*px))
|
||||
fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
|
||||
|
||||
origX := *px
|
||||
*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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (p *Package) isType(t ast.Expr) bool {
|
||||
switch t := t.(type) {
|
||||
|
@ -1214,7 +1254,7 @@ func (p *Package) isType(t ast.Expr) bool {
|
|||
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 {
|
||||
switch x := x.(type) {
|
||||
case *ast.BasicLit:
|
||||
|
@ -1232,7 +1272,8 @@ func (p *Package) isConst(f *File, x ast.Expr) bool {
|
|||
return x.Name == "nil" ||
|
||||
strings.HasPrefix(x.Name, "_Ciconst_") ||
|
||||
strings.HasPrefix(x.Name, "_Cfconst_") ||
|
||||
strings.HasPrefix(x.Name, "_Csconst_")
|
||||
strings.HasPrefix(x.Name, "_Csconst_") ||
|
||||
consts[x.Name]
|
||||
case *ast.UnaryExpr:
|
||||
return p.isConst(f, x.X)
|
||||
case *ast.BinaryExpr:
|
||||
|
@ -1254,6 +1295,17 @@ func (p *Package) isConst(f *File, x ast.Expr) bool {
|
|||
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
|
||||
// rewritten to use _cgo_unsafe.Pointer instead.
|
||||
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.
|
||||
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" {
|
||||
repl = "(" + repl + ")"
|
||||
}
|
||||
|
@ -1481,6 +1546,17 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.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.
|
||||
// It uses $CC if set, or else $GCC, or else the compiler recorded
|
||||
// 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")
|
||||
nl := len(nargs)
|
||||
nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
|
||||
|
||||
if *debugGcc {
|
||||
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.
|
||||
type typeConv struct {
|
||||
// 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.
|
||||
ptrs map[dwarf.Type][]*Type
|
||||
ptrs map[string][]*Type
|
||||
// Keys of ptrs in insertion order (deterministic worklist)
|
||||
// ptrKeys contains exactly the keys in ptrs.
|
||||
ptrKeys []dwarf.Type
|
||||
|
@ -2026,8 +2104,8 @@ var unionWithPointer = make(map[ast.Expr]bool)
|
|||
func (c *typeConv) Init(ptrSize, intSize int64) {
|
||||
c.ptrSize = ptrSize
|
||||
c.intSize = intSize
|
||||
c.m = make(map[dwarf.Type]*Type)
|
||||
c.ptrs = make(map[dwarf.Type][]*Type)
|
||||
c.m = make(map[string]*Type)
|
||||
c.ptrs = make(map[string][]*Type)
|
||||
c.getTypeIDs = make(map[string]bool)
|
||||
c.bool = c.Ident("bool")
|
||||
c.byte = c.Ident("byte")
|
||||
|
@ -2135,11 +2213,12 @@ func (c *typeConv) FinishType(pos token.Pos) {
|
|||
// Keep looping until they're all done.
|
||||
for len(c.ptrKeys) > 0 {
|
||||
dtype := c.ptrKeys[0]
|
||||
dtypeKey := dtype.String()
|
||||
c.ptrKeys = c.ptrKeys[1:]
|
||||
ptrs := c.ptrs[dtype]
|
||||
delete(c.ptrs, dtype)
|
||||
ptrs := c.ptrs[dtypeKey]
|
||||
delete(c.ptrs, dtypeKey)
|
||||
|
||||
// Note Type might invalidate c.ptrs[dtype].
|
||||
// Note Type might invalidate c.ptrs[dtypeKey].
|
||||
t := c.Type(dtype, pos)
|
||||
for _, ptr := range ptrs {
|
||||
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
|
||||
// dtype when used as the type of a variable or a struct field.
|
||||
func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||
if t, ok := c.m[dtype]; ok {
|
||||
if t.Go == nil {
|
||||
fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
|
||||
// Always recompute bad pointer typedefs, as the set of such
|
||||
// typedefs changes as we see more types.
|
||||
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.Size = dtype.Size() // note: wrong for array of pointers, corrected below
|
||||
t.Align = -1
|
||||
t.C = &TypeRepr{Repr: dtype.Common().Name}
|
||||
c.m[dtype] = t
|
||||
c.m[key] = t
|
||||
|
||||
switch dt := dtype.(type) {
|
||||
default:
|
||||
|
@ -2325,10 +2415,11 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
|||
// Placeholder initialization; completed in FinishType.
|
||||
t.Go = &ast.StarExpr{}
|
||||
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.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
|
||||
c.ptrs[key] = append(c.ptrs[key], t)
|
||||
|
||||
case *dwarf.QualType:
|
||||
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
|
||||
for _, f := range dt.Field {
|
||||
if f.ByteOffset > off {
|
||||
fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
|
||||
off = f.ByteOffset
|
||||
}
|
||||
|
||||
name := f.Name
|
||||
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.
|
||||
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)
|
||||
fld = fld[0 : n+1]
|
||||
if name == "" {
|
||||
|
@ -2818,7 +2917,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
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 {
|
||||
switch dt := dt.(type) {
|
||||
default:
|
||||
|
@ -2935,6 +3034,9 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
|
|||
if c.badJNI(dt) {
|
||||
return true
|
||||
}
|
||||
if c.badEGLDisplay(dt) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -3071,6 +3173,19 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
|
|||
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
|
||||
// they are mapped. The base "jobject" maps to the empty string.
|
||||
var jniTypes = map[string]string{
|
||||
|
|
|
@ -127,8 +127,35 @@ func gofmt(n interface{}) 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,
|
||||
// ensuring that it is on a single line.
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
@ -64,6 +71,9 @@ type File struct {
|
|||
Edit *edit.Buffer
|
||||
}
|
||||
|
||||
// Untyped constants in the current package.
|
||||
var consts = make(map[string]bool)
|
||||
|
||||
func (f *File) offset(p token.Pos) int {
|
||||
return fset.Position(p).Offset
|
||||
}
|
||||
|
@ -96,13 +106,15 @@ func (r *Ref) Pos() token.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.
|
||||
type Name struct {
|
||||
Go string // name used in Go referring to package C
|
||||
Mangle string // name used in generated Go
|
||||
C string // name used in C
|
||||
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
|
||||
FuncType *FuncType
|
||||
AddError bool
|
||||
|
|
|
@ -6,7 +6,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/xcoff"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"debug/pe"
|
||||
|
@ -14,6 +13,7 @@ import (
|
|||
"go/ast"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"internal/xcoff"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"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 \"_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 __SIZE_TYPE__ _cgo_wait_runtime_init_done();\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())
|
||||
}
|
||||
|
||||
// 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
|
||||
// info).
|
||||
func gccgoUsesNewMangling() bool {
|
||||
|
@ -1255,7 +1262,7 @@ func determineGccgoManglingScheme() bool {
|
|||
cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename)
|
||||
buf, cerr := cmd.CombinedOutput()
|
||||
if cerr != nil {
|
||||
fatalf("%s", err)
|
||||
fatalf("%s", cerr)
|
||||
}
|
||||
|
||||
// New mangling: expect go.l..u00e4ufer.Run
|
||||
|
@ -1271,7 +1278,7 @@ func gccgoPkgpathToSymbolNew(ppath string) string {
|
|||
for _, c := range []byte(ppath) {
|
||||
switch {
|
||||
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
|
||||
'0' <= c && c <= '9', '_' == c:
|
||||
'0' <= c && c <= '9', c == '_', c == '.':
|
||||
bsl = append(bsl, c)
|
||||
default:
|
||||
changed = true
|
||||
|
@ -1473,6 +1480,14 @@ __cgo_size_assert(double, 8)
|
|||
|
||||
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 <string.h>
|
||||
`
|
||||
|
@ -1555,6 +1570,7 @@ const builtinProlog = `
|
|||
/* Define intgo when compiling with GCC. */
|
||||
typedef ptrdiff_t intgo;
|
||||
|
||||
#define GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; intgo n; } _GoString_;
|
||||
typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
|
||||
_GoString_ GoString(char *p);
|
||||
|
@ -1806,15 +1822,20 @@ void localCgoCheckResult(Eface val) {
|
|||
// because _cgo_export.h defines GoString as a struct while builtinProlog
|
||||
// defines it as a function. We don't change this to avoid unnecessarily
|
||||
// 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 = `
|
||||
#line 1 "cgo-builtin-prolog"
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef 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_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
`
|
||||
|
@ -1823,6 +1844,19 @@ func (p *Package) gccExportHeaderProlog() string {
|
|||
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 = `
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#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];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
|
|
|
@ -44,8 +44,12 @@ Flags:
|
|||
Print compiler version and exit.
|
||||
-asmhdr file
|
||||
Write assembly header to file.
|
||||
-buildid id
|
||||
Record id as the build id in the export metadata.
|
||||
-blockprofile file
|
||||
Write block profile for the compilation to file.
|
||||
-c int
|
||||
Concurrency during compilation. Set 1 for no concurrency (default is 1).
|
||||
-complete
|
||||
Assume package has no non-Go components.
|
||||
-cpuprofile file
|
||||
|
@ -54,8 +58,14 @@ Flags:
|
|||
Allow references to Go symbols in shared libraries (experimental).
|
||||
-e
|
||||
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
|
||||
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
|
||||
Interpret import "old" as import "new" during compilation.
|
||||
The option may be repeated to add multiple mappings.
|
||||
|
@ -74,6 +84,8 @@ Flags:
|
|||
object to usual output file (as specified by -o).
|
||||
Without this flag, the -o output is a combination of both
|
||||
linker and compiler input.
|
||||
-m
|
||||
Print optimization decisions.
|
||||
-memprofile file
|
||||
Write memory profile for the compilation to file.
|
||||
-memprofilerate rate
|
||||
|
@ -93,11 +105,50 @@ Flags:
|
|||
Write a package (archive) file rather than an object file
|
||||
-race
|
||||
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
|
||||
Remove prefix from recorded source file paths.
|
||||
|
||||
There are also a number of debugging flags; run the command with no arguments
|
||||
for a usage message.
|
||||
Flags related to debugging information:
|
||||
|
||||
-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
|
||||
|
||||
|
|
|
@ -9,18 +9,24 @@
|
|||
// TestFormats finds potential (Printf, etc.) format strings.
|
||||
// If they are used in a call, the format verbs are verified
|
||||
// based on the matching argument type against a precomputed
|
||||
// table of valid formats. The knownFormats table can be used
|
||||
// to automatically rewrite format strings with the -u flag.
|
||||
// map of valid formats (knownFormats). This map can be used to
|
||||
// automatically rewrite format strings across all compiler
|
||||
// files with the -r flag.
|
||||
//
|
||||
// A new knownFormats table based on the found formats is printed
|
||||
// when the test is run in verbose mode (-v flag). The table
|
||||
// needs to be updated whenever a new (type, format) combination
|
||||
// is found and the format verb is not 'v' or 'T' (as in "%v" or
|
||||
// "%T").
|
||||
// The format map needs to be updated whenever a new (type,
|
||||
// format) combination is found and the format verb is not
|
||||
// 'v' or 'T' (as in "%v" or "%T"). To update the map auto-
|
||||
// matically from the compiler source's use of format strings,
|
||||
// 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
|
||||
// (the test will fail)
|
||||
// - format strings that are not simple string literals cannot
|
||||
|
@ -45,6 +51,7 @@ import (
|
|||
"go/token"
|
||||
"go/types"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -56,7 +63,10 @@ import (
|
|||
"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.
|
||||
var (
|
||||
|
@ -173,11 +183,11 @@ func TestFormats(t *testing.T) {
|
|||
|
||||
// write dirty files back
|
||||
var filesUpdated bool
|
||||
if len(updatedFiles) > 0 && *update {
|
||||
if len(updatedFiles) > 0 && *rewrite {
|
||||
for _, file := range updatedFiles {
|
||||
var buf bytes.Buffer
|
||||
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
|
||||
}
|
||||
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() {
|
||||
set := make(map[string]bool)
|
||||
for _, p := range callSites {
|
||||
|
@ -199,23 +209,33 @@ func TestFormats(t *testing.T) {
|
|||
for s := range set {
|
||||
list = append(list, s)
|
||||
}
|
||||
fmt.Println("\nFunctions")
|
||||
printList(list)
|
||||
fmt.Println("\nFunctions called with a format string")
|
||||
writeList(os.Stdout, list)
|
||||
}
|
||||
|
||||
// report all formats found
|
||||
if len(foundFormats) > 0 && testing.Verbose() {
|
||||
// update formats
|
||||
if len(foundFormats) > 0 && *update {
|
||||
var list []string
|
||||
for s := range foundFormats {
|
||||
list = append(list, fmt.Sprintf("%q: \"\",", s))
|
||||
}
|
||||
fmt.Println("\nvar knownFormats = map[string]string{")
|
||||
printList(list)
|
||||
fmt.Println("}")
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(knownFormatsHeader)
|
||||
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
|
||||
if !testing.Verbose() && !*update {
|
||||
if !*rewrite && !*update {
|
||||
var mismatch bool
|
||||
for s := range foundFormats {
|
||||
if _, ok := knownFormats[s]; !ok {
|
||||
|
@ -232,7 +252,7 @@ func TestFormats(t *testing.T) {
|
|||
}
|
||||
}
|
||||
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)))
|
||||
}
|
||||
fmt.Println("\nWARNING: Potentially missed format strings")
|
||||
printList(list)
|
||||
writeList(os.Stdout, list)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
|
@ -365,11 +385,11 @@ func collectPkgFormats(t *testing.T, pkg *build.Package) {
|
|||
}
|
||||
}
|
||||
|
||||
// printList prints list in sorted order.
|
||||
func printList(list []string) {
|
||||
// writeList writes list in sorted order to w.
|
||||
func writeList(w io.Writer, list []string) {
|
||||
sort.Strings(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
|
||||
for key, val := range knownFormats {
|
||||
// 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, "%")
|
||||
if i < 0 || !oneFormat(key[i:]) {
|
||||
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".
|
||||
// An absent entry means that the format is not recognized as valid.
|
||||
// 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{
|
||||
"*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,
|
||||
// but at the point where it gets used, AX is dead
|
||||
// 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.To.Type = obj.TYPE_REG
|
||||
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.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = arm.REG_R0
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0
|
||||
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.From.Type = obj.TYPE_CONST
|
||||
return p
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ func genhash(sym *types.Sym, t *types.Type) {
|
|||
// pure memory.
|
||||
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.Type = types.Types[TINT]
|
||||
n.List.Set1(ni)
|
||||
|
@ -290,10 +290,10 @@ func genhash(sym *types.Sym, t *types.Type) {
|
|||
funcbody()
|
||||
|
||||
fn.Func.SetDupok(true)
|
||||
fn = typecheck(fn, Etop)
|
||||
fn = typecheck(fn, ctxStmt)
|
||||
|
||||
Curfn = fn
|
||||
typecheckslice(fn.Nbody.Slice(), Etop)
|
||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
||||
Curfn = nil
|
||||
|
||||
if debug_dclstack != 0 {
|
||||
|
@ -330,6 +330,7 @@ func hashfor(t *types.Type) *Node {
|
|||
|
||||
n := newname(sym)
|
||||
n.SetClass(PFUNC)
|
||||
n.Sym.SetFunc(true)
|
||||
n.Type = functype(nil, []*Node{
|
||||
anonfield(types.NewPtr(t)),
|
||||
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,
|
||||
// each iteration would be a function call, so don't bother
|
||||
// unrolling.
|
||||
nrange := nod(ORANGE, nil, nod(OIND, np, nil))
|
||||
nrange := nod(ORANGE, nil, nod(ODEREF, np, nil))
|
||||
|
||||
ni := newname(lookup("i"))
|
||||
ni.Type = types.Types[TINT]
|
||||
|
@ -464,10 +465,10 @@ func geneq(sym *types.Sym, t *types.Type) {
|
|||
funcbody()
|
||||
|
||||
fn.Func.SetDupok(true)
|
||||
fn = typecheck(fn, Etop)
|
||||
fn = typecheck(fn, ctxStmt)
|
||||
|
||||
Curfn = fn
|
||||
typecheckslice(fn.Nbody.Slice(), Etop)
|
||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
||||
Curfn = nil
|
||||
|
||||
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 {
|
||||
nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
|
||||
ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
|
||||
nx = typecheck(nx, Erv)
|
||||
ny = typecheck(ny, Erv)
|
||||
nx = typecheck(nx, ctxExpr)
|
||||
ny = typecheck(ny, ctxExpr)
|
||||
|
||||
fn, needsize := eqmemfunc(size, nx.Type.Elem())
|
||||
call := nod(OCALL, fn, nil)
|
||||
|
|
|
@ -144,8 +144,9 @@ var runtimeDecls = [...]struct {
|
|||
{"racewriterange", funcTag, 113},
|
||||
{"msanread", funcTag, 113},
|
||||
{"msanwrite", funcTag, 113},
|
||||
{"support_popcnt", varTag, 11},
|
||||
{"support_sse41", varTag, 11},
|
||||
{"x86HasPOPCNT", varTag, 11},
|
||||
{"x86HasSSE41", varTag, 11},
|
||||
{"arm64HasATOMICS", varTag, 11},
|
||||
}
|
||||
|
||||
func runtimeTypes() []*types.Type {
|
||||
|
|
|
@ -195,5 +195,6 @@ func msanread(addr, size uintptr)
|
|||
func msanwrite(addr, size uintptr)
|
||||
|
||||
// architecture variants
|
||||
var support_popcnt bool
|
||||
var support_sse41 bool
|
||||
var x86HasPOPCNT bool
|
||||
var x86HasSSE41 bool
|
||||
var arm64HasATOMICS bool
|
||||
|
|
|
@ -93,7 +93,7 @@ func typecheckclosure(clo *Node, top int) {
|
|||
xfunc.Func.Nname.Sym = closurename(Curfn)
|
||||
disableExport(xfunc.Func.Nname.Sym)
|
||||
declare(xfunc.Func.Nname, PFUNC)
|
||||
xfunc = typecheck(xfunc, Etop)
|
||||
xfunc = typecheck(xfunc, ctxStmt)
|
||||
|
||||
clo.Func.Ntype = typecheck(clo.Func.Ntype, Etype)
|
||||
clo.Type = clo.Func.Ntype.Type
|
||||
|
@ -108,7 +108,7 @@ func typecheckclosure(clo *Node, top int) {
|
|||
Curfn = xfunc
|
||||
olddd := decldepth
|
||||
decldepth = 1
|
||||
typecheckslice(xfunc.Nbody.Slice(), Etop)
|
||||
typecheckslice(xfunc.Nbody.Slice(), ctxStmt)
|
||||
decldepth = olddd
|
||||
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))
|
||||
}
|
||||
|
||||
outer = typecheck(outer, Erv)
|
||||
outer = typecheck(outer, ctxExpr)
|
||||
clo.Func.Enter.Append(outer)
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ func transformclosure(xfunc *Node) {
|
|||
lineno = xfunc.Pos
|
||||
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
|
||||
// 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)
|
||||
|
@ -305,7 +305,7 @@ func transformclosure(xfunc *Node) {
|
|||
}
|
||||
|
||||
if len(body) > 0 {
|
||||
typecheckslice(body, Etop)
|
||||
typecheckslice(body, ctxStmt)
|
||||
xfunc.Func.Enter.Set(body)
|
||||
xfunc.Func.SetNeedctxt(true)
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ func walkclosure(clo *Node, init *Nodes) *Node {
|
|||
|
||||
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.Right.SetImplicit(true)
|
||||
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)
|
||||
|
||||
savecurfn := Curfn
|
||||
saveLineNo := lineno
|
||||
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.List.Set(structargs(t0.Params(), true))
|
||||
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.List.Set(paramNnames(tfn.Type))
|
||||
call.SetIsddd(tfn.Type.IsVariadic())
|
||||
call.SetIsDDD(tfn.Type.IsVariadic())
|
||||
if t0.NumResults() != 0 {
|
||||
n := nod(ORETURN, nil, nil)
|
||||
n.List.Set1(call)
|
||||
|
@ -478,10 +490,11 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
|
|||
xfunc.Nbody.Set(body)
|
||||
funcbody()
|
||||
|
||||
xfunc = typecheck(xfunc, Etop)
|
||||
xfunc = typecheck(xfunc, ctxStmt)
|
||||
sym.Def = asTypesNode(xfunc)
|
||||
xtop = append(xtop, xfunc)
|
||||
Curfn = savecurfn
|
||||
lineno = saveLineNo
|
||||
|
||||
return xfunc
|
||||
}
|
||||
|
@ -516,7 +529,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
|
|||
|
||||
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.Right.SetImplicit(true)
|
||||
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.
|
||||
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
|
||||
|
||||
// Pick off just the opcodes that can be constant evaluated.
|
||||
switch op := n.Op; op {
|
||||
case OPLUS, OMINUS, OCOM, ONOT:
|
||||
case OPLUS, ONEG, OBITNOT, ONOT:
|
||||
if nl.Op == OLITERAL {
|
||||
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())
|
||||
}
|
||||
|
||||
case OARRAYBYTESTR:
|
||||
case OBYTES2STR:
|
||||
// string([]byte(nil)) or string([]rune(nil))
|
||||
if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL {
|
||||
setconst(n, Val{U: ""})
|
||||
|
@ -873,7 +881,7 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
|
|||
return x
|
||||
}
|
||||
|
||||
case OMINUS:
|
||||
case ONEG:
|
||||
switch x.Ctype() {
|
||||
case CTINT, CTRUNE:
|
||||
x := x.U.(*Mpint)
|
||||
|
@ -900,7 +908,7 @@ func unaryOp(op Op, x Val, t *types.Type) Val {
|
|||
return Val{U: u}
|
||||
}
|
||||
|
||||
case OCOM:
|
||||
case OBITNOT:
|
||||
x := x.U.(*Mpint)
|
||||
|
||||
u := new(Mpint)
|
||||
|
@ -1024,9 +1032,9 @@ func idealkind(n *Node) Ctype {
|
|||
case OADD,
|
||||
OAND,
|
||||
OANDNOT,
|
||||
OCOM,
|
||||
OBITNOT,
|
||||
ODIV,
|
||||
OMINUS,
|
||||
ONEG,
|
||||
OMOD,
|
||||
OMUL,
|
||||
OSUB,
|
||||
|
@ -1221,6 +1229,7 @@ func strlit(n *Node) string {
|
|||
return n.Val().U.(string)
|
||||
}
|
||||
|
||||
// TODO(gri) smallintconst is only used in one place - can we used indexconst?
|
||||
func smallintconst(n *Node) bool {
|
||||
if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
|
||||
switch simtype[n.Type.Etype] {
|
||||
|
@ -1235,7 +1244,7 @@ func smallintconst(n *Node) bool {
|
|||
|
||||
case TIDEAL, TINT64, TUINT64, TPTR:
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -1244,21 +1253,24 @@ func smallintconst(n *Node) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// nonnegintconst checks if Node n contains a constant expression
|
||||
// representable as a non-negative small integer, and returns its
|
||||
// (integer) value if that's the case. Otherwise, it returns -1.
|
||||
func nonnegintconst(n *Node) int64 {
|
||||
// indexconst checks if Node n contains a constant expression
|
||||
// representable as a non-negative int and returns its value.
|
||||
// If n is not a constant expression, not representable as an
|
||||
// integer, or negative, it returns -1. If n is too large, it
|
||||
// returns -2.
|
||||
func indexconst(n *Node) int64 {
|
||||
if n.Op != OLITERAL {
|
||||
return -1
|
||||
}
|
||||
|
||||
// toint will leave n.Val unchanged if it's not castable to an
|
||||
// Mpint, so we still have to guard the conversion.
|
||||
v := toint(n.Val())
|
||||
v := toint(n.Val()) // toint returns argument unchanged if not representable as an *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
|
||||
}
|
||||
if vi.Cmp(maxintval[TINT]) > 0 {
|
||||
return -2
|
||||
}
|
||||
|
||||
return vi.Int64()
|
||||
}
|
||||
|
@ -1268,7 +1280,7 @@ func nonnegintconst(n *Node) int64 {
|
|||
//
|
||||
// Expressions derived from nil, like string([]byte(nil)), while they
|
||||
// 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.
|
||||
func (n *Node) isGoConst() bool {
|
||||
if n.Orig != nil {
|
||||
|
@ -1277,11 +1289,10 @@ func (n *Node) isGoConst() bool {
|
|||
|
||||
switch n.Op {
|
||||
case OADD,
|
||||
OADDSTR,
|
||||
OAND,
|
||||
OANDAND,
|
||||
OANDNOT,
|
||||
OCOM,
|
||||
OBITNOT,
|
||||
ODIV,
|
||||
OEQ,
|
||||
OGE,
|
||||
|
@ -1289,7 +1300,7 @@ func (n *Node) isGoConst() bool {
|
|||
OLE,
|
||||
OLSH,
|
||||
OLT,
|
||||
OMINUS,
|
||||
ONEG,
|
||||
OMOD,
|
||||
OMUL,
|
||||
ONE,
|
||||
|
@ -1301,14 +1312,26 @@ func (n *Node) isGoConst() bool {
|
|||
OSUB,
|
||||
OXOR,
|
||||
OIOTA,
|
||||
OCOMPLEX,
|
||||
OREAL,
|
||||
OIMAG:
|
||||
if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) {
|
||||
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() {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -125,6 +125,9 @@ func declare(n *Node, ctxt Class) {
|
|||
s.Def = asTypesNode(n)
|
||||
n.Name.Vargen = int32(gen)
|
||||
n.SetClass(ctxt)
|
||||
if ctxt == PFUNC {
|
||||
n.Sym.SetFunc(true)
|
||||
}
|
||||
|
||||
autoexport(n, ctxt)
|
||||
}
|
||||
|
@ -280,7 +283,7 @@ func oldname(s *types.Sym) *Node {
|
|||
c = newname(s)
|
||||
c.SetClass(PAUTOHEAP)
|
||||
c.SetIsClosureVar(true)
|
||||
c.SetIsddd(n.Isddd())
|
||||
c.SetIsDDD(n.IsDDD())
|
||||
c.Name.Defn = n
|
||||
c.SetAddable(false)
|
||||
|
||||
|
@ -452,7 +455,7 @@ func funcarg(n *Node, ctxt Class) {
|
|||
|
||||
n.Right = newnamel(n.Pos, n.Sym)
|
||||
n.Right.Name.Param.Ntype = n.Left
|
||||
n.Right.SetIsddd(n.Isddd())
|
||||
n.Right.SetIsDDD(n.IsDDD())
|
||||
declare(n.Right, ctxt)
|
||||
|
||||
vargen++
|
||||
|
@ -485,7 +488,7 @@ func funcarg2(f *types.Field, ctxt Class) {
|
|||
n := newnamel(f.Pos, f.Sym)
|
||||
f.Nname = asTypesNode(n)
|
||||
n.Type = f.Type
|
||||
n.SetIsddd(f.Isddd())
|
||||
n.SetIsDDD(f.IsDDD())
|
||||
declare(n, ctxt)
|
||||
}
|
||||
|
||||
|
@ -625,7 +628,7 @@ func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
|
|||
fields := make([]*types.Field, len(l))
|
||||
for i, n := range l {
|
||||
f := structfield(n)
|
||||
f.SetIsddd(n.Isddd())
|
||||
f.SetIsDDD(n.IsDDD())
|
||||
if n.Right != nil {
|
||||
n.Right.Type = f.Type
|
||||
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
|
||||
// in different method sets. For example, T.M and (*T).M have distinct
|
||||
// method symbols.
|
||||
//
|
||||
// The returned symbol will be marked as a function.
|
||||
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
|
||||
|
|
|
@ -671,7 +671,7 @@ func (e *EscState) isSliceSelfAssign(dst, src *Node) bool {
|
|||
// when we evaluate it for dst and for src.
|
||||
|
||||
// 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
|
||||
}
|
||||
// src is a slice operation.
|
||||
|
@ -695,7 +695,7 @@ func (e *EscState) isSliceSelfAssign(dst, src *Node) bool {
|
|||
return false
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// 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)
|
||||
|
||||
// Left group.
|
||||
case ODOT, ODOTPTR, OIND, OCONVNOP, OCONV, OLEN, OCAP,
|
||||
ONOT, OCOM, OPLUS, OMINUS, OALIGNOF, OOFFSETOF, OSIZEOF:
|
||||
case ODOT, ODOTPTR, ODEREF, OCONVNOP, OCONV, OLEN, OCAP,
|
||||
ONOT, OBITNOT, OPLUS, ONEG, OALIGNOF, OOFFSETOF, OSIZEOF:
|
||||
return e.mayAffectMemory(n.Left)
|
||||
|
||||
default:
|
||||
|
@ -935,7 +935,7 @@ opSwitch:
|
|||
e.escassignSinkWhy(n, arg, "defer func arg")
|
||||
}
|
||||
|
||||
case OPROC:
|
||||
case OGO:
|
||||
// go f(x) - f and x escape
|
||||
e.escassignSinkWhy(n, n.Left.Left, "go func")
|
||||
e.escassignSinkWhy(n, n.Left.Right, "go func ...") // ODDDARG for call
|
||||
|
@ -991,7 +991,7 @@ opSwitch:
|
|||
e.escassignSinkWhy(n, n.Left, "panic")
|
||||
|
||||
case OAPPEND:
|
||||
if !n.Isddd() {
|
||||
if !n.IsDDD() {
|
||||
for _, nn := range n.List.Slice()[1:] {
|
||||
e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference
|
||||
}
|
||||
|
@ -1072,7 +1072,7 @@ opSwitch:
|
|||
a = nod(OADDR, a, nil)
|
||||
a.Pos = v.Pos
|
||||
e.nodeEscState(a).Loopdepth = e.loopdepth
|
||||
a = typecheck(a, Erv)
|
||||
a = typecheck(a, ctxExpr)
|
||||
}
|
||||
|
||||
e.escassignWhyWhere(n, a, "captured by a closure", n)
|
||||
|
@ -1083,10 +1083,10 @@ opSwitch:
|
|||
OMAKEMAP,
|
||||
OMAKESLICE,
|
||||
ONEW,
|
||||
OARRAYRUNESTR,
|
||||
OARRAYBYTESTR,
|
||||
OSTRARRAYRUNE,
|
||||
OSTRARRAYBYTE,
|
||||
ORUNES2STR,
|
||||
OBYTES2STR,
|
||||
OSTR2RUNES,
|
||||
OSTR2BYTES,
|
||||
ORUNESTR:
|
||||
e.track(n)
|
||||
|
||||
|
@ -1223,7 +1223,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
|
|||
dstwhy = "slice-element-equals"
|
||||
dst = &e.theSink // lose track of dereference
|
||||
|
||||
case OIND:
|
||||
case ODEREF:
|
||||
dstwhy = "star-equals"
|
||||
dst = &e.theSink // lose track of dereference
|
||||
|
||||
|
@ -1243,7 +1243,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
|
|||
|
||||
switch src.Op {
|
||||
case OADDR, // dst = &x
|
||||
OIND, // dst = *x
|
||||
ODEREF, // dst = *x
|
||||
ODOTPTR, // dst = (*x).f
|
||||
ONAME,
|
||||
ODDDARG,
|
||||
|
@ -1255,10 +1255,10 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
|
|||
OMAKECHAN,
|
||||
OMAKEMAP,
|
||||
OMAKESLICE,
|
||||
OARRAYRUNESTR,
|
||||
OARRAYBYTESTR,
|
||||
OSTRARRAYRUNE,
|
||||
OSTRARRAYBYTE,
|
||||
ORUNES2STR,
|
||||
OBYTES2STR,
|
||||
OSTR2RUNES,
|
||||
OSTR2BYTES,
|
||||
OADDSTR,
|
||||
ONEW,
|
||||
OCALLPART,
|
||||
|
@ -1293,7 +1293,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
|
|||
case OCONV,
|
||||
OCONVNOP,
|
||||
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
|
||||
OSLICE,
|
||||
OSLICE3,
|
||||
|
@ -1338,8 +1338,8 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) {
|
|||
OAND,
|
||||
OANDNOT,
|
||||
OPLUS,
|
||||
OMINUS,
|
||||
OCOM:
|
||||
ONEG,
|
||||
OBITNOT:
|
||||
e.escassign(dst, src.Left, 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)
|
||||
}
|
||||
|
||||
// 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,
|
||||
// some semantically dubious node combinations are (currently) possible.
|
||||
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
|
||||
ind.Pos = n.Pos
|
||||
t := n.Type
|
||||
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
|
||||
// yields the type of an element.
|
||||
t = t.Elem()
|
||||
|
@ -1652,49 +1652,79 @@ func (e *EscState) esccall(call *Node, parent *Node) {
|
|||
Fatalf("graph inconsistency")
|
||||
}
|
||||
|
||||
sawRcvr := false
|
||||
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
|
||||
i := 0
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check: all arguments must be consumed.
|
||||
if len(args) != 0 {
|
||||
Fatalf("esccall not consumed all args %+v\n", call)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1722,7 +1752,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
|
|||
for i, param := range fntype.Params().FieldSlice() {
|
||||
note := param.Note
|
||||
var arg *Node
|
||||
if param.Isddd() && !call.Isddd() {
|
||||
if param.IsDDD() && !call.IsDDD() {
|
||||
rest := args[i:]
|
||||
if len(rest) == 0 {
|
||||
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
|
||||
for a.Op == OCONVNOP {
|
||||
a = a.Left
|
||||
|
@ -2057,10 +2087,10 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep,
|
|||
case OMAKECHAN,
|
||||
OMAKEMAP,
|
||||
OMAKESLICE,
|
||||
OARRAYRUNESTR,
|
||||
OARRAYBYTESTR,
|
||||
OSTRARRAYRUNE,
|
||||
OSTRARRAYBYTE,
|
||||
ORUNES2STR,
|
||||
OBYTES2STR,
|
||||
OSTR2RUNES,
|
||||
OSTR2BYTES,
|
||||
OADDSTR,
|
||||
OMAPLIT,
|
||||
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))
|
||||
case OINDEXMAP:
|
||||
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))
|
||||
|
||||
// In this case a link went directly to a call, but should really go
|
||||
|
@ -2142,7 +2172,7 @@ func addrescapes(n *Node) {
|
|||
default:
|
||||
// Unexpected Op, probably due to a previous type error. Ignore.
|
||||
|
||||
case OIND, ODOTPTR:
|
||||
case ODEREF, ODOTPTR:
|
||||
// Nothing to do.
|
||||
|
||||
case ONAME:
|
||||
|
@ -2347,7 +2377,7 @@ func (e *EscState) esctag(fn *Node) {
|
|||
f.Note = uintptrEscapesTag
|
||||
}
|
||||
|
||||
if f.Isddd() && f.Type.Elem().Etype == TUINTPTR {
|
||||
if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR {
|
||||
// final argument is ...uintptr.
|
||||
if Debug['m'] != 0 {
|
||||
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) {
|
||||
// The linker also looks for the $$ marker - use char after $$ to distinguish 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.Pos = pos
|
||||
n.SetClass(ctxt)
|
||||
if ctxt == PFUNC {
|
||||
n.Sym.SetFunc(true)
|
||||
}
|
||||
n.Type = t
|
||||
return n
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ var goopnames = []string{
|
|||
OCASE: "case",
|
||||
OCLOSE: "close",
|
||||
OCOMPLEX: "complex",
|
||||
OCOM: "^",
|
||||
OBITNOT: "^",
|
||||
OCONTINUE: "continue",
|
||||
OCOPY: "copy",
|
||||
ODELETE: "delete",
|
||||
|
@ -174,13 +174,14 @@ var goopnames = []string{
|
|||
OGT: ">",
|
||||
OIF: "if",
|
||||
OIMAG: "imag",
|
||||
OIND: "*",
|
||||
OINLMARK: "inlmark",
|
||||
ODEREF: "*",
|
||||
OLEN: "len",
|
||||
OLE: "<=",
|
||||
OLSH: "<<",
|
||||
OLT: "<",
|
||||
OMAKE: "make",
|
||||
OMINUS: "-",
|
||||
ONEG: "-",
|
||||
OMOD: "%",
|
||||
OMUL: "*",
|
||||
ONEW: "new",
|
||||
|
@ -464,8 +465,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
|
|||
fmt.Fprintf(s, " tc(%d)", n.Typecheck())
|
||||
}
|
||||
|
||||
if n.Isddd() {
|
||||
fmt.Fprintf(s, " isddd(%v)", n.Isddd())
|
||||
if n.IsDDD() {
|
||||
fmt.Fprintf(s, " isddd(%v)", n.IsDDD())
|
||||
}
|
||||
|
||||
if n.Implicit() {
|
||||
|
@ -942,7 +943,10 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
|
|||
case ORETJMP:
|
||||
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)
|
||||
|
||||
case ODEFER:
|
||||
|
@ -1064,92 +1068,92 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
|
|||
}
|
||||
|
||||
var opprec = []int{
|
||||
OALIGNOF: 8,
|
||||
OAPPEND: 8,
|
||||
OARRAYBYTESTR: 8,
|
||||
OARRAYLIT: 8,
|
||||
OSLICELIT: 8,
|
||||
OARRAYRUNESTR: 8,
|
||||
OCALLFUNC: 8,
|
||||
OCALLINTER: 8,
|
||||
OCALLMETH: 8,
|
||||
OCALL: 8,
|
||||
OCAP: 8,
|
||||
OCLOSE: 8,
|
||||
OCONVIFACE: 8,
|
||||
OCONVNOP: 8,
|
||||
OCONV: 8,
|
||||
OCOPY: 8,
|
||||
ODELETE: 8,
|
||||
OGETG: 8,
|
||||
OLEN: 8,
|
||||
OLITERAL: 8,
|
||||
OMAKESLICE: 8,
|
||||
OMAKE: 8,
|
||||
OMAPLIT: 8,
|
||||
ONAME: 8,
|
||||
ONEW: 8,
|
||||
ONONAME: 8,
|
||||
OOFFSETOF: 8,
|
||||
OPACK: 8,
|
||||
OPANIC: 8,
|
||||
OPAREN: 8,
|
||||
OPRINTN: 8,
|
||||
OPRINT: 8,
|
||||
ORUNESTR: 8,
|
||||
OSIZEOF: 8,
|
||||
OSTRARRAYBYTE: 8,
|
||||
OSTRARRAYRUNE: 8,
|
||||
OSTRUCTLIT: 8,
|
||||
OTARRAY: 8,
|
||||
OTCHAN: 8,
|
||||
OTFUNC: 8,
|
||||
OTINTER: 8,
|
||||
OTMAP: 8,
|
||||
OTSTRUCT: 8,
|
||||
OINDEXMAP: 8,
|
||||
OINDEX: 8,
|
||||
OSLICE: 8,
|
||||
OSLICESTR: 8,
|
||||
OSLICEARR: 8,
|
||||
OSLICE3: 8,
|
||||
OSLICE3ARR: 8,
|
||||
OSLICEHEADER: 8,
|
||||
ODOTINTER: 8,
|
||||
ODOTMETH: 8,
|
||||
ODOTPTR: 8,
|
||||
ODOTTYPE2: 8,
|
||||
ODOTTYPE: 8,
|
||||
ODOT: 8,
|
||||
OXDOT: 8,
|
||||
OCALLPART: 8,
|
||||
OPLUS: 7,
|
||||
ONOT: 7,
|
||||
OCOM: 7,
|
||||
OMINUS: 7,
|
||||
OADDR: 7,
|
||||
OIND: 7,
|
||||
ORECV: 7,
|
||||
OMUL: 6,
|
||||
ODIV: 6,
|
||||
OMOD: 6,
|
||||
OLSH: 6,
|
||||
ORSH: 6,
|
||||
OAND: 6,
|
||||
OANDNOT: 6,
|
||||
OADD: 5,
|
||||
OSUB: 5,
|
||||
OOR: 5,
|
||||
OXOR: 5,
|
||||
OEQ: 4,
|
||||
OLT: 4,
|
||||
OLE: 4,
|
||||
OGE: 4,
|
||||
OGT: 4,
|
||||
ONE: 4,
|
||||
OSEND: 3,
|
||||
OANDAND: 2,
|
||||
OOROR: 1,
|
||||
OALIGNOF: 8,
|
||||
OAPPEND: 8,
|
||||
OBYTES2STR: 8,
|
||||
OARRAYLIT: 8,
|
||||
OSLICELIT: 8,
|
||||
ORUNES2STR: 8,
|
||||
OCALLFUNC: 8,
|
||||
OCALLINTER: 8,
|
||||
OCALLMETH: 8,
|
||||
OCALL: 8,
|
||||
OCAP: 8,
|
||||
OCLOSE: 8,
|
||||
OCONVIFACE: 8,
|
||||
OCONVNOP: 8,
|
||||
OCONV: 8,
|
||||
OCOPY: 8,
|
||||
ODELETE: 8,
|
||||
OGETG: 8,
|
||||
OLEN: 8,
|
||||
OLITERAL: 8,
|
||||
OMAKESLICE: 8,
|
||||
OMAKE: 8,
|
||||
OMAPLIT: 8,
|
||||
ONAME: 8,
|
||||
ONEW: 8,
|
||||
ONONAME: 8,
|
||||
OOFFSETOF: 8,
|
||||
OPACK: 8,
|
||||
OPANIC: 8,
|
||||
OPAREN: 8,
|
||||
OPRINTN: 8,
|
||||
OPRINT: 8,
|
||||
ORUNESTR: 8,
|
||||
OSIZEOF: 8,
|
||||
OSTR2BYTES: 8,
|
||||
OSTR2RUNES: 8,
|
||||
OSTRUCTLIT: 8,
|
||||
OTARRAY: 8,
|
||||
OTCHAN: 8,
|
||||
OTFUNC: 8,
|
||||
OTINTER: 8,
|
||||
OTMAP: 8,
|
||||
OTSTRUCT: 8,
|
||||
OINDEXMAP: 8,
|
||||
OINDEX: 8,
|
||||
OSLICE: 8,
|
||||
OSLICESTR: 8,
|
||||
OSLICEARR: 8,
|
||||
OSLICE3: 8,
|
||||
OSLICE3ARR: 8,
|
||||
OSLICEHEADER: 8,
|
||||
ODOTINTER: 8,
|
||||
ODOTMETH: 8,
|
||||
ODOTPTR: 8,
|
||||
ODOTTYPE2: 8,
|
||||
ODOTTYPE: 8,
|
||||
ODOT: 8,
|
||||
OXDOT: 8,
|
||||
OCALLPART: 8,
|
||||
OPLUS: 7,
|
||||
ONOT: 7,
|
||||
OBITNOT: 7,
|
||||
ONEG: 7,
|
||||
OADDR: 7,
|
||||
ODEREF: 7,
|
||||
ORECV: 7,
|
||||
OMUL: 6,
|
||||
ODIV: 6,
|
||||
OMOD: 6,
|
||||
OLSH: 6,
|
||||
ORSH: 6,
|
||||
OAND: 6,
|
||||
OANDNOT: 6,
|
||||
OADD: 5,
|
||||
OSUB: 5,
|
||||
OOR: 5,
|
||||
OXOR: 5,
|
||||
OEQ: 4,
|
||||
OLT: 4,
|
||||
OLE: 4,
|
||||
OGE: 4,
|
||||
OGT: 4,
|
||||
ONE: 4,
|
||||
OSEND: 3,
|
||||
OANDAND: 2,
|
||||
OOROR: 1,
|
||||
|
||||
// Statements handled by stmtfmt
|
||||
OAS: -1,
|
||||
|
@ -1172,7 +1176,7 @@ var opprec = []int{
|
|||
OGOTO: -1,
|
||||
OIF: -1,
|
||||
OLABEL: -1,
|
||||
OPROC: -1,
|
||||
OGO: -1,
|
||||
ORANGE: -1,
|
||||
ORETURN: -1,
|
||||
OSELECT: -1,
|
||||
|
@ -1183,7 +1187,7 @@ var opprec = []int{
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
||||
case OCOPY, OCOMPLEX:
|
||||
case OCOPY:
|
||||
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,
|
||||
OCONVIFACE,
|
||||
OCONVNOP,
|
||||
OARRAYBYTESTR,
|
||||
OARRAYRUNESTR,
|
||||
OSTRARRAYBYTE,
|
||||
OSTRARRAYRUNE,
|
||||
OBYTES2STR,
|
||||
ORUNES2STR,
|
||||
OSTR2BYTES,
|
||||
OSTR2RUNES,
|
||||
ORUNESTR:
|
||||
if n.Type == nil || n.Type.Sym == nil {
|
||||
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)
|
||||
return
|
||||
}
|
||||
if n.Isddd() {
|
||||
if n.IsDDD() {
|
||||
mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
|
||||
return
|
||||
}
|
||||
|
@ -1450,7 +1461,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
|||
|
||||
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
|
||||
n.Left.exprfmt(s, nprec, mode)
|
||||
if n.Isddd() {
|
||||
if n.IsDDD() {
|
||||
mode.Fprintf(s, "(%.v...)", n.List)
|
||||
return
|
||||
}
|
||||
|
@ -1471,7 +1482,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
|||
}
|
||||
mode.Fprintf(s, "make(%v)", n.Type)
|
||||
|
||||
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
|
||||
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
||||
// Unary
|
||||
mode.Fprintf(s, "%#v", 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
|
||||
if f.Isddd() {
|
||||
if f.IsDDD() {
|
||||
var et *types.Type
|
||||
if f.Type != nil {
|
||||
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()
|
||||
}
|
||||
|
||||
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 "<...>"
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,18 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// sysfunc looks up Go function name in package runtime. This function
|
||||
// must follow the internal calling convention.
|
||||
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()
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"bytes"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
@ -24,7 +23,7 @@ func TestScanfRemoval(t *testing.T) {
|
|||
// Make a directory to work in.
|
||||
dir, err := ioutil.TempDir("", "issue6853a-")
|
||||
if err != nil {
|
||||
log.Fatalf("could not create directory: %v", err)
|
||||
t.Fatalf("could not create directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
|
@ -32,7 +31,7 @@ func TestScanfRemoval(t *testing.T) {
|
|||
src := filepath.Join(dir, "test.go")
|
||||
f, err := os.Create(src)
|
||||
if err != nil {
|
||||
log.Fatalf("could not create source file: %v", err)
|
||||
t.Fatalf("could not create source file: %v", err)
|
||||
}
|
||||
f.Write([]byte(`
|
||||
package main
|
||||
|
@ -50,17 +49,17 @@ func main() {
|
|||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
|
||||
out, err := cmd.CombinedOutput()
|
||||
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.
|
||||
cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
|
||||
out, err = cmd.CombinedOutput()
|
||||
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")) {
|
||||
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.
|
||||
dir, err := ioutil.TempDir("", "issue14515-")
|
||||
if err != nil {
|
||||
log.Fatalf("could not create directory: %v", err)
|
||||
t.Fatalf("could not create directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
|
@ -79,7 +78,7 @@ func TestDashS(t *testing.T) {
|
|||
src := filepath.Join(dir, "test.go")
|
||||
f, err := os.Create(src)
|
||||
if err != nil {
|
||||
log.Fatalf("could not create source file: %v", err)
|
||||
t.Fatalf("could not create source file: %v", err)
|
||||
}
|
||||
f.Write([]byte(`
|
||||
package main
|
||||
|
@ -94,7 +93,7 @@ func main() {
|
|||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatalf("could not build target: %v", err)
|
||||
t.Fatalf("could not build target: %v", err)
|
||||
}
|
||||
|
||||
patterns := []string{
|
||||
|
|
|
@ -257,7 +257,7 @@ type Arch struct {
|
|||
|
||||
PadFrame func(int64) int64
|
||||
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 func(*SSAGenState, *ssa.Block)
|
||||
|
@ -300,14 +300,15 @@ var (
|
|||
panicdottypeI,
|
||||
panicindex,
|
||||
panicnildottype,
|
||||
panicoverflow,
|
||||
panicslice,
|
||||
raceread,
|
||||
racereadrange,
|
||||
racewrite,
|
||||
racewriterange,
|
||||
supportPopcnt,
|
||||
supportSSE41,
|
||||
arm64SupportAtomics,
|
||||
x86HasPOPCNT,
|
||||
x86HasSSE41,
|
||||
arm64HasATOMICS,
|
||||
typedmemclr,
|
||||
typedmemmove,
|
||||
Udiv,
|
||||
|
|
|
@ -187,7 +187,13 @@ func (pp *Progs) settext(fn *Node) {
|
|||
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 {
|
||||
Fatalf("Func.initLSym called twice")
|
||||
}
|
||||
|
@ -197,6 +203,61 @@ func (f *Func) initLSym() {
|
|||
if f.Pragma&Systemstack != 0 {
|
||||
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
|
||||
|
|
|
@ -439,7 +439,7 @@ func (p *iexporter) doDecl(n *Node) {
|
|||
|
||||
case OLITERAL:
|
||||
// Constant.
|
||||
n = typecheck(n, Erv)
|
||||
n = typecheck(n, ctxExpr)
|
||||
w.tag('C')
|
||||
w.pos(n.Pos)
|
||||
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.Results().FieldSlice())
|
||||
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:
|
||||
// unreachable - generated by compiler for trampolin routines
|
||||
|
||||
case OPROC, ODEFER:
|
||||
case OGO, ODEFER:
|
||||
w.op(op)
|
||||
w.pos(n.Pos)
|
||||
w.expr(n.Left)
|
||||
|
@ -1127,7 +1127,7 @@ func (w *exportWriter) expr(n *Node) {
|
|||
// }
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1252,7 @@ func (w *exportWriter) expr(n *Node) {
|
|||
w.expr(n.Right)
|
||||
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.pos(n.Pos)
|
||||
w.expr(n.Left)
|
||||
|
@ -1269,8 +1269,8 @@ func (w *exportWriter) expr(n *Node) {
|
|||
}
|
||||
// only append() calls may contain '...' arguments
|
||||
if op == OAPPEND {
|
||||
w.bool(n.Isddd())
|
||||
} else if n.Isddd() {
|
||||
w.bool(n.IsDDD())
|
||||
} else if n.IsDDD() {
|
||||
Fatalf("exporter: unexpected '...' with %v call", op)
|
||||
}
|
||||
|
||||
|
@ -1279,7 +1279,7 @@ func (w *exportWriter) expr(n *Node) {
|
|||
w.pos(n.Pos)
|
||||
w.expr(n.Left)
|
||||
w.exprList(n.List)
|
||||
w.bool(n.Isddd())
|
||||
w.bool(n.IsDDD())
|
||||
|
||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||
w.op(op) // must keep separate from OMAKE for importer
|
||||
|
@ -1301,7 +1301,7 @@ func (w *exportWriter) expr(n *Node) {
|
|||
}
|
||||
|
||||
// unary expressions
|
||||
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
|
||||
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
||||
w.op(op)
|
||||
w.pos(n.Pos)
|
||||
w.expr(n.Left)
|
||||
|
@ -1325,7 +1325,7 @@ func (w *exportWriter) expr(n *Node) {
|
|||
|
||||
default:
|
||||
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.Type = mtyp
|
||||
m.SetClass(PFUNC)
|
||||
// methodSym already marked m.Sym as a function.
|
||||
|
||||
// (comment from parser.go)
|
||||
// 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()
|
||||
results := r.paramList()
|
||||
if n := len(params); n > 0 {
|
||||
params[n-1].SetIsddd(r.bool())
|
||||
params[n-1].SetIsDDD(r.bool())
|
||||
}
|
||||
t := functypefield(recv, params, results)
|
||||
t.SetPkg(r.currPkg)
|
||||
|
@ -819,7 +820,7 @@ func (r *importReader) node() *Node {
|
|||
if !r.bool() /* !implicit, i.e. '&' operator */ {
|
||||
if n.Op == OCOMPLIT {
|
||||
// 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)
|
||||
} else {
|
||||
n = nodl(pos, OADDR, n, nil)
|
||||
|
@ -886,7 +887,7 @@ func (r *importReader) node() *Node {
|
|||
n.SetSliceBounds(low, high, max)
|
||||
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
|
||||
|
||||
case OCONV:
|
||||
|
@ -898,7 +899,7 @@ func (r *importReader) node() *Node {
|
|||
n := npos(r.pos(), builtinCall(op))
|
||||
n.List.Set(r.exprList())
|
||||
if op == OAPPEND {
|
||||
n.SetIsddd(r.bool())
|
||||
n.SetIsDDD(r.bool())
|
||||
}
|
||||
return n
|
||||
|
||||
|
@ -908,7 +909,7 @@ func (r *importReader) node() *Node {
|
|||
case OCALL:
|
||||
n := nodl(r.pos(), OCALL, r.expr(), nil)
|
||||
n.List.Set(r.exprList())
|
||||
n.SetIsddd(r.bool())
|
||||
n.SetIsDDD(r.bool())
|
||||
return n
|
||||
|
||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||
|
@ -918,7 +919,7 @@ func (r *importReader) node() *Node {
|
|||
return n
|
||||
|
||||
// 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)
|
||||
|
||||
// binary expressions
|
||||
|
@ -981,7 +982,7 @@ func (r *importReader) node() *Node {
|
|||
// case ORETJMP:
|
||||
// unreachable - generated by compiler for trampolin routines (not exported)
|
||||
|
||||
case OPROC, ODEFER:
|
||||
case OGO, ODEFER:
|
||||
return nodl(r.pos(), op, r.expr(), nil)
|
||||
|
||||
case OIF:
|
||||
|
@ -1052,7 +1053,7 @@ func (r *importReader) node() *Node {
|
|||
|
||||
default:
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ func anyinit(n []*Node) bool {
|
|||
|
||||
// fninit hand-crafts package initialization code.
|
||||
//
|
||||
// func init.ializers() { (0)
|
||||
// <init stmts>
|
||||
// }
|
||||
// var initdone· uint8 (1)
|
||||
// func init() { (2)
|
||||
// if initdone· > 1 { (3)
|
||||
|
@ -68,7 +71,7 @@ func anyinit(n []*Node) bool {
|
|||
// initdone· = 1 (5)
|
||||
// // over all matching imported symbols
|
||||
// <pkg>.init() (6)
|
||||
// { <init stmts> } (7)
|
||||
// init.ializers() (7)
|
||||
// init.<n>() // if any (8)
|
||||
// initdone· = 2 (9)
|
||||
// return (10)
|
||||
|
@ -80,6 +83,27 @@ func fninit(n []*Node) {
|
|||
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
|
||||
|
||||
// (1)
|
||||
|
@ -130,7 +154,11 @@ func fninit(n []*Node) {
|
|||
}
|
||||
|
||||
// (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)
|
||||
|
||||
|
@ -166,7 +194,7 @@ func fninit(n []*Node) {
|
|||
rhs := asNode(s.Def)
|
||||
rhs.checkInitFuncSignature()
|
||||
as := nod(OAS, lhs, rhs)
|
||||
as = typecheck(as, Etop)
|
||||
as = typecheck(as, ctxStmt)
|
||||
genAsStatic(as)
|
||||
}
|
||||
|
||||
|
@ -187,7 +215,7 @@ func fninit(n []*Node) {
|
|||
loop.Nbody.Set1(body)
|
||||
loop.Ninit.Set1(zero)
|
||||
|
||||
loop = typecheck(loop, Etop)
|
||||
loop = typecheck(loop, ctxStmt)
|
||||
r = append(r, loop)
|
||||
}
|
||||
|
||||
|
@ -206,8 +234,8 @@ func fninit(n []*Node) {
|
|||
funcbody()
|
||||
|
||||
Curfn = fn
|
||||
fn = typecheck(fn, Etop)
|
||||
typecheckslice(r, Etop)
|
||||
fn = typecheck(fn, ctxStmt)
|
||||
typecheckslice(r, ctxStmt)
|
||||
Curfn = nil
|
||||
funccompile(fn)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ const (
|
|||
inlineMaxBudget = 80
|
||||
inlineExtraAppendCost = 0
|
||||
// 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.
|
||||
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
|
||||
Curfn = fn
|
||||
typecheckslice(fn.Func.Inl.Body, Etop)
|
||||
typecheckslice(fn.Func.Inl.Body, ctxStmt)
|
||||
Curfn = savefn
|
||||
|
||||
// During typechecking, declarations are added to
|
||||
|
@ -377,7 +377,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
|||
OFORUNTIL,
|
||||
OSELECT,
|
||||
OTYPESW,
|
||||
OPROC,
|
||||
OGO,
|
||||
ODEFER,
|
||||
ODCLTYPE, // can't print yet
|
||||
OBREAK,
|
||||
|
@ -552,7 +552,7 @@ func inlnode(n *Node, maxCost int32) *Node {
|
|||
|
||||
switch n.Op {
|
||||
// inhibit inlining of their argument
|
||||
case ODEFER, OPROC:
|
||||
case ODEFER, OGO:
|
||||
switch n.Left.Op {
|
||||
case OCALLFUNC, OCALLMETH:
|
||||
n.Left.SetNoInline(true)
|
||||
|
@ -620,7 +620,7 @@ func inlnode(n *Node, maxCost int32) *Node {
|
|||
n.Rlist.Set(inlconv2list(n.Rlist.First()))
|
||||
n.Op = OAS2
|
||||
n.SetTypecheck(0)
|
||||
n = typecheck(n, Etop)
|
||||
n = typecheck(n, ctxStmt)
|
||||
} else {
|
||||
s := n.Rlist.Slice()
|
||||
for i1, n1 := range s {
|
||||
|
@ -815,7 +815,7 @@ func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node {
|
|||
return inlvar
|
||||
}
|
||||
|
||||
return typecheck(nblank, Erv|Easgn)
|
||||
return typecheck(nblank, ctxExpr|ctxAssign)
|
||||
}
|
||||
|
||||
var inlgen int
|
||||
|
@ -897,21 +897,21 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
|
|||
}
|
||||
|
||||
if v.Name.Byval() {
|
||||
iv := typecheck(inlvar(v), Erv)
|
||||
iv := typecheck(inlvar(v), ctxExpr)
|
||||
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
|
||||
} else {
|
||||
addr := newname(lookup("&" + v.Sym.Name))
|
||||
addr.Type = types.NewPtr(v.Type)
|
||||
ia := typecheck(inlvar(addr), Erv)
|
||||
ia := typecheck(inlvar(addr), ctxExpr)
|
||||
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
|
||||
|
||||
// When capturing by reference, all occurrence of the captured var
|
||||
// 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
|
||||
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 {
|
||||
ninit.Append(nod(ODCL, inlvars[ln], nil))
|
||||
}
|
||||
|
@ -950,7 +950,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
|
|||
mpos := t.Pos
|
||||
if n := asNode(t.Nname); n != nil && !n.isBlank() {
|
||||
m = inlvar(n)
|
||||
m = typecheck(m, Erv)
|
||||
m = typecheck(m, ctxExpr)
|
||||
inlvars[n] = m
|
||||
} else {
|
||||
// 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)
|
||||
}
|
||||
ras := nod(OAS, tinlvar(rcv, inlvars), n.Left.Left)
|
||||
ras = typecheck(ras, Etop)
|
||||
ras = typecheck(ras, ctxStmt)
|
||||
ninit.Append(ras)
|
||||
} else {
|
||||
// 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
|
||||
// dotted calls, just add the variable to the
|
||||
// assignment list, and we're done.
|
||||
if !param.Isddd() || n.Isddd() {
|
||||
if !param.IsDDD() || n.IsDDD() {
|
||||
as.List.Append(tinlvar(param, inlvars))
|
||||
continue
|
||||
}
|
||||
|
@ -1037,19 +1037,19 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
|
|||
}
|
||||
|
||||
if as.Rlist.Len() != 0 {
|
||||
as = typecheck(as, Etop)
|
||||
as = typecheck(as, ctxStmt)
|
||||
ninit.Append(as)
|
||||
}
|
||||
|
||||
if vas != nil {
|
||||
vas = typecheck(vas, Etop)
|
||||
vas = typecheck(vas, ctxStmt)
|
||||
ninit.Append(vas)
|
||||
}
|
||||
|
||||
// Zero the return parameters.
|
||||
for _, n := range retvars {
|
||||
ras := nod(OAS, n, nil)
|
||||
ras = typecheck(ras, Etop)
|
||||
ras = typecheck(ras, ctxStmt)
|
||||
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())
|
||||
|
||||
// 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 !fn.Sym.Linksym().WasInlined() {
|
||||
Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn)
|
||||
|
@ -1083,7 +1092,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
|
|||
lab := nodSym(OLABEL, nil, retlabel)
|
||||
body = append(body, lab)
|
||||
|
||||
typecheckslice(body, Etop)
|
||||
typecheckslice(body, ctxStmt)
|
||||
|
||||
if genDwarfInline > 0 {
|
||||
for _, v := range inlfvars {
|
||||
|
@ -1239,12 +1248,12 @@ func (subst *inlsubst) node(n *Node) *Node {
|
|||
as.List.Append(n)
|
||||
}
|
||||
as.Rlist.Set(subst.list(n.List))
|
||||
as = typecheck(as, Etop)
|
||||
as = typecheck(as, ctxStmt)
|
||||
m.Ninit.Append(as)
|
||||
}
|
||||
|
||||
typecheckslice(m.Ninit.Slice(), Etop)
|
||||
m = typecheck(m, Etop)
|
||||
typecheckslice(m.Ninit.Slice(), ctxStmt)
|
||||
m = typecheck(m, ctxStmt)
|
||||
|
||||
// dump("Return after substitution", m);
|
||||
return m
|
||||
|
|
|
@ -85,7 +85,7 @@ func TestIntendedInlining(t *testing.T) {
|
|||
"puintptr.ptr",
|
||||
"spanOf",
|
||||
"spanOfUnchecked",
|
||||
"(*gcWork).putFast",
|
||||
//"(*gcWork).putFast", // TODO(austin): For debugging #27993
|
||||
"(*gcWork).tryGetFast",
|
||||
"(*guintptr).set",
|
||||
"(*markBits).advance",
|
||||
|
@ -104,6 +104,7 @@ func TestIntendedInlining(t *testing.T) {
|
|||
"(*Buffer).Bytes",
|
||||
"(*Buffer).Cap",
|
||||
"(*Buffer).Len",
|
||||
"(*Buffer).Grow",
|
||||
"(*Buffer).Next",
|
||||
"(*Buffer).Read",
|
||||
"(*Buffer).ReadByte",
|
||||
|
|
|
@ -41,6 +41,11 @@ func TestInvalidLang(t *testing.T) {
|
|||
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 {
|
||||
t.Error("compilation with -lang=go1.8 succeeded unexpectedly")
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ var (
|
|||
|
||||
var (
|
||||
Debug_append int
|
||||
Debug_asm bool
|
||||
Debug_closure int
|
||||
Debug_compilelater int
|
||||
debug_dclstack int
|
||||
|
@ -195,7 +194,7 @@ func Main(archInit func(*Arch)) {
|
|||
objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
|
||||
objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
|
||||
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.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
|
||||
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`")
|
||||
var goversion string
|
||||
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(&blockprofile, "blockprofile", "", "write block 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_optimize = Debug['N'] == 0
|
||||
|
||||
Ctxt.Debugasm = Debug_asm
|
||||
Ctxt.Debugasm = Debug['S']
|
||||
Ctxt.Debugvlog = Debug_vlog
|
||||
if flagDWARF {
|
||||
Ctxt.DebugInfo = debuginfo
|
||||
|
@ -285,6 +287,10 @@ func Main(archInit func(*Arch)) {
|
|||
|
||||
checkLang()
|
||||
|
||||
if symabisPath != "" {
|
||||
readSymABIs(symabisPath, myimportpath)
|
||||
}
|
||||
|
||||
thearch.LinkArch.Init(Ctxt)
|
||||
|
||||
if outfile == "" {
|
||||
|
@ -431,9 +437,16 @@ func Main(archInit func(*Arch)) {
|
|||
}
|
||||
|
||||
ssaDump = os.Getenv("GOSSAFUNC")
|
||||
if strings.HasSuffix(ssaDump, "+") {
|
||||
ssaDump = ssaDump[:len(ssaDump)-1]
|
||||
ssaDumpStdout = true
|
||||
if ssaDump != "" {
|
||||
if strings.HasSuffix(ssaDump, "+") {
|
||||
ssaDump = ssaDump[:len(ssaDump)-1]
|
||||
ssaDumpStdout = true
|
||||
}
|
||||
spl := strings.Split(ssaDump, ":")
|
||||
if len(spl) > 1 {
|
||||
ssaDump = spl[0]
|
||||
ssaDumpCFG = spl[1]
|
||||
}
|
||||
}
|
||||
|
||||
trackScopes = flagDWARF
|
||||
|
@ -502,7 +515,7 @@ func Main(archInit func(*Arch)) {
|
|||
for i := 0; i < len(xtop); i++ {
|
||||
n := xtop[i]
|
||||
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++ {
|
||||
n := xtop[i]
|
||||
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()
|
||||
|
@ -529,7 +542,7 @@ func Main(archInit func(*Arch)) {
|
|||
Curfn = n
|
||||
decldepth = 1
|
||||
saveerrors()
|
||||
typecheckslice(Curfn.Nbody.Slice(), Etop)
|
||||
typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
|
||||
checkreturn(Curfn)
|
||||
if nerrors != 0 {
|
||||
Curfn.Nbody.Set(nil) // type errors; do not compile
|
||||
|
@ -681,7 +694,7 @@ func Main(archInit func(*Arch)) {
|
|||
timings.Start("be", "externaldcls")
|
||||
for i, n := range externdcl {
|
||||
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
|
||||
|
@ -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() {
|
||||
nsavederrors += nerrors
|
||||
nerrors = 0
|
||||
|
@ -1236,6 +1324,7 @@ var concurrentFlagOK = [256]bool{
|
|||
'l': true, // disable inlining
|
||||
'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 {
|
||||
|
@ -1244,15 +1333,15 @@ func concurrentBackendAllowed() bool {
|
|||
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.
|
||||
// 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.
|
||||
if Debug_vlog || debugstr != "" || debuglive > 0 {
|
||||
return false
|
||||
}
|
||||
// TODO: Test and delete these conditions.
|
||||
if objabi.Fieldtrack_enabled != 0 || objabi.Clobberdead_enabled != 0 {
|
||||
// TODO: Test and delete this condition.
|
||||
if objabi.Fieldtrack_enabled != 0 {
|
||||
return false
|
||||
}
|
||||
// TODO: fix races and enable the following flags
|
||||
|
@ -1366,7 +1455,7 @@ func checkLang() {
|
|||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
|
||||
"cmd/compile/internal/syntax"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"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...)
|
||||
lineno = src.NoXPos
|
||||
clearImports()
|
||||
|
@ -484,7 +497,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
|||
}
|
||||
} else {
|
||||
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
|
||||
if typ.Op == ODDD {
|
||||
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 {
|
||||
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.Right = typ.Left
|
||||
typ.Left = nil
|
||||
n.SetIsddd(true)
|
||||
n.SetIsDDD(true)
|
||||
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?
|
||||
if x.Op == OCOMPLIT {
|
||||
// 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)
|
||||
return x
|
||||
}
|
||||
|
@ -630,7 +660,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
|||
case *syntax.CallExpr:
|
||||
n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
|
||||
n.List.Set(p.exprs(expr.ArgList))
|
||||
n.SetIsddd(expr.HasDots)
|
||||
n.SetIsDDD(expr.HasDots)
|
||||
return n
|
||||
|
||||
case *syntax.ArrayType:
|
||||
|
@ -857,7 +887,7 @@ func (p *noder) embedded(typ syntax.Expr) *Node {
|
|||
n.SetEmbedded(true)
|
||||
|
||||
if isStar {
|
||||
n.Left = p.nod(op, OIND, n.Left, nil)
|
||||
n.Left = p.nod(op, ODEREF, n.Left, nil)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
@ -956,7 +986,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
|
|||
case syntax.Defer:
|
||||
op = ODEFER
|
||||
case syntax.Go:
|
||||
op = OPROC
|
||||
op = OGO
|
||||
default:
|
||||
panic("unhandled CallStmt")
|
||||
}
|
||||
|
@ -1232,13 +1262,13 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
|
|||
|
||||
var unOps = [...]Op{
|
||||
syntax.Recv: ORECV,
|
||||
syntax.Mul: OIND,
|
||||
syntax.Mul: ODEREF,
|
||||
syntax.And: OADDR,
|
||||
|
||||
syntax.Not: ONOT,
|
||||
syntax.Xor: OCOM,
|
||||
syntax.Xor: OBITNOT,
|
||||
syntax.Add: OPLUS,
|
||||
syntax.Sub: OMINUS,
|
||||
syntax.Sub: ONEG,
|
||||
}
|
||||
|
||||
func (p *noder) unOp(op syntax.Operator) Op {
|
||||
|
|
|
@ -4,9 +4,9 @@ package gc
|
|||
|
||||
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 {
|
||||
if i >= Op(len(_Op_index)-1) {
|
||||
|
|
|
@ -81,7 +81,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
|
|||
}
|
||||
if clear {
|
||||
a := nod(OAS, v, nil)
|
||||
a = typecheck(a, Etop)
|
||||
a = typecheck(a, ctxStmt)
|
||||
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 {
|
||||
v := o.newTemp(t, clear)
|
||||
a := nod(OAS, v, n)
|
||||
a = typecheck(a, Etop)
|
||||
a = typecheck(a, ctxStmt)
|
||||
o.out = append(o.out, a)
|
||||
return v
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ func (o *Order) cheapExpr(n *Node) *Node {
|
|||
}
|
||||
a := n.sepcopy()
|
||||
a.Left = l
|
||||
return typecheck(a, Erv)
|
||||
return typecheck(a, ctxExpr)
|
||||
}
|
||||
|
||||
return o.copyExpr(n, n.Type, false)
|
||||
|
@ -153,16 +153,16 @@ func (o *Order) safeExpr(n *Node) *Node {
|
|||
}
|
||||
a := n.sepcopy()
|
||||
a.Left = l
|
||||
return typecheck(a, Erv)
|
||||
return typecheck(a, ctxExpr)
|
||||
|
||||
case ODOTPTR, OIND:
|
||||
case ODOTPTR, ODEREF:
|
||||
l := o.cheapExpr(n.Left)
|
||||
if l == n.Left {
|
||||
return n
|
||||
}
|
||||
a := n.sepcopy()
|
||||
a.Left = l
|
||||
return typecheck(a, Erv)
|
||||
return typecheck(a, ctxExpr)
|
||||
|
||||
case OINDEX, OINDEXMAP:
|
||||
var l *Node
|
||||
|
@ -178,7 +178,7 @@ func (o *Order) safeExpr(n *Node) *Node {
|
|||
a := n.sepcopy()
|
||||
a.Left = l
|
||||
a.Right = r
|
||||
return typecheck(a, Erv)
|
||||
return typecheck(a, ctxExpr)
|
||||
|
||||
default:
|
||||
Fatalf("ordersafeexpr %v", n.Op)
|
||||
|
@ -213,7 +213,7 @@ func (o *Order) addrTemp(n *Node) *Node {
|
|||
if out != nil {
|
||||
Fatalf("staticassign of const generated code: %+v", n)
|
||||
}
|
||||
vstat = typecheck(vstat, Erv)
|
||||
vstat = typecheck(vstat, ctxExpr)
|
||||
return vstat
|
||||
}
|
||||
if isaddrokay(n) {
|
||||
|
@ -233,7 +233,7 @@ func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
|
|||
return n
|
||||
}
|
||||
|
||||
// mapKeyReplaceStrConv replaces OARRAYBYTESTR by OARRAYBYTESTRTMP
|
||||
// mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
|
||||
// in n to avoid string allocations for keys in map lookups.
|
||||
// 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 {
|
||||
var replaced bool
|
||||
switch n.Op {
|
||||
case OARRAYBYTESTR:
|
||||
n.Op = OARRAYBYTESTRTMP
|
||||
case OBYTES2STR:
|
||||
n.Op = OBYTES2STRTMP
|
||||
replaced = true
|
||||
case OSTRUCTLIT:
|
||||
for _, elem := range n.List.Slice() {
|
||||
|
@ -300,11 +300,11 @@ func (o *Order) cleanTempNoPop(mark ordermarker) []*Node {
|
|||
n.Name.SetKeepalive(false)
|
||||
n.SetAddrtaken(true) // ensure SSA keeps the n variable
|
||||
live := nod(OVARLIVE, n, nil)
|
||||
live = typecheck(live, Etop)
|
||||
live = typecheck(live, ctxStmt)
|
||||
out = append(out, live)
|
||||
}
|
||||
kill := nod(OVARKILL, n, nil)
|
||||
kill = typecheck(kill, Etop)
|
||||
kill = typecheck(kill, ctxStmt)
|
||||
out = append(out, kill)
|
||||
}
|
||||
return out
|
||||
|
@ -418,7 +418,7 @@ func (o *Order) copyRet(n *Node) []*Node {
|
|||
as := nod(OAS2, nil, nil)
|
||||
as.List.Set(l1)
|
||||
as.Rlist.Set1(n)
|
||||
as = typecheck(as, Etop)
|
||||
as = typecheck(as, ctxStmt)
|
||||
o.stmt(as)
|
||||
|
||||
return l2
|
||||
|
@ -463,7 +463,7 @@ func (o *Order) call(n *Node) {
|
|||
|
||||
for i, t := range n.Left.Type.Params().FieldSlice() {
|
||||
// Check for "unsafe-uintptr" tag provided by escape analysis.
|
||||
if t.Isddd() && !n.Isddd() {
|
||||
if t.IsDDD() && !n.IsDDD() {
|
||||
if t.Note == uintptrEscapesTag {
|
||||
for ; i < n.List.Len(); i++ {
|
||||
keepAlive(i)
|
||||
|
@ -528,7 +528,7 @@ func (o *Order) mapAssign(n *Node) {
|
|||
t := o.newTemp(m.Type, false)
|
||||
n.List.SetIndex(i, t)
|
||||
a := nod(OAS, m, t)
|
||||
a = typecheck(a, Etop)
|
||||
a = typecheck(a, ctxStmt)
|
||||
post = append(post, a)
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ func (o *Order) stmt(n *Node) {
|
|||
default:
|
||||
Fatalf("orderstmt %v", n.Op)
|
||||
|
||||
case OVARKILL, OVARLIVE:
|
||||
case OVARKILL, OVARLIVE, OINLMARK:
|
||||
o.out = append(o.out, n)
|
||||
|
||||
case OAS:
|
||||
|
@ -602,7 +602,7 @@ func (o *Order) stmt(n *Node) {
|
|||
}
|
||||
l = o.copyExpr(l, n.Left.Type, false)
|
||||
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.Op = OAS
|
||||
|
@ -657,10 +657,10 @@ func (o *Order) stmt(n *Node) {
|
|||
tmp2 := o.newTemp(types.Types[TBOOL], false)
|
||||
o.out = append(o.out, n)
|
||||
r := nod(OAS, n.List.First(), tmp1)
|
||||
r = typecheck(r, Etop)
|
||||
r = typecheck(r, ctxStmt)
|
||||
o.mapAssign(r)
|
||||
r = okas(n.List.Second(), tmp2)
|
||||
r = typecheck(r, Etop)
|
||||
r = typecheck(r, ctxStmt)
|
||||
o.mapAssign(r)
|
||||
n.List.Set2(tmp1, tmp2)
|
||||
o.cleanTemp(t)
|
||||
|
@ -689,7 +689,7 @@ func (o *Order) stmt(n *Node) {
|
|||
o.cleanTemp(t)
|
||||
|
||||
// Special: order arguments to inner call but not call itself.
|
||||
case ODEFER, OPROC:
|
||||
case ODEFER, OGO:
|
||||
t := o.markTemp()
|
||||
o.call(n.Left)
|
||||
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.
|
||||
// It is safe because the storage cannot be mutated.
|
||||
if n.Right.Op == OSTRARRAYBYTE {
|
||||
n.Right.Op = OSTRARRAYBYTETMP
|
||||
if n.Right.Op == OSTR2BYTES {
|
||||
n.Right.Op = OSTR2BYTESTMP
|
||||
}
|
||||
|
||||
t := o.markTemp()
|
||||
|
@ -779,7 +779,7 @@ func (o *Order) stmt(n *Node) {
|
|||
if r.Type.IsString() && r.Type != types.Types[TSTRING] {
|
||||
r = nod(OCONV, r, nil)
|
||||
r.Type = types.Types[TSTRING]
|
||||
r = typecheck(r, Erv)
|
||||
r = typecheck(r, ctxExpr)
|
||||
}
|
||||
|
||||
n.Right = o.copyExpr(r, r.Type, false)
|
||||
|
@ -897,13 +897,13 @@ func (o *Order) stmt(n *Node) {
|
|||
|
||||
if r.Colas() {
|
||||
tmp2 := nod(ODCL, tmp1, nil)
|
||||
tmp2 = typecheck(tmp2, Etop)
|
||||
tmp2 = typecheck(tmp2, ctxStmt)
|
||||
n2.Ninit.Append(tmp2)
|
||||
}
|
||||
|
||||
r.Left = o.newTemp(r.Right.Left.Type.Elem(), types.Haspointers(r.Right.Left.Type.Elem()))
|
||||
tmp2 := nod(OAS, tmp1, r.Left)
|
||||
tmp2 = typecheck(tmp2, Etop)
|
||||
tmp2 = typecheck(tmp2, ctxStmt)
|
||||
n2.Ninit.Append(tmp2)
|
||||
}
|
||||
|
||||
|
@ -914,13 +914,13 @@ func (o *Order) stmt(n *Node) {
|
|||
tmp1 := r.List.First()
|
||||
if r.Colas() {
|
||||
tmp2 := nod(ODCL, tmp1, nil)
|
||||
tmp2 = typecheck(tmp2, Etop)
|
||||
tmp2 = typecheck(tmp2, ctxStmt)
|
||||
n2.Ninit.Append(tmp2)
|
||||
}
|
||||
|
||||
r.List.Set1(o.newTemp(types.Types[TBOOL], false))
|
||||
tmp2 := okas(tmp1, r.List.First())
|
||||
tmp2 = typecheck(tmp2, Etop)
|
||||
tmp2 = typecheck(tmp2, ctxStmt)
|
||||
n2.Ninit.Append(tmp2)
|
||||
}
|
||||
orderBlock(&n2.Ninit, o.free)
|
||||
|
@ -1064,14 +1064,14 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
|||
|
||||
haslit := false
|
||||
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
|
||||
}
|
||||
|
||||
if haslit && hasbyte {
|
||||
for _, n2 := range n.List.Slice() {
|
||||
if n2.Op == OARRAYBYTESTR {
|
||||
n2.Op = OARRAYBYTESTRTMP
|
||||
if n2.Op == OBYTES2STR {
|
||||
n2.Op = OBYTES2STRTMP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1153,9 +1153,9 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
|||
ONEW,
|
||||
OREAL,
|
||||
ORECOVER,
|
||||
OSTRARRAYBYTE,
|
||||
OSTRARRAYBYTETMP,
|
||||
OSTRARRAYRUNE:
|
||||
OSTR2BYTES,
|
||||
OSTR2BYTESTMP,
|
||||
OSTR2RUNES:
|
||||
|
||||
if isRuneCount(n) {
|
||||
// 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
|
||||
// buffer during conversion. String comparison does not
|
||||
// memorize the strings for later use, so it is safe.
|
||||
if n.Left.Op == OARRAYBYTESTR {
|
||||
n.Left.Op = OARRAYBYTESTRTMP
|
||||
if n.Left.Op == OBYTES2STR {
|
||||
n.Left.Op = OBYTES2STRTMP
|
||||
}
|
||||
if n.Right.Op == OARRAYBYTESTR {
|
||||
n.Right.Op = OARRAYBYTESTRTMP
|
||||
if n.Right.Op == OBYTES2STR {
|
||||
n.Right.Op = OBYTES2STRTMP
|
||||
}
|
||||
|
||||
case t.IsStruct() || t.IsArray():
|
||||
|
@ -1301,7 +1301,7 @@ func (o *Order) as2(n *Node) {
|
|||
as := nod(OAS2, nil, nil)
|
||||
as.List.Set(left)
|
||||
as.Rlist.Set(tmplist)
|
||||
as = typecheck(as, Etop)
|
||||
as = typecheck(as, ctxStmt)
|
||||
o.stmt(as)
|
||||
}
|
||||
|
||||
|
@ -1322,13 +1322,13 @@ func (o *Order) okAs2(n *Node) {
|
|||
|
||||
if tmp1 != nil {
|
||||
r := nod(OAS, n.List.First(), tmp1)
|
||||
r = typecheck(r, Etop)
|
||||
r = typecheck(r, ctxStmt)
|
||||
o.mapAssign(r)
|
||||
n.List.SetFirst(tmp1)
|
||||
}
|
||||
if tmp2 != nil {
|
||||
r := okas(n.List.Second(), tmp2)
|
||||
r = typecheck(r, Etop)
|
||||
r = typecheck(r, ctxStmt)
|
||||
o.mapAssign(r)
|
||||
n.List.SetSecond(tmp2)
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue