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

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

View file

@ -418,7 +418,7 @@ Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com>
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>

View file

@ -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>

View file

@ -386,15 +386,11 @@ pkg syscall (windows-amd64), type RawSockaddrAny struct, Pad [96]int8
pkg syscall (freebsd-386), func Mknod(string, uint32, int) error
pkg syscall (freebsd-386), 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
View file

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

View file

@ -276,7 +276,7 @@ CodewalkViewer.prototype.changeSelectedComment = function(target) {
}
// Force original file even if user hasn't changed comments since they may
// 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);
};

View file

@ -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>

View file

@ -49,6 +49,23 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.11.2">Go
1.11.2 milestone</a> on our issue tracker for details.
</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>

View file

@ -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>

View file

@ -1710,7 +1710,7 @@ prints
&amp;{7 -2.35 abc def}
&amp;{a:7 b:-2.35 c:abc def}
&amp;main.T{a:7, b:-2.35, c:"abc\tdef"}
map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}
map[string]int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}
</pre>
<p>
(Note the ampersands.)
@ -1733,7 +1733,7 @@ fmt.Printf(&quot;%T\n&quot;, 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))
}

View file

@ -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>&nbsp;<code>run</code></a>
command now allows a single import path, a directory name or a
pattern matching a single package.
This allows <code>go</code>&nbsp;<code>run</code>&nbsp;<code>pkg</code> or <code>go</code>&nbsp;<code>run</code>&nbsp;<code>dir</code>, most importantly <code>go</code>&nbsp;<code>run</code>&nbsp;<code>.</code>
</p>
<h2 id="runtime">Runtime</h2>
<p><!-- CL 85887 -->

View file

@ -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>&lt;nil&gt;</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 &#34;hurd&#34; as a GOOS value
</p>
</dl><!-- go/build, cmd/go -->
<dl id="go/doc"><dt><a href="/pkg/go/doc/">go/doc</a></dt>
<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&#39;t error on non-chunked response with Trailer header
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer rejects HTTP responses which declare
HTTP Trailers but don't use chunked encoding. Instead, the declared trailers are now just ignored.
</p>
<p><!-- CL 152080 --> <!-- CL 151857 -->
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer handles <code>MAX_CONCURRENT_STREAMS</code> values
advertised from HTTP/2 servers as strictly as it did during Go 1.10 and Go 1.11. The default behavior is now back
to how it was in Go 1.9: each connection to a server can have up to <code>MAX_CONCURRENT_STREAMS</code> requests
active and then new TCP connections are created as needed. In Go 1.10 and Go 1.11 the <code>http2</code> package
would block and wait for requests to finish instead of creating new connections.
To get the stricter behavior back, import the
<a href="https://godoc.org/golang.org/x/net/http2"><code>golang.org/x/net/http2</code></a> package
directly and set
<a href="https://godoc.org/golang.org/x/net/http2#Transport.StrictMaxConcurrentStreams"><code>Transport.StrictMaxConcurrentStreams</code></a> to
<code>true</code>.
</p>
</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 &#34;undefined&#34;
The meaning of the zero
<a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Value"><code>Value</code></a>
has changed. It now represents the JavaScript <code>undefined</code> value
instead of the number zero.
This is a breaking change, but WebAssembly support is still experimental
and not yet subject to the
<a href="/doc/go1compat">Go 1 compatibility promise</a>. Any code relying on
the zero <a href="/pkg/syscall/js/?GOOS=js&GOARCH=wasm#Value"><code>Value</code></a>
to mean the number zero will need to be updated.
</p>
<p><!-- 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 -->

View file

@ -1769,7 +1769,7 @@ while that of the corresponding pointer
type <code>*T</code> consists of all methods with receiver <code>*T</code> or
<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>

View file

@ -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>

View file

@ -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>&amp;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" "&lt;-" | "&lt;-" "chan" ) ElementType .
The optional <code>&lt;-</code> operator specifies the channel <i>direction</i>,
<i>send</i> or <i>receive</i>. If no direction is given, the channel is
<i>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>&lt;&lt;</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 &lt; x + 1</code> is always true.
</p>

View file

@ -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>

View file

@ -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 += " "
}

View file

@ -70,7 +70,7 @@ This person coordinates the fix and release process.</li>
<li>Code is audited to find any potential similar problems.</li>
<li>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

View file

@ -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.

View file

@ -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)
}
}
}

View 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)
}

View file

@ -0,0 +1,17 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// int a;
// void CF(int i) {}
import "C"
func F1(i int) int {
return C.a + 1 // ERROR HERE: :13
}
func F2(i int) {
C.CF(i) // ERROR HERE: :6
}

View file

@ -0,0 +1,26 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test that the error message for an unrepresentable typedef in a
// union appears on the right line. This test is only run if the size
// of long double is larger than 64.
package main
/*
typedef long double Float128;
typedef struct SV {
union {
Float128 float128;
} value;
} SV;
*/
import "C"
type ts struct {
tv *C.SV // ERROR HERE
}
func main() {}

View file

@ -0,0 +1,29 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// cgo should reject the use of mangled C names.
package main
/*
typedef struct a {
int i;
} a;
void fn(void) {}
*/
import "C"
type B _Ctype_struct_a // ERROR HERE
var a _Ctype_struct_a // ERROR HERE
type A struct {
a *_Ctype_struct_a // ERROR HERE
}
var notExist _Ctype_NotExist // ERROR HERE
func main() {
_Cfunc_fn() // ERROR HERE
}

View file

@ -179,7 +179,6 @@ func testCallbackCallers(t *testing.T) {
pc := make([]uintptr, 100)
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)
})

View file

@ -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) }

View file

@ -0,0 +1,7 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This is the relevant part of EGL/egl.h.
typedef void *EGLDisplay;

View file

@ -0,0 +1,17 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package issue27054
/*
#include "egl.h"
*/
import "C"
import (
"testing"
)
func Test27054(t *testing.T) {
var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type.
}

View file

@ -0,0 +1,12 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Failed to resolve typedefs consistently.
// No runtime test; just make sure it compiles.
package cgotest
import "./issue27340"
var issue27340Var = issue27340.Issue27340GoFunc

View file

@ -0,0 +1,42 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Failed to resolve typedefs consistently.
// No runtime test; just make sure it compiles.
// In separate directory to isolate #pragma GCC diagnostic.
package issue27340
// We use the #pragma to avoid a compiler warning about incompatible
// pointer types, because we generate code passing a struct ptr rather
// than using the typedef. This warning is expected and does not break
// a normal build.
// We can only disable -Wincompatible-pointer-types starting with GCC 5.
// #if __GNU_MAJOR__ >= 5
//
// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
//
// typedef struct {
// int a;
// } issue27340Struct, *issue27340Ptr;
//
// static void issue27340CFunc(issue27340Ptr p) {}
//
// #else /* _GNU_MAJOR_ < 5 */
//
// typedef struct {
// int a;
// } issue27340Struct;
//
// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; }
//
// static void issue27340CFunc(issue27340Struct *p) {}
// #endif /* _GNU_MAJOR_ < 5 */
import "C"
func Issue27340GoFunc() {
var s C.issue27340Struct
C.issue27340CFunc(C.issue27340Ptr(&s))
}

View file

@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
// 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)
}

View file

@ -0,0 +1,12 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
// Constants didn't work if defined in different source file.
// #define issue28772Constant2 2
import "C"
const issue28772Constant2 = C.issue28772Constant2

View file

@ -0,0 +1,83 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// cgo was incorrectly adding padding after a packed struct.
package cgotest
/*
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct {
void *f1;
uint32_t f2;
} __attribute__((__packed__)) innerPacked;
typedef struct {
innerPacked g1;
uint64_t g2;
} outerPacked;
typedef struct {
void *f1;
uint32_t f2;
} innerUnpacked;
typedef struct {
innerUnpacked g1;
uint64_t g2;
} outerUnpacked;
size_t offset(int x) {
switch (x) {
case 0:
return offsetof(innerPacked, f2);
case 1:
return offsetof(outerPacked, g2);
case 2:
return offsetof(innerUnpacked, f2);
case 3:
return offsetof(outerUnpacked, g2);
default:
abort();
}
}
*/
import "C"
import (
"testing"
"unsafe"
)
func offset(i int) uintptr {
var pi C.innerPacked
var po C.outerPacked
var ui C.innerUnpacked
var uo C.outerUnpacked
switch i {
case 0:
return unsafe.Offsetof(pi.f2)
case 1:
return unsafe.Offsetof(po.g2)
case 2:
return unsafe.Offsetof(ui.f2)
case 3:
return unsafe.Offsetof(uo.g2)
default:
panic("can't happen")
}
}
func test28896(t *testing.T) {
for i := 0; i < 4; i++ {
c := uintptr(C.offset(C.int(i)))
g := offset(i)
if c != g {
t.Errorf("%d: C: %d != Go %d", i, c, g)
}
}
}

View file

@ -0,0 +1,19 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// cgo's /*line*/ comments failed when inserted after '/',
// because the result looked like a "//" comment.
// No runtime test; just make sure it compiles.
package cgotest
// #include <stddef.h>
import "C"
func Issue29383(n, size uint) int {
if ^C.size_t(0)/C.size_t(n) < C.size_t(size) {
return 0
}
return 0
}

View file

@ -0,0 +1,22 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Error handling a struct initializer that requires pointer checking.
// Compilation test only, nothing to run.
package cgotest
// typedef struct { char **p; } S29748;
// static int f29748(S29748 *p) { return 0; }
import "C"
var Vissue29748 = C.f29748(&C.S29748{
nil,
})
func Fissue299748() {
C.f29748(&C.S29748{
nil,
})
}

View file

@ -0,0 +1,17 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Error with newline inserted into constant expression.
// Compilation test only, nothing to run.
package cgotest
// static void issue29781F(char **p, int n) {}
// #define ISSUE29781C 0
import "C"
func issue29781G() {
var p *C.char
C.issue29781F(&p, C.ISSUE29781C+1)
}

View file

@ -0,0 +1,38 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Don't make a private copy of an array when taking the address of an
// element.
package cgotest
// #include <string.h>
import "C"
import (
"testing"
"unsafe"
)
func test30065(t *testing.T) {
var a [256]byte
b := []byte("a")
C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1)
if a[0] != 'a' {
t.Errorf("&a failed: got %c, want %c", a[0], 'a')
}
b = []byte("b")
C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1)
if a[0] != 'b' {
t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b')
}
d := make([]byte, 256)
b = []byte("c")
C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1)
if d[0] != 'c' {
t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c')
}
}

View file

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

View file

@ -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)
}

View file

@ -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)
}

View file

@ -0,0 +1,12 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "C"
//export GoFunc
func GoFunc() int { return 1 }
func main() {}

View file

@ -0,0 +1,9 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "libtestgo2c2go.h"
int CFunc(void) {
return (GoFunc() << 8) + 2;
}

View file

@ -0,0 +1,22 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// extern int CFunc(void);
import "C"
import (
"fmt"
"os"
)
func main() {
got := C.CFunc()
const want = (1 << 8) | 2
if got != want {
fmt.Printf("got %#x, want %#x\n", got, want)
os.Exit(1)
}
}

View file

@ -0,0 +1,22 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// #include "libtestgo2c2go.h"
import "C"
import (
"fmt"
"os"
)
func main() {
got := C.GoFunc()
const want = 1
if got != want {
fmt.Printf("got %#x, want %#x\n", got, want)
os.Exit(1)
}
}

View file

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

View file

@ -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")
}

View file

@ -0,0 +1,20 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package issue25065 has a type with a method that is
// 1) referenced in a method expression
// 2) not called
// 3) not converted to an interface
// 4) is a value method but the reference is to the pointer method
// These cases avoid the call to makefuncsym from typecheckfunc, but we
// still need to call makefuncsym somehow or the symbol will not be defined.
package issue25065
type T int
func (t T) M() {}
func F() func(*T) {
return (*T).M
}

View file

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

View file

@ -1,79 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Sortac sorts the AUTHORS and CONTRIBUTORS files.
//
// Usage:
//
// sortac [file...]
//
// Sortac sorts the named files in place.
// If given no arguments, it sorts standard input to standard output.
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)
func main() {
log.SetFlags(0)
log.SetPrefix("sortac: ")
flag.Parse()
args := flag.Args()
if len(args) == 0 {
os.Stdout.Write(sortAC(os.Stdin))
} else {
for _, arg := range args {
f, err := os.Open(arg)
if err != nil {
log.Fatal(err)
}
sorted := sortAC(f)
f.Close()
if err := ioutil.WriteFile(arg, sorted, 0644); err != nil {
log.Fatal(err)
}
}
}
}
func sortAC(r io.Reader) []byte {
bs := bufio.NewScanner(r)
var header []string
var lines []string
for bs.Scan() {
t := bs.Text()
lines = append(lines, t)
if t == "# Please keep the list sorted." {
header = lines
lines = nil
continue
}
}
if err := bs.Err(); err != nil {
log.Fatal(err)
}
var out bytes.Buffer
c := collate.New(language.Und, collate.Loose)
c.SortStrings(lines)
for _, l := range header {
fmt.Fprintln(&out, l)
}
for _, l := range lines {
fmt.Fprintln(&out, l)
}
return out.Bytes()
}

View file

@ -61,6 +61,11 @@
err.code = "ENOSYS";
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();
}
});

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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 {

View file

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

View file

@ -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;

View file

@ -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 {

View file

@ -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)
}

View file

@ -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,

View file

@ -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 {

View file

@ -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
}

View file

@ -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).

View file

@ -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

View file

@ -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 (

View file

@ -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 {

View file

@ -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
}
}
}
}
}
}

View file

@ -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:

View file

@ -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{

View file

@ -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))
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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": "",
}
`

View file

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

View file

@ -141,7 +141,7 @@ func zeroAuto(pp *gc.Progs, n *gc.Node) {
}
}
func ginsnop(pp *gc.Progs) {
func ginsnop(pp *gc.Progs) *obj.Prog {
// This is actually not the x86 NOP anymore,
// 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
}

View file

@ -68,11 +68,12 @@ func zeroAuto(pp *gc.Progs, n *gc.Node) {
}
}
func ginsnop(pp *gc.Progs) {
func ginsnop(pp *gc.Progs) *obj.Prog {
p := pp.Prog(arm.AAND)
p.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
}

View file

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

View file

@ -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)

View file

@ -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 {

View file

@ -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

View file

@ -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)

View file

@ -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
}

View file

@ -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

View file

@ -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))

View file

@ -62,13 +62,6 @@ func autoexport(n *Node, ctxt Class) {
}
}
// methodbyname sorts types by symbol name.
type methodbyname []*types.Field
func (x methodbyname) Len() int { return len(x) }
func (x methodbyname) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x methodbyname) Less(i, j int) bool { return x[i].Sym.Name < x[j].Sym.Name }
func dumpexport(bout *bio.Writer) {
// 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
}

View file

@ -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 "<...>"
}

View file

@ -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()
}

View file

@ -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{

View file

@ -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,

View file

@ -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

View file

@ -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))
}
}

View file

@ -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
}
}

View file

@ -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)
}

View file

@ -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

View file

@ -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",

View file

@ -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")
}

View file

@ -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)
}
}

View file

@ -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 {

View file

@ -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) {

View file

@ -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