From 3f2a6b041d910cab08332ae01a8a9fcfe2e9036a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 16 Feb 2022 16:57:28 -0800 Subject: net: add hurd build tag for setReadMsgCloseOnExec Patch from Svante Signell. PR go/103573 PR go/104290 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386216 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3742414..1fdc5a9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -3742e8a154bfec805054b4ebf0809f12dc7694da +90ed127ef053b758288af9c4e43473e257770bc3 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 18 Feb 2022 13:10:34 -0800 Subject: libgo: update to Go1.18rc1 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386594 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 1fdc5a9..073fb4b 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -90ed127ef053b758288af9c4e43473e257770bc3 +fade776395ffe5497d8aae5c0e6bd6d15e09e04a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 3343e7e2c4cd2cd111cda86737f539cc6eda49ff Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 18 Feb 2022 15:04:00 -0800 Subject: libgo: update Hurd support Patches from Svante Signell for PR go/104290. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386797 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 073fb4b..3c0380e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -fade776395ffe5497d8aae5c0e6bd6d15e09e04a +20e74f9ef8206fb02fd28ce3d6e0f01f6fb95dc9 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From a7eeaa48986f37badb78717e3c138a8d02bb01a6 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 21 Feb 2022 09:50:28 -0800 Subject: runtime/internal/syscall: build dummy package if not Linux Fixes libgo build on non-Linux systems. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/387134 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3c0380e..7455d01 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -20e74f9ef8206fb02fd28ce3d6e0f01f6fb95dc9 +aee8eddbfc3ef1b03353a060e79e7d668fb229e2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 3d54f1ffaf77f9dfa75362f2228e6bbd191bcbc8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 22 Feb 2022 15:04:06 -0800 Subject: libgo: update README.gcc Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/387514 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7455d01..424bbeb 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -aee8eddbfc3ef1b03353a060e79e7d668fb229e2 +45fd14ab8baf5e86012a808426f8ef52c1d77943 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 6be8281c16e14e8a06057a38c01d80e56c14fdb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 1 Mar 2022 09:29:37 +0100 Subject: libgo: fix AIX build for the Go1.18 update Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/388635 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 424bbeb..5cf2ace 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -45fd14ab8baf5e86012a808426f8ef52c1d77943 +34dece725f9f8826f4abe86209112626867bc716 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From e71079517f16fee6759bad2be14f574c3548743e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 1 Mar 2022 09:25:26 +0100 Subject: libgo: move golang.org/x/sync/semaphore to gotool packages golang/x/sync/semaphore is required by gofmt.go. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/388634 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5cf2ace..7778cd9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -34dece725f9f8826f4abe86209112626867bc716 +943b95876ca0f14c3cea7067d33170ba76cf0fab The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From c3402486afa8b6f98d6b0cc05cd229526bc7611f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 Mar 2022 10:18:00 -0800 Subject: mkruntimeinc: skip _FILE We don't need it, and it breaks uclibc. PR go/101246 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/390021 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7778cd9..e68d2d9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -943b95876ca0f14c3cea7067d33170ba76cf0fab +787fd4475f9d9101bc138d0b9763b0f5ecca89a9 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 2858e2afcb0a6553a222e724d8426451364ee755 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 8 Mar 2022 13:30:02 -0800 Subject: compiler: ignore function type result name in export data This change ensures that we never output a result name in the export data if there is only a single result. Previously we would output a ? if the single result had a name. That made the output unstable, because the hashing ignores the result name, so whether we output a ? or not depended on how equal hash elements were handled. For https://gcc.gnu.org/PR104832 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/390874 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/types.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e68d2d9..d9b1269 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -787fd4475f9d9101bc138d0b9763b0f5ecca89a9 +5042f7efbdb2d64537dfef53a19e96ee5ec4db2d The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 8267f15..3de0bd3 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -5303,7 +5303,7 @@ Function_type::do_export(Export* exp) const if (results != NULL) { exp->write_c_string(" "); - if (results->size() == 1 && results->begin()->name().empty()) + if (results->size() == 1) exp->write_type(results->begin()->type()); else { -- cgit v1.1 From 69921f4a7ec081c5b37dae13e3372003e4efd49f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 16 Mar 2022 10:31:57 -0700 Subject: libgo: update to final Go 1.18 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/393377 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d9b1269..afaccb0 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -5042f7efbdb2d64537dfef53a19e96ee5ec4db2d +7f33baa09a8172bb2c5f1ca0435d9efe3e194c9b The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 0abc1cbad1687a887d754917927b6023e4dba3ce Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 31 Mar 2022 13:05:37 -0700 Subject: runtime: support PPC32 MUSL register access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on patch by Sören Tempel. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/397394 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index afaccb0..f93eaf4 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7f33baa09a8172bb2c5f1ca0435d9efe3e194c9b +45108f37070afb696b069768700e39a269f1fecb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From af27d545dc6132dcd67d1ee854372ea9cfd2a225 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 13 Apr 2022 14:37:12 -0700 Subject: runtime: use regset indexes for PPC register values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using names depended on , which glibc includes somewhere but musl did not. Change to just always use indexes. Based on patch by Sören Tempel. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/400214 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f93eaf4..75ee2e3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -45108f37070afb696b069768700e39a269f1fecb +323ab0e6fab89978bdbd83dca9c2ad9c5dcd690f The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From d00dd52ea15f9026c327d2f591eb456d6f11df2c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 25 Mar 2022 17:23:50 -0700 Subject: compiler: revert `for package-scope "a = b; b = x" just set "a = x"` Revert CL 245098. It caused incorrect initialization ordering. Adjust the runtime package to work even with the CL reverted. Original description of CL 245098: This avoids requiring an init function to initialize the variable. This can only be done if x is a static initializer. The go1.15rc1 runtime package relies on this optimization. The package has a variable "var maxSearchAddr = maxOffAddr". The maxSearchAddr variable is used by code that runs before package initialization is complete. For golang/go#51913 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/395994 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 37 +++++++------------------------------ 2 files changed, 8 insertions(+), 31 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 75ee2e3..bcb526c 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -323ab0e6fab89978bdbd83dca9c2ad9c5dcd690f +62fc90f52da2f52cbe3b4f10e560dc6aa59baeb5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 30d5c9f..d35c6ba 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1612,31 +1612,16 @@ Gogo::write_globals() // The initializer is constant if it is the zero-value of the // variable's type or if the initial value is an immutable value // that is not copied to the heap. - Expression* init = var->init(); - - // If we see "a = b; b = x", and x is a static - // initializer, just set a to x. - while (init != NULL && init->var_expression() != NULL) - { - Named_object* ino = init->var_expression()->named_object(); - if (!ino->is_variable() || ino->package() != NULL) - break; - Expression* ino_init = ino->var_value()->init(); - if (ino->var_value()->has_pre_init() - || ino_init == NULL - || !ino_init->is_static_initializer()) - break; - init = ino_init; - } - - bool is_static_initializer; - if (init == NULL) + bool is_static_initializer = false; + if (var->init() == NULL) is_static_initializer = true; else { Type* var_type = var->type(); - init = Expression::make_cast(var_type, init, var->location()); - is_static_initializer = init->is_static_initializer(); + Expression* init = var->init(); + Expression* init_cast = + Expression::make_cast(var_type, init, var->location()); + is_static_initializer = init_cast->is_static_initializer(); } // Non-constant variable initializations might need to create @@ -1655,15 +1640,7 @@ Gogo::write_globals() } var_init_fn = init_fndecl; } - - Bexpression* var_binit; - if (init == NULL) - var_binit = NULL; - else - { - Translate_context context(this, var_init_fn, NULL, NULL); - var_binit = init->get_backend(&context); - } + Bexpression* var_binit = var->get_init(this, var_init_fn); if (var_binit == NULL) ; -- cgit v1.1 From 208b7d85d73cbd166e207f0e062cccbdfbf52bb3 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sun, 30 Aug 2020 17:30:07 +0200 Subject: runtime: add special handling for signal 34 The musl libc uses signal 34 internally for setgid (similar to how glibc uses signal 32 and signal 33). For this reason, special handling is needed for this signal in the runtime. The gc implementation already handles the signal accordingly. As such, this commit intends to simply copy the behavior of the Google Go implementation to libgo. See https://go.dev/issues/39343 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/400594 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index bcb526c..eeff61d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -62fc90f52da2f52cbe3b4f10e560dc6aa59baeb5 +8336fe4a5da68d9188dfbc4fb647ccbbe4d60ba4 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From ace4928a29b79ac6aa0c84d6fd78f5dce5fa6190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Fri, 15 Apr 2022 11:04:15 +0200 Subject: libgo: only add signum to siglist if it doesn't exist yet This fixes a build issue on musl libc where the same signal number is used for SIGIO and SIGPOLL. This causes a compilation error since the signal numbers must be unique for the signal table. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/400595 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index eeff61d..2321f67 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -8336fe4a5da68d9188dfbc4fb647ccbbe4d60ba4 +22b0ccda3aa4d16f770a26a3eb251f8da615c318 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 4a1a72a89c65a6c1d01f717a20440d08c958a6e8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 19 Apr 2022 06:49:22 -0700 Subject: libgo: make a couple of sed uses POSIX compliant Patch from Jonathan Wakely. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/401054 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 2321f67..6323871 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -22b0ccda3aa4d16f770a26a3eb251f8da615c318 +99ca6be406a5781be078ff23f45a72b4c84b16e3 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 6a4e9934545c112eef5eb7248636baa96cbfd2c0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 20 Apr 2022 14:22:41 -0700 Subject: runtime: use correct field name for PPC32 GLIBC registers One of these days we will get this right. Fixes PR go/105315 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/401374 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 6323871..ef20a0a 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -99ca6be406a5781be078ff23f45a72b4c84b16e3 +70ca85f08edf63f46c87d540fa99c45e2903edc2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 374b3c936d62c8b6e7c607fdf6e84a83748e85c7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 May 2022 15:48:23 -0700 Subject: compiler: error for duplicate bool map keys For golang/go#35945 Fixes golang/go#28104 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/403954 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index ef20a0a..4559551 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -70ca85f08edf63f46c87d540fa99c45e2903edc2 +fbadca004b1e09db177c8e071706841038d1dd64 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 1b3b3bf..dce48e0 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -17266,6 +17266,8 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function, Location location = this->location(); Unordered_map(unsigned int, std::vector) st; Unordered_map(unsigned int, std::vector) nt; + bool saw_false = false; + bool saw_true = false; if (this->vals_ != NULL) { if (!this->has_keys_) @@ -17300,6 +17302,7 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function, continue; std::string sval; Numeric_constant nval; + bool bval; if ((*p)->string_constant_value(&sval)) // Check string keys. { unsigned int h = Gogo::hash_string(sval, 0); @@ -17373,6 +17376,19 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function, mit->second.push_back(*p); } } + else if ((*p)->boolean_constant_value(&bval)) + { + if ((bval && saw_true) || (!bval && saw_false)) + { + go_error_at((*p)->location(), + "duplicate key in map literal"); + return Expression::make_error(location); + } + if (bval) + saw_true = true; + else + saw_false = true; + } } } -- cgit v1.1 From fa2d5fc0497b702f37ef18a85535826e910a7307 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 22 Mar 2022 10:51:21 -0700 Subject: compiler: remove Array_index_expression::is_lvalue_ As of CL 77510 it is never true. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/394695 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 13 +++++-------- gcc/go/gofrontend/expressions.h | 16 +--------------- gcc/go/gofrontend/types.cc | 21 +-------------------- gcc/go/gofrontend/types.h | 2 +- 5 files changed, 9 insertions(+), 45 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4559551..3ec315f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -fbadca004b1e09db177c8e071706841038d1dd64 +6a33e7e30c89edc12340dc470b44791bb1066feb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index dce48e0..734ecb9 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7671,8 +7671,7 @@ Expression::comparison(Translate_context* context, Type* result_type, && left_type->array_type()->length() == NULL) { Array_type* at = left_type->array_type(); - bool is_lvalue = false; - left = at->get_value_pointer(context->gogo(), left, is_lvalue); + left = at->get_value_pointer(context->gogo(), left); } else if (left_type->interface_type() != NULL) { @@ -9276,7 +9275,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function, Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type()); Expression* a1 = Expression::make_type_descriptor(element_type, loc); Expression* a2 = Expression::make_temporary_reference(s1tmp, loc); - a2 = slice_type->array_type()->get_value_pointer(gogo, a2, false); + a2 = slice_type->array_type()->get_value_pointer(gogo, a2); a2 = Expression::make_cast(unsafe_ptr_type, a2, loc); Expression* a3 = Expression::make_temporary_reference(l1tmp, loc); Expression* a4 = Expression::make_temporary_reference(c1tmp, loc); @@ -13848,9 +13847,8 @@ Array_index_expression::do_get_backend(Translate_context* context) } else { - Expression* valptr = - array_type->get_value_pointer(gogo, this->array_, - this->is_lvalue_); + Expression* valptr = array_type->get_value_pointer(gogo, + this->array_); Bexpression* ptr = valptr->get_backend(context); ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc); @@ -13891,8 +13889,7 @@ Array_index_expression::do_get_backend(Translate_context* context) Bexpression* offset = gogo->backend()->conditional_expression(bfn, int_btype, cond, zero, start, loc); - Expression* valptr = array_type->get_value_pointer(gogo, this->array_, - this->is_lvalue_); + Expression* valptr = array_type->get_value_pointer(gogo, this->array_); Bexpression* val = valptr->get_backend(context); val = gogo->backend()->pointer_offset_expression(val, offset, loc); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 92e8d8d..707c193 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -3055,7 +3055,7 @@ class Array_index_expression : public Expression Expression* end, Expression* cap, Location location) : Expression(EXPRESSION_ARRAY_INDEX, location), array_(array), start_(start), end_(end), cap_(cap), type_(NULL), - is_lvalue_(false), needs_bounds_check_(true), is_flattened_(false) + needs_bounds_check_(true), is_flattened_(false) { } // Return the array. @@ -3087,18 +3087,6 @@ class Array_index_expression : public Expression end() const { return this->end_; } - // Return whether this array index expression appears in an lvalue - // (left hand side of assignment) context. - bool - is_lvalue() const - { return this->is_lvalue_; } - - // Update this array index expression to indicate that it appears - // in a left-hand-side or lvalue context. - void - set_is_lvalue() - { this->is_lvalue_ = true; } - void set_needs_bounds_check(bool b) { this->needs_bounds_check_ = b; } @@ -3174,8 +3162,6 @@ class Array_index_expression : public Expression Expression* cap_; // The type of the expression. Type* type_; - // Whether expr appears in an lvalue context. - bool is_lvalue_; // Whether bounds check is needed. bool needs_bounds_check_; // Whether this has already been flattened. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 3de0bd3..ef65670 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -7815,7 +7815,7 @@ Array_type::finish_backend_element(Gogo* gogo) // Return an expression for a pointer to the values in ARRAY. Expression* -Array_type::get_value_pointer(Gogo*, Expression* array, bool is_lvalue) const +Array_type::get_value_pointer(Gogo*, Expression* array) const { if (this->length() != NULL) { @@ -7828,25 +7828,6 @@ Array_type::get_value_pointer(Gogo*, Expression* array, bool is_lvalue) const } // Slice. - - if (is_lvalue) - { - Temporary_reference_expression* tref = - array->temporary_reference_expression(); - Var_expression* ve = array->var_expression(); - if (tref != NULL) - { - tref = tref->copy()->temporary_reference_expression(); - tref->set_is_lvalue(); - array = tref; - } - else if (ve != NULL) - { - ve = new Var_expression(ve->named_object(), ve->location()); - array = ve; - } - } - return Expression::make_slice_info(array, Expression::SLICE_INFO_VALUE_POINTER, array->location()); diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index c55345a..6d72e09 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2800,7 +2800,7 @@ class Array_type : public Type // Return an expression for the pointer to the values in an array. Expression* - get_value_pointer(Gogo*, Expression* array, bool is_lvalue) const; + get_value_pointer(Gogo*, Expression* array) const; // Return an expression for the length of an array with this type. Expression* -- cgit v1.1 From dd7813f05df50d2ad8e0dc34503f2dff0b521d89 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 May 2022 19:23:01 -0700 Subject: compiler: always sort interface parse methods The exporter relies on sorting interface parse methods. It would sort them as it encountered interface types. However, when an interface type is an element of a struct or array type, the exporter might encounter that interface type before sorting the parse methods. If it then encountered an identical interface type again, it could get confused about whether the two types are identical or not. Fix the problem by always sorting the parse methods in the finalize_methods pass. Also firm up the export type sorting to make sure we never have this kind of confusion again. Doing this revealed that we need to be more careful about sorting in order to handle aliases correctly. Also fix the interface type hash computation to use the right hash value when looking at parse methods rather than all methods. The test case for this is https://go.dev/cl/405759. Fixes golang/go#52841 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405556 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/export.cc | 315 ++++++++++++++++++++++++++++++++++++++------ gcc/go/gofrontend/types.cc | 15 ++- gcc/go/gofrontend/types.h | 9 -- 4 files changed, 289 insertions(+), 52 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3ec315f..daa725f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6a33e7e30c89edc12340dc470b44791bb1066feb +f5bc28a30b7503015bbef38afb5812313184e822 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index 3d11334..70d3f70 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -360,16 +360,6 @@ Collect_export_references::type(Type* type) if (type->is_abstract()) return TRAVERSE_SKIP_COMPONENTS; - // For interfaces make sure that embedded methods are sorted, since the - // comparison function we use for indexing types relies on it (this call has - // to happen before the record_type call below). - if (type->classification() == Type::TYPE_INTERFACE) - { - Interface_type* it = type->interface_type(); - if (it != NULL) - it->sort_embedded(); - } - if (!this->exp_->record_type(type)) { // We've already seen this type. @@ -501,6 +491,11 @@ should_export(Named_object* no) return true; } +// Compare Typed_identifier_list's. + +static int +compare_til(const Typed_identifier_list*, const Typed_identifier_list*); + // A functor to sort Named_object pointers by name. struct Sort_bindings @@ -514,10 +509,57 @@ struct Sort_bindings return true; if (n2->package() == NULL) return false; - return n1->package()->pkgpath() < n2->package()->pkgpath(); + + // Make sure we don't see the same pkgpath twice. + const std::string& p1(n1->package()->pkgpath()); + const std::string& p2(n2->package()->pkgpath()); + go_assert(p1 != p2); + + return p1 < p2; } - return n1->name() < n2->name(); + if (n1->name() != n2->name()) + return n1->name() < n2->name(); + + // We shouldn't see the same name twice, but it can happen for + // nested type names. + + go_assert(n1->is_type() && n2->is_type()); + + unsigned int ind1; + const Named_object* g1 = n1->type_value()->in_function(&ind1); + unsigned int ind2; + const Named_object* g2 = n2->type_value()->in_function(&ind2); + + if (g1 == NULL) + { + go_assert(g2 != NULL); + return true; + } + else if (g2 == NULL) + return false; + else if (g1 == g2) + { + go_assert(ind1 != ind2); + return ind1 < ind2; + } + else if ((g1->package() != g2->package()) || (g1->name() != g2->name())) + return Sort_bindings()(g1, g2); + else + { + // This case can happen if g1 or g2 is a method. + if (g1 != NULL && g1->func_value()->is_method()) + { + const Typed_identifier* r = g1->func_value()->type()->receiver(); + g1 = r->type()->named_type()->named_object(); + } + if (g2 != NULL && g2->func_value()->is_method()) + { + const Typed_identifier* r = g2->func_value()->type()->receiver(); + g2 = r->type()->named_type()->named_object(); + } + return Sort_bindings()(g1, g2); + } } }; @@ -528,17 +570,20 @@ struct Sort_types bool operator()(const Type* t1, const Type* t2) const { + t1 = t1->forwarded(); + t2 = t2->forwarded(); + const Named_type* nt1 = t1->named_type(); const Named_type* nt2 = t2->named_type(); if (nt1 != NULL) { - if (nt2 != NULL) - { - Sort_bindings sb; - return sb(nt1->named_object(), nt2->named_object()); - } - else - return true; + if (nt2 != NULL) + { + Sort_bindings sb; + return sb(nt1->named_object(), nt2->named_object()); + } + else + return true; } else if (nt2 != NULL) return false; @@ -549,10 +594,218 @@ struct Sort_types gogo->type_descriptor_backend_name(t1, NULL, &b1); Backend_name b2; gogo->type_descriptor_backend_name(t2, NULL, &b2); - return b1.name() < b2.name(); + + std::string n1 = b1.name(); + std::string n2 = b2.name(); + if (n1 != n2) + return n1 < n2; + + // We should never see equal types here. If we do, we may not + // generate an identical output file for identical input. But the + // backend names can be equal because we want to treat aliases + // differently while type_descriptor_backend_name does not. In + // that case we need to traverse the type elements. + + // t1 == t2 in case std::sort compares elements to themselves. + if (t1 == t2) + return false; + + Sort_types sort; + Type_alias_identical identical; + go_assert(!identical(t1, t2)); + + switch (t1->classification()) + { + case Type::TYPE_ERROR: + return false; + + case Type::TYPE_VOID: + case Type::TYPE_BOOLEAN: + case Type::TYPE_INTEGER: + case Type::TYPE_FLOAT: + case Type::TYPE_COMPLEX: + case Type::TYPE_STRING: + case Type::TYPE_SINK: + case Type::TYPE_NIL: + case Type::TYPE_CALL_MULTIPLE_RESULT: + case Type::TYPE_NAMED: + case Type::TYPE_FORWARD: + default: + go_unreachable(); + + case Type::TYPE_FUNCTION: + { + const Function_type* ft1 = t1->function_type(); + const Function_type* ft2 = t2->function_type(); + const Typed_identifier* r1 = ft1->receiver(); + const Typed_identifier* r2 = ft2->receiver(); + if (r1 == NULL) + go_assert(r2 == NULL); + else + { + go_assert(r2 != NULL); + const Type* rt1 = r1->type()->forwarded(); + const Type* rt2 = r2->type()->forwarded(); + if (!identical(rt1, rt2)) + return sort(rt1, rt2); + } + + const Typed_identifier_list* p1 = ft1->parameters(); + const Typed_identifier_list* p2 = ft2->parameters(); + if (p1 == NULL || p1->empty()) + go_assert(p2 == NULL || p2->empty()); + else + { + go_assert(p2 != NULL && !p2->empty()); + int i = compare_til(p1, p2); + if (i < 0) + return false; + else if (i > 0) + return true; + } + + p1 = ft1->results(); + p2 = ft2->results(); + if (p1 == NULL || p1->empty()) + go_assert(p2 == NULL || p2->empty()); + else + { + go_assert(p2 != NULL && !p2->empty()); + int i = compare_til(p1, p2); + if (i < 0) + return false; + else if (i > 0) + return true; + } + + go_unreachable(); + } + + case Type::TYPE_POINTER: + { + const Type* p1 = t1->points_to()->forwarded(); + const Type* p2 = t2->points_to()->forwarded(); + go_assert(!identical(p1, p2)); + return sort(p1, p2); + } + + case Type::TYPE_STRUCT: + { + const Struct_type* s1 = t1->struct_type(); + const Struct_type* s2 = t2->struct_type(); + const Struct_field_list* f1 = s1->fields(); + const Struct_field_list* f2 = s2->fields(); + go_assert(f1 != NULL && f2 != NULL); + Struct_field_list::const_iterator p1 = f1->begin(); + Struct_field_list::const_iterator p2 = f2->begin(); + for (; p2 != f2->end(); ++p1, ++p2) + { + go_assert(p1 != f1->end()); + go_assert(p1->field_name() == p2->field_name()); + go_assert(p1->is_anonymous() == p2->is_anonymous()); + const Type* ft1 = p1->type()->forwarded(); + const Type* ft2 = p2->type()->forwarded(); + if (!identical(ft1, ft2)) + return sort(ft1, ft2); + } + go_assert(p1 == f1->end()); + go_unreachable(); + } + + case Type::TYPE_ARRAY: + { + const Type* e1 = t1->array_type()->element_type()->forwarded(); + const Type* e2 = t2->array_type()->element_type()->forwarded(); + go_assert(!identical(e1, e2)); + return sort(e1, e2); + } + + case Type::TYPE_MAP: + { + const Map_type* m1 = t1->map_type(); + const Map_type* m2 = t2->map_type(); + const Type* k1 = m1->key_type()->forwarded(); + const Type* k2 = m2->key_type()->forwarded(); + if (!identical(k1, k2)) + return sort(k1, k2); + const Type* v1 = m1->val_type()->forwarded(); + const Type* v2 = m2->val_type()->forwarded(); + go_assert(!identical(v1, v2)); + return sort(v1, v2); + } + + case Type::TYPE_CHANNEL: + { + const Type* e1 = t1->channel_type()->element_type()->forwarded(); + const Type* e2 = t2->channel_type()->element_type()->forwarded(); + go_assert(!identical(e1, e2)); + return sort(e1, e2); + } + + case Type::TYPE_INTERFACE: + { + const Interface_type* it1 = t1->interface_type(); + const Interface_type* it2 = t2->interface_type(); + const Typed_identifier_list* m1 = it1->local_methods(); + const Typed_identifier_list* m2 = it2->local_methods(); + + // We know the full method lists are the same, because the + // mangled type names were the same, but here we are looking + // at the local method lists, which include embedded + // interfaces, and we can have an embedded empty interface. + if (m1 == NULL || m1->empty()) + { + go_assert(m2 != NULL && !m2->empty()); + return true; + } + else if (m2 == NULL || m2->empty()) + { + go_assert(m1 != NULL && !m1->empty()); + return false; + } + + int i = compare_til(m1, m2); + if (i < 0) + return false; + else if (i > 0) + return true; + else + go_unreachable(); + } + } } }; +// Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1. + +static int +compare_til( + const Typed_identifier_list* til1, + const Typed_identifier_list* til2) +{ + Type_alias_identical identical; + Sort_types sort; + Typed_identifier_list::const_iterator p1 = til1->begin(); + Typed_identifier_list::const_iterator p2 = til2->begin(); + for (; p2 != til2->end(); ++p1, ++p2) + { + if (p1 == til1->end()) + return -1; + const Type* t1 = p1->type()->forwarded(); + const Type* t2 = p2->type()->forwarded(); + if (!identical(t1, t2)) + { + if (sort(t1, t2)) + return -1; + else + return +1; + } + } + if (p1 != til1->end()) + return +1; + return 0; +} + // Export those identifiers marked for exporting. void @@ -714,17 +967,9 @@ bool Export::record_type(Type* type) { type = type->forwarded(); - std::pair ins = this->impl_->type_refs.insert(std::make_pair(type, 0)); - if (!ins.second) - { - // We've already seen this type. - return false; - } - ins.first->second = 0; - - return true; + return ins.second; } // Assign the specified type an index. @@ -733,13 +978,12 @@ void Export::set_type_index(const Type* type) { type = type->forwarded(); - std::pair ins = - this->impl_->type_refs.insert(std::make_pair(type, 0)); - go_assert(!ins.second); + Type_refs::iterator p = this->impl_->type_refs.find(type); + go_assert(p != this->impl_->type_refs.end()); int index = this->type_index_; ++this->type_index_; - go_assert(ins.first->second == 0); - ins.first->second = index; + go_assert(p->second == 0); + p->second = index; } // This helper assigns type indices to all types mentioned directly or @@ -758,9 +1002,6 @@ Export::assign_type_indices(const std::vector& sorted_exports) { if (!(*p)->is_type()) continue; - Interface_type* it = (*p)->type_value()->interface_type(); - if (it != NULL) - it->sort_embedded(); this->record_type((*p)->type_value()); this->set_type_index((*p)->type_value()); } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index ef65670..a8e3090 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -9031,6 +9031,9 @@ Interface_type::finalize_methods() if (this->parse_methods_ == NULL) return; + // The exporter uses parse_methods_. + this->parse_methods_->sort_by_name(); + this->all_methods_ = new Typed_identifier_list(); this->all_methods_->reserve(this->parse_methods_->size()); Typed_identifier_list inherit; @@ -9318,15 +9321,17 @@ Interface_type::is_compatible_for_assign(const Interface_type* t, // Hash code. unsigned int -Interface_type::do_hash_for_method(Gogo*, int) const +Interface_type::do_hash_for_method(Gogo*, int flags) const { go_assert(this->methods_are_finalized_); + Typed_identifier_list* methods = (((flags & COMPARE_EMBEDDED_INTERFACES) != 0) + ? this->parse_methods_ + : this->all_methods_); unsigned int ret = 0; - if (this->all_methods_ != NULL) + if (methods != NULL) { - for (Typed_identifier_list::const_iterator p = - this->all_methods_->begin(); - p != this->all_methods_->end(); + for (Typed_identifier_list::const_iterator p = methods->begin(); + p != methods->end(); ++p) { ret = Gogo::hash_string(p->name(), ret); diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 6d72e09..49404bd 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -3272,15 +3272,6 @@ class Interface_type : public Type methods_are_finalized() const { return this->methods_are_finalized_; } - // Sort embedded interfaces by name. Needed when we are preparing - // to emit types into the export data. - void - sort_embedded() - { - if (parse_methods_ != NULL) - parse_methods_->sort_by_name(); - } - protected: int do_traverse(Traverse*); -- cgit v1.1 From 1bfb823e2a7346ef55bd53a5354770599f7a550b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 May 2022 17:05:08 -0700 Subject: compiler: load LHS subexpressions of op= assignment only once Fixes golang/go#52811 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405617 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/statements.cc | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index daa725f..5fa8bec 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f5bc28a30b7503015bbef38afb5812313184e822 +9d07072e58ca4f9f05343dfd3475b9f49dae5ec5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 95fa3c4..b3db843 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -1260,6 +1260,16 @@ Assignment_operation_statement::do_lower(Gogo*, Named_object*, Move_ordered_evals moe(b); this->lhs_->traverse_subexpressions(&moe); + // We can still be left with subexpressions that have to be loaded + // even if they don't have side effects themselves, in case the RHS + // changes variables named on the LHS. + int i; + if (this->lhs_->must_eval_subexpressions_in_order(&i)) + { + Move_subexpressions ms(i, b); + this->lhs_->traverse_subexpressions(&ms); + } + Expression* lval = this->lhs_->copy(); Operator op; -- cgit v1.1 From b8944f0438a183a0245ffe17aeaeaf3a1a00069c Mon Sep 17 00:00:00 2001 From: Julia Lapenko Date: Mon, 16 May 2022 10:37:49 +0300 Subject: compiler: traverse expressions when exporting constants When exporting a constant A that is expressed through a constant B from another package, it is necessary to traverse an expression representing the constant A to generate a sequence of type casts from the constant B. Current implementation doesn't collect types of constants contained in such expressions. This change fetches these types. Fixes golang/go#51291 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405976 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/export.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5fa8bec..2cf7141 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -9d07072e58ca4f9f05343dfd3475b9f49dae5ec5 +0058658a9efb6e5c5faa6f0f65949beea5ddbc98 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index 70d3f70..a30b11a 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -124,6 +124,11 @@ class Collect_export_references : public Traverse void prepare_types(const std::vector& sorted_exports); + // Third entry point (called after the method above), to find + // all types in expressions referenced by exports. + void + prepare_expressions(const std::vector& sorted_exports); + protected: // Override of parent class method. int @@ -281,6 +286,28 @@ Collect_export_references::expression(Expression** pexpr) return TRAVERSE_CONTINUE; } +// Collect up the set of types mentioned in expressions of things we're exporting, +// and collect all the packages encountered during type traversal, to make sure +// we can declare things referered to indirectly (for example, in the body of an +// exported inline function from another package). + +void +Collect_export_references::prepare_expressions(const std::vector& sorted_exports) +{ + for (std::vector::const_iterator p = sorted_exports.begin(); + p != sorted_exports.end(); + ++p) + { + Named_object* no = *p; + if (no->classification() == Named_object::NAMED_OBJECT_CONST) + { + Expression* e = no->const_value()->expr(); + if (e != NULL) + Expression::traverse(&e, this); + } + } +} + // Collect up the set of types mentioned in things we're exporting, and collect // all the packages encountered during type traversal, to make sure we can // declare things referered to indirectly (for example, in the body of an @@ -891,6 +918,7 @@ Export::export_globals(const std::string& package_name, // Collect up the set of types mentioned in things we're exporting, // and any packages that may be referred to indirectly. collect.prepare_types(sorted_exports); + collect.prepare_expressions(sorted_exports); // Assign indexes to all exported types and types referenced by // things we're exporting. Return value is index of first non-exported -- cgit v1.1 From a8b5d63503b8cf49de32d241218057409f8731ac Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 27 May 2022 12:15:36 -0400 Subject: build: TAGS and .cc transition A few globs missed in the .c -> .cc transition. Some targets were looking at both *.c and *.cc, but there are no longer any .c files to scan. gcc/ChangeLog: * Makefile.in (TAGS): Look at libcpp/*.cc. gcc/c/ChangeLog: * Make-lang.in (c.tags): Look at *.cc. gcc/cp/ChangeLog: * Make-lang.in (c++.tags): Just look at *.cc. gcc/d/ChangeLog: * Make-lang.in (d.tags): Just look at *.cc. gcc/fortran/ChangeLog: * Make-lang.in (fortran.tags): Look at *.cc. gcc/go/ChangeLog: * Make-lang.in (go.tags): Look at *.cc. gcc/objc/ChangeLog: * Make-lang.in (objc.tags): Look at *.cc. gcc/objcp/ChangeLog: * Make-lang.in (obj-c++.tags): Look at *.cc. --- gcc/go/Make-lang.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in index 31c6773..0e81268 100644 --- a/gcc/go/Make-lang.in +++ b/gcc/go/Make-lang.in @@ -133,7 +133,7 @@ go.srcinfo: doc/gccgo.info go.srcextra: go.tags: force cd $(srcdir)/go; \ - $(ETAGS) -o TAGS.sub *.c *.h gofrontend/*.h gofrontend/*.cc; \ + $(ETAGS) -o TAGS.sub *.cc *.h gofrontend/*.h gofrontend/*.cc; \ $(ETAGS) --include TAGS.sub --include ../TAGS.sub go.man: doc/gccgo.1 go.srcman: doc/gccgo.1 -- cgit v1.1 From 820ead4519c266c83b4e3d11484a66d6691bc441 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 1 Jun 2022 00:16:34 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index f50a60b7..ee08e1c 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2022-05-31 Jason Merrill + + * Make-lang.in (go.tags): Look at *.cc. + 2022-02-13 Ian Lance Taylor * gospec.cc: Revert 2022-02-09 change: -- cgit v1.1 From 6cf276ddf22066af780335cd0072d2c27aabe468 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 2 Jun 2022 15:40:22 -0400 Subject: diagnostics: add SARIF output format This patch adds support to gcc's diagnostic subsystem for emitting diagnostics in SARIF, aka the Static Analysis Results Interchange Format: https://sarifweb.azurewebsites.net/ by extending -fdiagnostics-format= to add two new options: -fdiagnostics-format=sarif-stderr and: -fdiagnostics-format=sarif-file The patch targets SARIF v2.1.0 This is a JSON-based format suited for capturing the results of static analysis tools (like GCC's -fanalyzer), but it can also be used for plain GCC warnings and errors. SARIF supports per-event metadata in diagnostic paths such as ["acquire", "resource"] and ["release", "lock"] (specifically, the threadFlowLocation "kinds" property: SARIF v2.1.0 section 3.38.8), so the patch extends GCC"s diagnostic_event subclass with a "struct meaning" with similar purpose. The patch implements this for -fanalyzer so that the various state-machine-based warnings set these in the SARIF output. The heart of the implementation is in the new file diagnostic-format-sarif.cc. Much of the rest of the patch is interface classes, isolating the diagnostic subsystem (which has no knowledge of e.g. tree or langhook) from the "client" code in the compiler proper cc1 etc). The patch adds a langhook for specifying the SARIF v2.1.0 "artifact.sourceLanguage" property, based on the list in SARIF v2.1.0 Appendix J. The patch adds automated DejaGnu tests to our testsuite via new scan-sarif-file and scan-sarif-file-not directives (although these merely use regexps, rather than attempting to use a proper JSON parser). I've tested the patch by hand using the validator at: https://sarifweb.azurewebsites.net/Validation and the react-based viewer at: https://microsoft.github.io/sarif-web-component/ which successfully shows most of the information (although not paths, and not CWE IDs), and I've fixed all validation errors I've seen (though bugs no doubt remain). I've also tested the generated SARIF using the VS Code extension linked to from the SARIF website; I'm a novice with VS Code, but it seems to be able to handle my generated SARIF files (e.g. showing the data in the SARIF tab, and showing squiggly underlines under issues, and when I click on them, it visualizes the events in the path inline within the source window). Has anyone written an Emacs mode for SARIF files? (pretty please) gcc/ChangeLog: * Makefile.in (OBJS): Add tree-diagnostic-client-data-hooks.o and tree-logical-location.o. (OBJS-libcommon): Add diagnostic-format-sarif.o; reorder. (CFLAGS-tree-diagnostic-client-data-hooks.o): Add TARGET_NAME. * common.opt (fdiagnostics-format=): Add sarif-stderr and sarif-file. (sarif-stderr, sarif-file): New enum values. * diagnostic-client-data-hooks.h: New file. * diagnostic-format-sarif.cc: New file. * diagnostic-path.h (enum diagnostic_event::verb): New enum. (enum diagnostic_event::noun): New enum. (enum diagnostic_event::property): New enum. (struct diagnostic_event::meaning): New struct. (diagnostic_event::get_logical_location): New vfunc. (diagnostic_event::get_meaning): New vfunc. (simple_diagnostic_event::get_logical_location): New vfunc impl. (simple_diagnostic_event::get_meaning): New vfunc impl. * diagnostic.cc: Include "diagnostic-client-data-hooks.h". (diagnostic_initialize): Initialize m_client_data_hooks. (diagnostic_finish): Clean up m_client_data_hooks. (diagnostic_event::meaning::dump_to_pp): New. (diagnostic_event::meaning::maybe_get_verb_str): New. (diagnostic_event::meaning::maybe_get_noun_str): New. (diagnostic_event::meaning::maybe_get_property_str): New. (get_cwe_url): Make non-static. (diagnostic_output_format_init): Handle DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR and DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE. * diagnostic.h (enum diagnostics_output_format): Add DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR and DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE. (class diagnostic_client_data_hooks): New forward decl. (class logical_location): New forward decl. (diagnostic_context::m_client_data_hooks): New field. (diagnostic_output_format_init_sarif_stderr): New decl. (diagnostic_output_format_init_sarif_file): New decl. (get_cwe_url): New decl. * doc/invoke.texi (-fdiagnostics-format=): Add sarif-stderr and sarif-file. * doc/sourcebuild.texi (Scan a particular file): Add scan-sarif-file and scan-sarif-file-not. * langhooks-def.h (lhd_get_sarif_source_language): New decl. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): New macro. (LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE. * langhooks.cc (lhd_get_sarif_source_language): New. * langhooks.h (lang_hooks::get_sarif_source_language): New field. * logical-location.h: New file. * plugin.cc (struct for_each_plugin_closure): New. (for_each_plugin_cb): New. (for_each_plugin): New. * plugin.h (for_each_plugin): New decl. * tree-diagnostic-client-data-hooks.cc: New file. * tree-diagnostic.cc: Include "diagnostic-client-data-hooks.h". (tree_diagnostics_defaults): Populate m_client_data_hooks. * tree-logical-location.cc: New file. * tree-logical-location.h: New file. gcc/ada/ChangeLog: * gcc-interface/misc.cc (gnat_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/analyzer/ChangeLog: * checker-path.cc (checker_event::get_meaning): New. (function_entry_event::get_meaning): New. (state_change_event::get_desc): Add dump of meaning of the event to the -fanalyzer-verbose-state-changes output. (state_change_event::get_meaning): New. (cfg_edge_event::get_meaning): New. (call_event::get_meaning): New. (return_event::get_meaning): New. (start_consolidated_cfg_edges_event::get_meaning): New. (warning_event::get_meaning): New. * checker-path.h: Include "tree-logical-location.h". (checker_event::checker_event): Construct m_logical_loc. (checker_event::get_logical_location): New. (checker_event::get_meaning): New decl. (checker_event::m_logical_loc): New. (function_entry_event::get_meaning): New decl. (state_change_event::get_meaning): New decl. (cfg_edge_event::get_meaning): New decl. (call_event::get_meaning): New decl. (return_event::get_meaning): New decl. (start_consolidated_cfg_edges_event::get_meaning): New. (warning_event::get_meaning): New decl. * pending-diagnostic.h: Include "diagnostic-path.h". (pending_diagnostic::get_meaning_for_state_change): New vfunc. * sm-file.cc (file_diagnostic::get_meaning_for_state_change): New vfunc impl. * sm-malloc.cc (malloc_diagnostic::get_meaning_for_state_change): Likewise. * sm-sensitive.cc (exposure_through_output_file::get_meaning_for_state_change): Likewise. * sm-taint.cc (taint_diagnostic::get_meaning_for_state_change): Likewise. * varargs.cc (va_list_sm_diagnostic::get_meaning_for_state_change): Likewise. gcc/c/ChangeLog: * c-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (c_get_sarif_source_language): New. * c-tree.h (c_get_sarif_source_language): New decl. gcc/cp/ChangeLog: * cp-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (cp_get_sarif_source_language): New. gcc/d/ChangeLog: * d-lang.cc (d_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/fortran/ChangeLog: * f95-lang.cc (gfc_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/go/ChangeLog: * go-lang.cc (go_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/objc/ChangeLog: * objc-act.h (objc_get_sarif_source_language): New decl. * objc-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (objc_get_sarif_source_language): New. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-1.c: New test. * c-c++-common/diagnostic-format-sarif-file-2.c: New test. * c-c++-common/diagnostic-format-sarif-file-3.c: New test. * c-c++-common/diagnostic-format-sarif-file-4.c: New test. * gcc.dg/analyzer/file-meaning-1.c: New test. * gcc.dg/analyzer/malloc-meaning-1.c: New test. * gcc.dg/analyzer/malloc-sarif-1.c: New test. * gcc.dg/plugin/analyzer_gil_plugin.c (gil_diagnostic::get_meaning_for_state_change): New vfunc impl. * gcc.dg/plugin/diagnostic-test-paths-5.c: New test. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic-test-paths-5.c to tests for diagnostic_plugin_test_paths.c. * lib/gcc-dg.exp: Load scansarif.exp. * lib/scansarif.exp: New test. libatomic/ChangeLog: * testsuite/lib/libatomic.exp: Add load_gcc_lib of scansarif.exp. libgomp/ChangeLog: * testsuite/lib/libgomp.exp: Add load_gcc_lib of scansarif.exp. libitm/ChangeLog: * testsuite/lib/libitm.exp: Add load_gcc_lib of scansarif.exp. libphobos/ChangeLog: * testsuite/lib/libphobos-dg.exp: Add load_gcc_lib of scansarif.exp. Signed-off-by: David Malcolm --- gcc/go/go-lang.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc index c8365d2..84cd623 100644 --- a/gcc/go/go-lang.cc +++ b/gcc/go/go-lang.cc @@ -545,6 +545,15 @@ go_langhook_eh_personality (void) return personality_decl; } +/* Get a value for the SARIF v2.1.0 "artifact.sourceLanguage" property, + based on the list in SARIF v2.1.0 Appendix J. */ + +static const char * +go_get_sarif_source_language (const char *) +{ + return "go"; +} + /* Functions called directly by the generic backend. */ tree @@ -615,6 +624,7 @@ go_localize_identifier (const char *ident) #undef LANG_HOOKS_GETDECLS #undef LANG_HOOKS_GIMPLIFY_EXPR #undef LANG_HOOKS_EH_PERSONALITY +#undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE #define LANG_HOOKS_NAME "GNU Go" #define LANG_HOOKS_INIT go_langhook_init @@ -631,6 +641,7 @@ go_localize_identifier (const char *ident) #define LANG_HOOKS_GETDECLS go_langhook_getdecls #define LANG_HOOKS_GIMPLIFY_EXPR go_langhook_gimplify_expr #define LANG_HOOKS_EH_PERSONALITY go_langhook_eh_personality +#define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE go_get_sarif_source_language struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; -- cgit v1.1 From b168441c8a6b7cb6b6623694eb9e1cc87a3d51af Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 3 Jun 2022 00:16:40 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index ee08e1c..5fdf423 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2022-06-02 David Malcolm + + * go-lang.cc (go_get_sarif_source_language): New. + (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. + 2022-05-31 Jason Merrill * Make-lang.in (go.tags): Look at *.cc. -- cgit v1.1 From cf79b1117bd177d3d4c6ed24b6fa243c3628ac2d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 13 Jun 2022 21:32:25 -0700 Subject: syscall: gofmt Add blank lines after //sys comments where needed, and then run gofmt on the syscall package with the new formatter. This is the libgo version of CL 407136. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/412074 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 2cf7141..aeada9f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -0058658a9efb6e5c5faa6f0f65949beea5ddbc98 +bbb3a4347714faee620dc205674510a0f20b81ae The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From b2aaa44d2c9c0e5a31688a6e40a7b132dd03338a Mon Sep 17 00:00:00 2001 From: Mikhail Ablakatov Date: Thu, 12 May 2022 21:45:35 +0300 Subject: compiler: don't generate stubs for ambiguous direct interface methods Current implementation checks whether it has to generate a stub method for a promoted method of an embedded struct field in Type::build_stub_methods(). If the promoted method is ambiguous it's simply skipped. But struct types that can fit in an interface value (e.g. structs that consist of a single pointer field) get a second chance in Type::build_direct_iface_stub_methods(). This patch adds the same check used by Type::build_stub_methods() to Type::build_direct_iface_stub_methods(). Fixes golang/go#52870 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405974 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/types.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index aeada9f..0cda305 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -bbb3a4347714faee620dc205674510a0f20b81ae +8db6b78110f84e22c409f334aeaefb80a8b39917 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index a8e3090..eb3afd9 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -11891,7 +11891,7 @@ Type::build_direct_iface_stub_methods(Gogo* gogo, const Type* type, need_stub = true; if (!in_heap && !m->is_value_method()) need_stub = true; - if (!need_stub) + if (!need_stub || m->is_ambiguous()) continue; Type* receiver_type = const_cast(type); -- cgit v1.1 From 7f195a2270910a6ed08bd76e3a16b0a6503f9faf Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 14 Jun 2022 11:33:42 -0700 Subject: libgo: permit loff_t and off_t to be macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are macros in musl libc, rather than typedefs, and -fgo-dump-spec doesn't handle that case. Based on patch by Sören Tempel. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/412075 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0cda305..4b75dd3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -8db6b78110f84e22c409f334aeaefb80a8b39917 +a409e049737ec9a358a19233e017d957db3d6d2a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 7905a9ac26707ed6ac49e40e35a9c8755c6574e3 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 18 Jun 2022 18:19:28 -0700 Subject: libgo: #include when checking for loff_t PR go/106033 Fixes golang/go#53469 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/413214 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4b75dd3..737bc48 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a409e049737ec9a358a19233e017d957db3d6d2a +77821de1a149c2e6ef9c154ae384c16292173039 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 038a7150ec07770174907b93bc93caaa1e019f92 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 22 Jun 2022 16:40:24 -0700 Subject: compiler: unalias types for hash/equality functions Test case is https://go.dev/cl/413694. Fixes golang/go#52846 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/413660 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 2 +- gcc/go/gofrontend/types.cc | 17 ++++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 737bc48..629bc66 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -77821de1a149c2e6ef9c154ae384c16292173039 +6c3752315dc9b82d0f3f3ac646a1e7376818f84a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index d35c6ba..e13df0d 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -2811,7 +2811,7 @@ Specific_type_functions::type(Type* t) case Type::TYPE_MAP: { - Type* key_type = t->map_type()->key_type(); + Type* key_type = t->map_type()->key_type()->unalias(); if (key_type->needs_specific_type_functions(this->gogo_)) key_type->hash_function(this->gogo_, NULL); } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index eb3afd9..39aea76 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1764,6 +1764,9 @@ Type::needs_specific_type_functions(Gogo* gogo) Named_object* Type::hash_function(Gogo* gogo, Function_type* hash_fntype) { + if (this->named_type() != NULL) + go_assert(!this->named_type()->is_alias()); + if (!this->is_comparable()) return NULL; @@ -2067,6 +2070,9 @@ Type::write_identity_hash(Gogo* gogo, int64_t size) Named_object* Type::equal_function(Gogo* gogo, Named_type* name, Function_type* equal_fntype) { + if (this->named_type() != NULL) + go_assert(!this->named_type()->is_alias()); + // If the unaliased type is not a named type, then the type does not // have a name after all. if (name != NULL) @@ -6700,7 +6706,8 @@ Struct_type::write_hash_function(Gogo* gogo, Function_type* hash_fntype) subkey = Expression::make_cast(key_arg_type, subkey, bloc); // Get the hash function to use for the type of this field. - Named_object* hash_fn = pf->type()->hash_function(gogo, hash_fntype); + Named_object* hash_fn = + pf->type()->unalias()->hash_function(gogo, hash_fntype); // Call the hash function for the field, passing retval as the seed. ref = Expression::make_temporary_reference(retval, bloc); @@ -7553,8 +7560,8 @@ Array_type::write_hash_function(Gogo* gogo, Function_type* hash_fntype) gogo->start_block(bloc); // Get the hash function for the element type. - Named_object* hash_fn = this->element_type_->hash_function(gogo, - hash_fntype); + Named_object* hash_fn = + this->element_type_->unalias()->hash_function(gogo, hash_fntype); // Get a pointer to this element in the loop. Expression* subkey = Expression::make_temporary_reference(key, bloc); @@ -8441,8 +8448,8 @@ Map_type::do_type_descriptor(Gogo* gogo, Named_type* name) ++p; go_assert(p->is_field_name("hasher")); Function_type* hasher_fntype = p->type()->function_type(); - Named_object* hasher_fn = this->key_type_->hash_function(gogo, - hasher_fntype); + Named_object* hasher_fn = + this->key_type_->unalias()->hash_function(gogo, hasher_fntype); if (hasher_fn == NULL) vals->push_back(Expression::make_cast(hasher_fntype, Expression::make_nil(bloc), -- cgit v1.1 From 5ee8e1d1b0c0d9f6310d27a37a6162e0be80e413 Mon Sep 17 00:00:00 2001 From: zhangjian Date: Tue, 21 Jun 2022 16:08:47 +0000 Subject: compiler: in Sort_bindings return false if comparing value to itself Some versions of std::sort may pass elements at the same iterator location. Fixes golang/go#53483 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/413434 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/export.cc | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 629bc66..f882812 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6c3752315dc9b82d0f3f3ac646a1e7376818f84a +6b314f7947b4b31a86c09d166fe6664cd9968824 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index a30b11a..7373dee 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -530,6 +530,9 @@ struct Sort_bindings bool operator()(const Named_object* n1, const Named_object* n2) const { + if (n1 == n2) + return false; + if (n1->package() != n2->package()) { if (n1->package() == NULL) -- cgit v1.1 From bb403de36aa29e5398119e78a2c96794bdd6bad8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 23 Jun 2022 17:11:05 -0700 Subject: compiler: use bool for comma-ok if not already boolean If a comma-ok variable already has a type, and that type is not a boolean type, then set the type of the temporary variable to bool. Otherwise we may try to convert an unnamed bool type to an interface type, which will fail. But we don't want to always use bool, because the type of the comma-ok variable may be a named bool type, in which case the assignment would fail (or need an explicit conversion). The test case is https://go.dev/cl/404496. Fixes golang/go#52535 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/413894 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/statements.cc | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f882812..e20212e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6b314f7947b4b31a86c09d166fe6664cd9968824 +6a7ba754e5d98efe0875f1f41f40098e976e7958 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index b3db843..b442830 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -1594,9 +1594,9 @@ Tuple_map_assignment_statement::do_lower(Gogo* gogo, Named_object*, // var present_temp bool Temporary_statement* present_temp = - Statement::make_temporary((this->present_->type()->is_sink_type()) - ? Type::make_boolean_type() - : this->present_->type(), + Statement::make_temporary((this->present_->type()->is_boolean_type() + ? this->present_->type() + : Type::lookup_bool_type()), NULL, loc); b->add_statement(present_temp); @@ -1789,9 +1789,9 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, // var closed_temp bool Temporary_statement* closed_temp = - Statement::make_temporary((this->closed_->type()->is_sink_type()) - ? Type::make_boolean_type() - : this->closed_->type(), + Statement::make_temporary((this->closed_->type()->is_boolean_type() + ? this->closed_->type() + : Type::lookup_bool_type()), NULL, loc); b->add_statement(closed_temp); @@ -1965,6 +1965,8 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*, b->add_statement(s); res = Expression::make_call_result(call, 1); + if (!this->ok_->type()->is_boolean_type()) + res = Expression::make_cast(Type::lookup_bool_type(), res, loc); s = Statement::make_assignment(this->ok_, res, loc); b->add_statement(s); } @@ -2001,7 +2003,9 @@ Tuple_type_guard_assignment_statement::lower_to_object_type( Temporary_statement* ok_temp = NULL; if (!this->ok_->is_sink_expression()) { - ok_temp = Statement::make_temporary(this->ok_->type(), + ok_temp = Statement::make_temporary((this->ok_->type()->is_boolean_type() + ? this->ok_->type() + : Type::lookup_bool_type()), NULL, loc); b->add_statement(ok_temp); } -- cgit v1.1 From 722750a44a93ce7d23e09df240d8ab700a2d30e6 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 24 Jun 2022 17:18:15 -0700 Subject: compiler: always initialize mpfr in integer import Test case is https://go.dev/cl/413980. Fixes golang/go#52862 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/413981 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e20212e..f84347e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6a7ba754e5d98efe0875f1f41f40098e976e7958 +6edae0ef6521569e8f949aaaafa9dc1139825051 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 734ecb9..135dae02 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -2715,7 +2715,7 @@ Integer_expression::do_import(Import_expression* imp, Location loc) return Expression::make_error(loc); } if (pos == std::string::npos) - mpfr_set_ui(real, 0, MPFR_RNDN); + mpfr_init_set_ui(real, 0, MPFR_RNDN); else { std::string real_str = num.substr(0, pos); -- cgit v1.1 From 5f6b6494035fb984d745efa28d334f7893e7272b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 26 Jun 2022 21:52:35 -0700 Subject: compiler: don't use sink as parameter in method expression thunk Also fix a couple of cases where the error led to a later compiler crash. Test case is https://go.dev/cl/414336. Fixes golang/go#52871 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/414354 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 9 +++++++-- gcc/go/gofrontend/types.cc | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f84347e..16d274c 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6edae0ef6521569e8f949aaaafa9dc1139825051 +927528cdc112fc51e0d07ee79e7a1254b586eabe The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 135dae02..f59f61d 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1426,7 +1426,12 @@ Sink_expression::do_get_backend(Translate_context* context) Gogo* gogo = context->gogo(); if (this->bvar_ == NULL) { - go_assert(this->type_ != NULL && !this->type_->is_sink_type()); + if (this->type_ == NULL || this->type_->is_sink_type()) + { + go_assert(saw_errors()); + return gogo->backend()->error_expression(); + } + Named_object* fn = context->function(); go_assert(fn != NULL); Bfunction* fn_ctx = fn->func_value()->get_or_make_decl(gogo, fn); @@ -15235,7 +15240,7 @@ Selector_expression::lower_method_expression(Gogo* gogo) p != method_parameters->end(); ++p, ++i) { - if (!p->name().empty()) + if (!p->name().empty() && !Gogo::is_sink_name(p->name())) parameters->push_back(*p); else { diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 39aea76..e82be68 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -4654,8 +4654,11 @@ class Sink_type : public Type { return false; } Btype* - do_get_backend(Gogo*) - { go_unreachable(); } + do_get_backend(Gogo* gogo) + { + go_assert(saw_errors()); + return gogo->backend()->error_type(); + } Expression* do_type_descriptor(Gogo*, Named_type*) -- cgit v1.1 From ed06274eacc17a224b87f23111d7ca874ea53b7c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 27 Jun 2022 22:17:51 -0700 Subject: compiler: permit expressions of abstract bool to remain abstract Test case is https://go.dev/cl/414755. Fixes golang/go#51475 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/414735 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 16d274c..a0e386a 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -927528cdc112fc51e0d07ee79e7a1254b586eabe +28fe9fad4acb4e02083faf5503b06e3e6e8eecaf The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index f59f61d..aadca97 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6829,11 +6829,12 @@ Binary_expression::do_determine_type(const Type_context* context) { if ((tleft->integer_type() != NULL && tright->integer_type() != NULL) || (tleft->float_type() != NULL && tright->float_type() != NULL) - || (tleft->complex_type() != NULL && tright->complex_type() != NULL)) + || (tleft->complex_type() != NULL && tright->complex_type() != NULL) + || (tleft->is_boolean_type() && tright->is_boolean_type())) { - // Both sides have an abstract integer, abstract float, or - // abstract complex type. Just let CONTEXT determine - // whether they may remain abstract or not. + // Both sides have an abstract integer, abstract float, + // abstract complex, or abstract boolean type. Just let + // CONTEXT determine whether they may remain abstract or not. } else if (tleft->complex_type() != NULL) subcontext.type = tleft; -- cgit v1.1 From 53c4ef1e3cc103ce5bdf1d9923144e93b523102a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 27 Jun 2022 17:22:53 -0700 Subject: libgo: make runtime.Version return a meaningful string Fixes golang/go#51850 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/414734 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index a0e386a..551ea65 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -28fe9fad4acb4e02083faf5503b06e3e6e8eecaf +d5b4abed2f206e492890acc20738e89617ea542c The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 74956337e8276e5bc9524104b01c147374dd94e7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 25 Jun 2022 22:09:16 -0700 Subject: compiler: use package path with embedded builtin type The test case is https://go.dev/cl/414235. Fixes golang/go#52856 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/414294 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/names.cc | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 551ea65..13cb6ea 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -d5b4abed2f206e492890acc20738e89617ea542c +c7238f58a26131b7611eff6f555cab02af8a623c The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc index f85d84c..dac7f20 100644 --- a/gcc/go/gofrontend/names.cc +++ b/gcc/go/gofrontend/names.cc @@ -831,15 +831,28 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret, ret->push_back(' '); } - // For an anonymous field with an alias type, the field name - // is the alias name. - if (p->is_anonymous() - && p->type()->named_type() != NULL - && p->type()->named_type()->is_alias()) - p->type()->named_type()->append_symbol_type_name(gogo, true, ret, - is_non_identifier); + const Type* ft = p->type(); + const Named_type* nt = ft->named_type(); + + if (p->is_anonymous() && nt != NULL && nt->is_builtin()) + { + // For an embedded field with a builtin type, we must + // include a package path. Otherwise embedding builtin + // types in different packages will produce identical + // types, which shouldn't happen because the builtin + // types are not exported. + ret->append(gogo->pkgpath()); + ret->push_back('.'); + nt->append_symbol_type_name(gogo, true, ret, is_non_identifier); + } + else if (p->is_anonymous() && nt != NULL && nt->is_alias()) + { + // For an anonymous field with an alias type, the field name + // is the alias name. + nt->append_symbol_type_name(gogo, true, ret, is_non_identifier); + } else - this->append_mangled_name(p->type(), gogo, ret, is_non_identifier); + this->append_mangled_name(ft, gogo, ret, is_non_identifier); if (p->has_tag()) { -- cgit v1.1 From 3183acc8e0452fbc0ad429a909811ca0308c86c9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 28 Jun 2022 17:03:28 -0700 Subject: compiler: check repeated const expressions in new scope Test case is const8.go in https://go.dev/cl/414795. Fixes golang/go#53585 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/414914 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 110 +++++++-------------------------------- gcc/go/gofrontend/expressions.h | 105 +++++++++++++++++++++++++++++++++++++ gcc/go/gofrontend/parse.cc | 89 +++++++++++++++++++++++++++++++ gcc/go/gofrontend/parse.h | 1 + 5 files changed, 215 insertions(+), 92 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 13cb6ea..4fde25a 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -c7238f58a26131b7611eff6f555cab02af8a623c +63782f8a318e9eebfdc983f171a920c7a937c759 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index aadca97..00d35a9 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3352,97 +3352,7 @@ class Find_named_object : public Traverse bool found_; }; -// A reference to a const in an expression. - -class Const_expression : public Expression -{ - public: - Const_expression(Named_object* constant, Location location) - : Expression(EXPRESSION_CONST_REFERENCE, location), - constant_(constant), type_(NULL), seen_(false) - { } - - Named_object* - named_object() - { return this->constant_; } - - const Named_object* - named_object() const - { return this->constant_; } - - // Check that the initializer does not refer to the constant itself. - void - check_for_init_loop(); - - protected: - int - do_traverse(Traverse*); - - Expression* - do_lower(Gogo*, Named_object*, Statement_inserter*, int); - - bool - do_is_constant() const - { return true; } - - bool - do_is_zero_value() const - { return this->constant_->const_value()->expr()->is_zero_value(); } - - bool - do_is_static_initializer() const - { return true; } - - bool - do_numeric_constant_value(Numeric_constant* nc) const; - - bool - do_string_constant_value(std::string* val) const; - - bool - do_boolean_constant_value(bool* val) const; - - Type* - do_type(); - - // The type of a const is set by the declaration, not the use. - void - do_determine_type(const Type_context*); - - void - do_check_types(Gogo*); - - Expression* - do_copy() - { return this; } - - Bexpression* - do_get_backend(Translate_context* context); - - int - do_inlining_cost() const - { return 1; } - - // When exporting a reference to a const as part of a const - // expression, we export the value. We ignore the fact that it has - // a name. - void - do_export(Export_function_body* efb) const - { this->constant_->const_value()->expr()->export_expression(efb); } - - void - do_dump_expression(Ast_dump_context*) const; - - private: - // The constant. - Named_object* constant_; - // The type of this reference. This is used if the constant has an - // abstract type. - Type* type_; - // Used to prevent infinite recursion when a constant incorrectly - // refers to itself. - mutable bool seen_; -}; +// Class Const_expression. // Traversal. @@ -3454,6 +3364,14 @@ Const_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +// Whether this is the zero value. + +bool +Const_expression::do_is_zero_value() const +{ + return this->constant_->const_value()->expr()->is_zero_value(); +} + // Lower a constant expression. This is where we convert the // predeclared constant iota into an integer value. @@ -3708,6 +3626,16 @@ Const_expression::do_get_backend(Translate_context* context) return expr->get_backend(context); } +// When exporting a reference to a const as part of a const +// expression, we export the value. We ignore the fact that it has +// a name. + +void +Const_expression::do_export(Export_function_body* efb) const +{ + this->constant_->const_value()->expr()->export_expression(efb); +} + // Dump ast representation for constant expression. void diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 707c193..a1e3733 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -28,6 +28,7 @@ class Map_type; class Struct_type; class Struct_field; class Expression_list; +class Const_expression; class Var_expression; class Enclosed_var_expression; class Temporary_reference_expression; @@ -626,6 +627,20 @@ class Expression is_type_expression() const { return this->classification_ == EXPRESSION_TYPE; } + // If this is a const reference, return the Const_expression + // structure. Otherwise, return NULL. This is a controlled dynamic + // cast. + Const_expression* + const_expression() + { return this->convert(); } + + const Const_expression* + const_expression() const + { + return this->convert(); + } + // If this is a variable reference, return the Var_expression // structure. Otherwise, return NULL. This is a controlled dynamic // cast. @@ -1453,6 +1468,96 @@ class Parser_expression : public Expression { go_unreachable(); } }; +// A reference to a const in an expression. + +class Const_expression : public Expression +{ + public: + Const_expression(Named_object* constant, Location location) + : Expression(EXPRESSION_CONST_REFERENCE, location), + constant_(constant), type_(NULL), seen_(false) + { } + + Named_object* + named_object() + { return this->constant_; } + + const Named_object* + named_object() const + { return this->constant_; } + + // Check that the initializer does not refer to the constant itself. + void + check_for_init_loop(); + + protected: + int + do_traverse(Traverse*); + + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + + bool + do_is_constant() const + { return true; } + + bool + do_is_zero_value() const; + + bool + do_is_static_initializer() const + { return true; } + + bool + do_numeric_constant_value(Numeric_constant* nc) const; + + bool + do_string_constant_value(std::string* val) const; + + bool + do_boolean_constant_value(bool* val) const; + + Type* + do_type(); + + // The type of a const is set by the declaration, not the use. + void + do_determine_type(const Type_context*); + + void + do_check_types(Gogo*); + + Expression* + do_copy() + { return this; } + + Bexpression* + do_get_backend(Translate_context* context); + + int + do_inlining_cost() const + { return 1; } + + // When exporting a reference to a const as part of a const + // expression, we export the value. We ignore the fact that it has + // a name. + void + do_export(Export_function_body* efb) const; + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The constant. + Named_object* constant_; + // The type of this reference. This is used if the constant has an + // abstract type. + Type* type_; + // Used to prevent infinite recursion when a constant incorrectly + // refers to itself. + mutable bool seen_; +}; + // An expression which is simply a variable. class Var_expression : public Expression diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index cc197e5..e388261 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -1468,6 +1468,7 @@ Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list) { Expression* copy = (*p)->copy(); copy->set_location(loc); + this->update_references(©); expr_list->push_back(copy); } } @@ -1513,6 +1514,94 @@ Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list) return; } +// Update any references to names to refer to the current names, +// for weird cases like +// +// const X = 1 +// func F() { +// const ( +// X = X + X +// Y +// ) +// } +// +// where the X + X for the first X is the outer X, but the X + X +// copied for Y is the inner X. + +class Update_references : public Traverse +{ + public: + Update_references(Gogo* gogo) + : Traverse(traverse_expressions), + gogo_(gogo) + { } + + int + expression(Expression**); + + private: + Gogo* gogo_; +}; + +int +Update_references::expression(Expression** pexpr) +{ + Named_object* old_no; + switch ((*pexpr)->classification()) + { + case Expression::EXPRESSION_CONST_REFERENCE: + old_no = (*pexpr)->const_expression()->named_object(); + break; + case Expression::EXPRESSION_VAR_REFERENCE: + old_no = (*pexpr)->var_expression()->named_object(); + break; + case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE: + old_no = (*pexpr)->enclosed_var_expression()->variable(); + break; + case Expression::EXPRESSION_FUNC_REFERENCE: + old_no = (*pexpr)->func_expression()->named_object(); + break; + case Expression::EXPRESSION_UNKNOWN_REFERENCE: + old_no = (*pexpr)->unknown_expression()->named_object(); + break; + default: + return TRAVERSE_CONTINUE; + } + + if (old_no->package() != NULL) + { + // This is a qualified reference, so it can't have changed in + // scope. FIXME: This probably doesn't handle dot imports + // correctly. + return TRAVERSE_CONTINUE; + } + + Named_object* in_function; + Named_object* new_no = this->gogo_->lookup(old_no->name(), &in_function); + if (new_no == old_no) + return TRAVERSE_CONTINUE; + + // The new name must be a constant, since that is all we have + // introduced into scope. + if (!new_no->is_const()) + { + go_assert(saw_errors()); + return TRAVERSE_CONTINUE; + } + + *pexpr = Expression::make_const_reference(new_no, (*pexpr)->location()); + + return TRAVERSE_CONTINUE; +} + +void +Parse::update_references(Expression** pexpr) +{ + Update_references ur(this->gogo_); + ur.expression(pexpr); + (*pexpr)->traverse_subexpressions(&ur); +} + // TypeDecl = "type" Decl . void diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h index 6e300ef..cda0bee 100644 --- a/gcc/go/gofrontend/parse.h +++ b/gcc/go/gofrontend/parse.h @@ -185,6 +185,7 @@ class Parse void list(void (Parse::*)(), bool); void const_decl(); void const_spec(int, Type**, Expression_list**); + void update_references(Expression**); void type_decl(); void type_spec(); void var_decl(); -- cgit v1.1 From 762fd5e5547e464e25b4bee435db6df4eda0de90 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 29 Jun 2022 15:32:04 -0700 Subject: libgo: handle stat st_atim32 field and SYS_SECCOMP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patches for musl support, from Sören Tempel. Fixes PR go/105225 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415294 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4fde25a..0d49e9e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -63782f8a318e9eebfdc983f171a920c7a937c759 +548720bca6bff21ebc9aba22249d9ce45bbd90c7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 1f76941c09f6f62f4cbf7a9f531ec95268dd2c0a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 1 Jul 2022 10:56:37 -0700 Subject: compiler: rename "requires" to "needs" As of C++20 "requires" is a C++ keyword. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415754 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 12 ++++++------ gcc/go/gofrontend/types.cc | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0d49e9e..65f64e0f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -548720bca6bff21ebc9aba22249d9ce45bbd90c7 +ac438edc5335f69c95df9342f43712ad2f61ad66 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index e13df0d..67b91fa 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5302,16 +5302,16 @@ Gogo::write_c_header() Named_object* no = types.front(); types.pop_front(); - std::vector requires; + std::vector needs; std::vector declare; - if (!no->type_value()->struct_type()->can_write_to_c_header(&requires, + if (!no->type_value()->struct_type()->can_write_to_c_header(&needs, &declare)) continue; bool ok = true; for (std::vector::const_iterator pr - = requires.begin(); - pr != requires.end() && ok; + = needs.begin(); + pr != needs.end() && ok; ++pr) { for (std::list::const_iterator pt = types.begin(); @@ -5342,10 +5342,10 @@ Gogo::write_c_header() if (*pd == no) continue; - std::vector drequires; + std::vector dneeds; std::vector ddeclare; if (!(*pd)->type_value()->struct_type()-> - can_write_to_c_header(&drequires, &ddeclare)) + can_write_to_c_header(&dneeds, &ddeclare)) continue; bool done = false; diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index e82be68..4995283 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -6967,7 +6967,7 @@ Struct_type::do_import(Import* imp) bool Struct_type::can_write_to_c_header( - std::vector* requires, + std::vector* needs, std::vector* declare) const { const Struct_field_list* fields = this->fields_; @@ -6978,7 +6978,7 @@ Struct_type::can_write_to_c_header( p != fields->end(); ++p) { - if (!this->can_write_type_to_c_header(p->type(), requires, declare)) + if (!this->can_write_type_to_c_header(p->type(), needs, declare)) return false; if (Gogo::message_name(p->field_name()) == "_") sinks++; @@ -6993,7 +6993,7 @@ Struct_type::can_write_to_c_header( bool Struct_type::can_write_type_to_c_header( const Type* t, - std::vector* requires, + std::vector* needs, std::vector* declare) const { t = t->forwarded(); @@ -7027,13 +7027,13 @@ Struct_type::can_write_type_to_c_header( return true; case TYPE_STRUCT: - return t->struct_type()->can_write_to_c_header(requires, declare); + return t->struct_type()->can_write_to_c_header(needs, declare); case TYPE_ARRAY: if (t->is_slice_type()) return true; return this->can_write_type_to_c_header(t->array_type()->element_type(), - requires, declare); + needs, declare); case TYPE_NAMED: { @@ -7049,10 +7049,10 @@ Struct_type::can_write_type_to_c_header( // We will accept empty struct fields, but not print them. if (t->struct_type()->total_field_count() == 0) return true; - requires->push_back(no); - return t->struct_type()->can_write_to_c_header(requires, declare); + needs->push_back(no); + return t->struct_type()->can_write_to_c_header(needs, declare); } - return this->can_write_type_to_c_header(t->base(), requires, declare); + return this->can_write_type_to_c_header(t->base(), needs, declare); } case TYPE_CALL_MULTIPLE_RESULT: @@ -7150,9 +7150,9 @@ Struct_type::write_field_to_c_header(std::ostream& os, const std::string& name, case TYPE_POINTER: { - std::vector requires; + std::vector needs; std::vector declare; - if (!this->can_write_type_to_c_header(t->points_to(), &requires, + if (!this->can_write_type_to_c_header(t->points_to(), &needs, &declare)) os << "void*"; else -- cgit v1.1 From fbd7665360d259434f378f68cb2680b17d6cab57 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 30 Jun 2022 17:40:00 -0700 Subject: compiler: use correct init order for multi-value initialization Use the correct initialization order for var a = c var b, c = x.(bool) The global c is initialized by the preinit of b, but were missing a dependency of c on b, so a would be initialized to the zero value of c rather than the correct value. Simply adding the dependency of c on b didn't work because the preinit of b refers to c, so that appeared circular. So this patch changes the init order to skip dependencies that only appear on the left hand side of assignments in preinit blocks. Doing that didn't work because the write barrier pass can transform "a = b" into code like "gcWriteBarrier(&a, b)" that is not obviously a simple assigment. So this patch moves the collection of dependencies to just after lowering, before the write barriers are inserted. Making those changes permit relaxing the requirement that we don't warn about self-dependency in preinit blocks, so now we correctly warn for var a, b any = b.(bool) The test case is https://go.dev/cl/415238. Fixes golang/go#53619 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415594 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/go.cc | 3 + gcc/go/gofrontend/gogo.cc | 202 +++++++++++++++++++++++++-------------------- gcc/go/gofrontend/gogo.h | 23 +++++- gcc/go/gofrontend/parse.cc | 18 +++- 5 files changed, 150 insertions(+), 98 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 65f64e0f..7b1d301 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ac438edc5335f69c95df9342f43712ad2f61ad66 +6479d5976c5d848ec6f5843041275723a00006b0 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index 404cb12..1512770 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -146,6 +146,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, if (only_check_syntax) return; + // Record global variable initializer dependencies. + ::gogo->record_global_init_refs(); + // Do simple deadcode elimination. ::gogo->remove_deadcode(); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 67b91fa..9197eef 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1086,8 +1086,8 @@ class Find_vars : public Traverse public: Find_vars() - : Traverse(traverse_expressions), - vars_(), seen_objects_() + : Traverse(traverse_expressions | traverse_statements), + vars_(), seen_objects_(), lhs_is_ref_(false) { } // An iterator through the variables found, after the traversal. @@ -1104,11 +1104,16 @@ class Find_vars : public Traverse int expression(Expression**); + int + statement(Block*, size_t* index, Statement*); + private: // Accumulated variables. Vars vars_; // Objects we have already seen. Seen_objects seen_objects_; + // Whether an assignment to a variable counts as a reference. + bool lhs_is_ref_; }; // Collect global variables referenced by EXPR. Look through function @@ -1164,7 +1169,11 @@ Find_vars::expression(Expression** pexpr) if (ins.second) { // This is the first time we have seen this name. - if (f->func_value()->block()->traverse(this) == TRAVERSE_EXIT) + bool hold = this->lhs_is_ref_; + this->lhs_is_ref_ = true; + int r = f->func_value()->block()->traverse(this); + this->lhs_is_ref_ = hold; + if (r == TRAVERSE_EXIT) return TRAVERSE_EXIT; } } @@ -1192,6 +1201,29 @@ Find_vars::expression(Expression** pexpr) return TRAVERSE_CONTINUE; } +// Check a statement while searching for variables. This is where we +// skip variables on the left hand side of assigments if appropriate. + +int +Find_vars::statement(Block*, size_t*, Statement* s) +{ + if (this->lhs_is_ref_) + return TRAVERSE_CONTINUE; + Assignment_statement* as = s->assignment_statement(); + if (as == NULL) + return TRAVERSE_CONTINUE; + + // Only traverse subexpressions of the LHS. + if (as->lhs()->traverse_subexpressions(this) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + + Expression* rhs = as->rhs(); + if (Expression::traverse(&rhs, this) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + + return TRAVERSE_SKIP_COMPONENTS; +} + // Return true if EXPR, PREINIT, or DEP refers to VAR. static bool @@ -1230,11 +1262,11 @@ class Var_init { public: Var_init() - : var_(NULL), init_(NULL), refs_(NULL), dep_count_(0) + : var_(NULL), init_(NULL), dep_count_(0) { } Var_init(Named_object* var, Bstatement* init) - : var_(var), init_(init), refs_(NULL), dep_count_(0) + : var_(var), init_(init), dep_count_(0) { } // Return the variable. @@ -1247,19 +1279,6 @@ class Var_init init() const { return this->init_; } - // Add a reference. - void - add_ref(Named_object* var); - - // The variables which this variable's initializers refer to. - const std::vector* - refs() - { return this->refs_; } - - // Clear the references, if any. - void - clear_refs(); - // Return the number of remaining dependencies. size_t dep_count() const @@ -1280,36 +1299,12 @@ class Var_init Named_object* var_; // The backend initialization statement. Bstatement* init_; - // Variables this refers to. - std::vector* refs_; // The number of initializations this is dependent on. A variable // initialization should not be emitted if any of its dependencies // have not yet been resolved. size_t dep_count_; }; -// Add a reference. - -void -Var_init::add_ref(Named_object* var) -{ - if (this->refs_ == NULL) - this->refs_ = new std::vector; - this->refs_->push_back(var); -} - -// Clear the references, if any. - -void -Var_init::clear_refs() -{ - if (this->refs_ != NULL) - { - delete this->refs_; - this->refs_ = NULL; - } -} - // For comparing Var_init keys in a map. inline bool @@ -1324,7 +1319,7 @@ typedef std::list Var_inits; // variable V2 then we initialize V1 after V2. static void -sort_var_inits(Gogo* gogo, Var_inits* var_inits) +sort_var_inits(Var_inits* var_inits) { if (var_inits->empty()) return; @@ -1337,33 +1332,13 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits) Init_deps init_deps; bool init_loop = false; - // Compute all variable references. + // Map from variable to Var_init. for (Var_inits::iterator pvar = var_inits->begin(); pvar != var_inits->end(); ++pvar) { Named_object* var = pvar->var(); var_to_init[var] = &*pvar; - - Find_vars find_vars; - Expression* init = var->var_value()->init(); - if (init != NULL) - Expression::traverse(&init, &find_vars); - if (var->var_value()->has_pre_init()) - var->var_value()->preinit()->traverse(&find_vars); - Named_object* dep = gogo->var_depends_on(var->var_value()); - if (dep != NULL) - { - Expression* dinit = dep->var_value()->init(); - if (dinit != NULL) - Expression::traverse(&dinit, &find_vars); - if (dep->var_value()->has_pre_init()) - dep->var_value()->preinit()->traverse(&find_vars); - } - for (Find_vars::const_iterator p = find_vars.begin(); - p != find_vars.end(); - ++p) - pvar->add_ref(*p); } // Add dependencies to init_deps, and check for cycles. @@ -1373,7 +1348,8 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits) { Named_object* var = pvar->var(); - const std::vector* refs = pvar->refs(); + const std::vector* refs = + pvar->var()->var_value()->init_refs(); if (refs == NULL) continue; for (std::vector::const_iterator pdep = refs->begin(); @@ -1383,19 +1359,11 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits) Named_object* dep = *pdep; if (var == dep) { - // This is a reference from a variable to itself, which - // may indicate a loop. We only report an error if - // there is an initializer and there is no dependency. - // When there is no initializer, it means that the - // preinitializer sets the variable, which will appear - // to be a loop here. - if (var->var_value()->init() != NULL - && gogo->var_depends_on(var->var_value()) == NULL) - go_error_at(var->location(), - ("initialization expression for %qs " - "depends upon itself"), - var->message_name().c_str()); - + // This is a reference from a variable to itself. + go_error_at(var->location(), + ("initialization expression for %qs " + "depends upon itself"), + var->message_name().c_str()); continue; } @@ -1412,7 +1380,8 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits) pvar->add_dependency(); // Check for cycles. - const std::vector* deprefs = dep_init->refs(); + const std::vector* deprefs = + dep_init->var()->var_value()->init_refs(); if (deprefs == NULL) continue; for (std::vector::const_iterator pdepdep = @@ -1437,10 +1406,6 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits) } var_to_init.clear(); - for (Var_inits::iterator pvar = var_inits->begin(); - pvar != var_inits->end(); - ++pvar) - pvar->clear_refs(); // If there are no dependencies then the declaration order is sorted. if (!init_deps.empty() && !init_loop) @@ -1748,7 +1713,7 @@ Gogo::write_globals() // workable order. if (!var_inits.empty()) { - sort_var_inits(this, &var_inits); + sort_var_inits(&var_inits); for (Var_inits::const_iterator p = var_inits.begin(); p != var_inits.end(); ++p) @@ -3840,6 +3805,51 @@ Gogo::check_types_in_block(Block* block) block->traverse(&traverse); } +// For each global variable defined in the current package, record the +// set of variables that its initializer depends on. We do this after +// lowering so that all unknown names are resolved to their final +// locations. We do this before write barrier insertion because that +// makes it harder to distinguish references from assignments in +// preinit blocks. + +void +Gogo::record_global_init_refs() +{ + Bindings* bindings = this->package_->bindings(); + for (Bindings::const_definitions_iterator pb = bindings->begin_definitions(); + pb != bindings->end_definitions(); + pb++) + { + Named_object* no = *pb; + if (!no->is_variable()) + continue; + + Variable* var = no->var_value(); + go_assert(var->is_global()); + + Find_vars find_vars; + Expression* init = var->init(); + if (init != NULL) + Expression::traverse(&init, &find_vars); + if (var->has_pre_init()) + var->preinit()->traverse(&find_vars); + Named_object* dep = this->var_depends_on(var); + if (dep != NULL) + { + Expression* dinit = dep->var_value()->init(); + if (dinit != NULL) + Expression::traverse(&dinit, &find_vars); + if (dep->var_value()->has_pre_init()) + dep->var_value()->preinit()->traverse(&find_vars); + } + + for (Find_vars::const_iterator pv = find_vars.begin(); + pv != find_vars.end(); + ++pv) + var->add_init_ref(*pv); + } +} + // A traversal class which finds all the expressions which must be // evaluated in order within a statement or larger expression. This // is used to implement the rules about order of evaluation. @@ -7422,16 +7432,16 @@ Variable::Variable(Type* type, Expression* init, bool is_global, bool is_parameter, bool is_receiver, Location location) : type_(type), init_(init), preinit_(NULL), location_(location), - embeds_(NULL), backend_(NULL), is_global_(is_global), - is_parameter_(is_parameter), is_closure_(false), is_receiver_(is_receiver), - is_varargs_parameter_(false), is_global_sink_(false), is_used_(false), - is_address_taken_(false), is_non_escaping_address_taken_(false), - seen_(false), init_is_lowered_(false), init_is_flattened_(false), + toplevel_decl_(NULL), init_refs_(NULL), embeds_(NULL), backend_(NULL), + is_global_(is_global), is_parameter_(is_parameter), is_closure_(false), + is_receiver_(is_receiver), is_varargs_parameter_(false), + is_global_sink_(false), is_used_(false), is_address_taken_(false), + is_non_escaping_address_taken_(false), seen_(false), + init_is_lowered_(false), init_is_flattened_(false), type_from_init_tuple_(false), type_from_range_index_(false), type_from_range_value_(false), type_from_chan_element_(false), is_type_switch_var_(false), determined_type_(false), - in_unique_section_(false), is_referenced_by_inline_(false), - toplevel_decl_(NULL) + in_unique_section_(false), is_referenced_by_inline_(false) { go_assert(type != NULL || init != NULL); go_assert(!is_parameter || init == NULL); @@ -7921,6 +7931,16 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, return block_stmt; } +// Add an initializer reference. + +void +Variable::add_init_ref(Named_object* var) +{ + if (this->init_refs_ == NULL) + this->init_refs_ = new std::vector; + this->init_refs_->push_back(var); +} + // Export the variable void diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 2ee0fda..433fdae 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -842,6 +842,11 @@ class Gogo void check_return_statements(); + // Gather references from global variables initializers to other + // variables. + void + record_global_init_refs(); + // Remove deadcode. void remove_deadcode(); @@ -2333,6 +2338,15 @@ class Variable this->toplevel_decl_ = s; } + // Note that the initializer of this global variable refers to VAR. + void + add_init_ref(Named_object* var); + + // The variables that this variable's initializers refer to. + const std::vector* + init_refs() const + { return this->init_refs_; } + // Traverse the initializer expression. int traverse_expression(Traverse*, unsigned int traverse_mask); @@ -2389,6 +2403,12 @@ class Variable Block* preinit_; // Location of variable definition. Location location_; + // The top-level declaration for this variable. Only used for local + // variables. Must be a Temporary_statement if not NULL. + Statement* toplevel_decl_; + // Variables that the initializer of a global variable refers to. + // Used for initializer ordering. + std::vector* init_refs_; // Any associated go:embed comments. std::vector* embeds_; // Backend representation. @@ -2439,9 +2459,6 @@ class Variable // True if this variable is referenced from an inlined body that // will be put into the export data. bool is_referenced_by_inline_ : 1; - // The top-level declaration for this variable. Only used for local - // variables. Must be a Temporary_statement if not NULL. - Statement* toplevel_decl_; }; // A variable which is really the name for a function return value, or diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index e388261..a3c6f63 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -1977,7 +1977,11 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type, else if (!val_no->is_sink()) { if (val_no->is_variable()) - val_no->var_value()->add_preinit_statement(this->gogo_, s); + { + val_no->var_value()->add_preinit_statement(this->gogo_, s); + if (no->is_variable()) + this->gogo_->record_var_depends_on(no->var_value(), val_no); + } } else if (!no->is_sink()) { @@ -2044,7 +2048,11 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type, else if (!val_no->is_sink()) { if (val_no->is_variable()) - val_no->var_value()->add_preinit_statement(this->gogo_, s); + { + val_no->var_value()->add_preinit_statement(this->gogo_, s); + if (no->is_variable()) + this->gogo_->record_var_depends_on(no->var_value(), val_no); + } } else if (!no->is_sink()) { @@ -2110,7 +2118,11 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars, else if (!val_no->is_sink()) { if (val_no->is_variable()) - val_no->var_value()->add_preinit_statement(this->gogo_, s); + { + val_no->var_value()->add_preinit_statement(this->gogo_, s); + if (no->is_variable()) + this->gogo_->record_var_depends_on(no->var_value(), val_no); + } } else if (!no->is_sink()) { -- cgit v1.1 From ccc39d9e97ce24623aefae2097bff791e01619d9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 4 Jul 2022 12:20:36 -0700 Subject: compiler: better error message for unknown package name Fixes golang/go#51237 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415994 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/parse.cc | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7b1d301..461e2fd 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6479d5976c5d848ec6f5843041275723a00006b0 +a209dca9ec918535977dcab99fd9bb60986ffacd The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index a3c6f63..c93d82b 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -191,7 +191,11 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage) Named_object* package = this->gogo_->lookup(name, NULL); if (package == NULL || !package->is_package()) { - go_error_at(this->location(), "expected package"); + if (package == NULL) + go_error_at(this->location(), "reference to undefined name %qs", + Gogo::message_name(name).c_str()); + else + go_error_at(this->location(), "expected package"); // We expect . IDENTIFIER; skip both. if (this->advance_token()->is_identifier()) this->advance_token(); -- cgit v1.1 From c70a48a8f8f6a43b35f783b5672c9a3c0a363c31 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 3 Jul 2022 14:37:23 -0700 Subject: compiler: propagate array length error marker farther Fixes golang/go#53639 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415936 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 6 ++++++ gcc/go/gofrontend/types.cc | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 461e2fd..7c5c456 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a209dca9ec918535977dcab99fd9bb60986ffacd +d295a0a2c96c0f7c3abd94fea3aa4e2303bf2af2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 00d35a9..2492d9f 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -8486,6 +8486,11 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function, pa != this->args()->end(); ++pa) { + if ((*pa)->is_error_expression()) + { + go_assert(saw_errors()); + return Expression::make_error(loc); + } if ((*pa)->is_nil_expression()) { Expression* nil = Expression::make_nil(loc); @@ -13391,6 +13396,7 @@ Array_index_expression::do_check_types(Gogo*) if (array_type == NULL) { go_assert(this->array_->type()->is_error()); + this->set_is_error(); return; } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 4995283..9f34801 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -7429,7 +7429,10 @@ bool Array_type::do_verify() { if (this->element_type()->is_error_type()) - return false; + { + this->set_is_error(); + return false; + } if (!this->verify_length()) { this->length_ = Expression::make_error(this->length_->location()); -- cgit v1.1 From f35d65517a59565758107c5b1a51a5fa382f8d1a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 12 Jul 2022 19:42:43 -0700 Subject: libgo: don't include when building gen-sysinfo.go Removing this doesn't change anything at least with glibc 2.33. The include was added in https://go.dev/cl/6100049 but it's not clear why. Fixes PR go/106266 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/417294 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7c5c456..5ea0406 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -d295a0a2c96c0f7c3abd94fea3aa4e2303bf2af2 +ff68b1a147eb60082fd60c198db0ef5477ade938 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 5054bc001d9b66fe68d938790f08f48621c6b976 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 15 Jul 2022 08:02:13 -0700 Subject: go: fix f(g()) where g returns zero-sized type Test case is https://go.dev/cl/417481. Fixes golang/go#23868 * go-gcc.cc (Gcc_backend::call_expression): Handle a void argument, as for f(g()) where g returns a zero-sized type. --- gcc/go/go-gcc.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index f3de7a8..7b4b2ad 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -2112,6 +2112,19 @@ Gcc_backend::call_expression(Bfunction*, // containing fcn for call args[i] = fn_args.at(i)->get_tree(); if (args[i] == error_mark_node) return this->error_expression(); + if (TREE_TYPE(args[i]) == void_type_node) + { + // This can happen for a case like f(g()) where g returns a + // zero-sized type, because in that case we've changed g to + // return void. + tree t = TYPE_ARG_TYPES(TREE_TYPE(TREE_TYPE(fn))); + for (size_t j = 0; j < i; ++j) + t = TREE_CHAIN(t); + tree arg_type = TREE_TYPE(TREE_VALUE(t)); + args[i] = fold_build2_loc(EXPR_LOCATION(args[i]), COMPOUND_EXPR, + arg_type, args[i], + build_zero_cst(arg_type)); + } } tree fndecl = fn; -- cgit v1.1 From bdc7b765f8728cbb769fe1eeef773eda15578aee Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 16 Jul 2022 00:16:30 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 5fdf423..6ad883f 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2022-07-15 Ian Lance Taylor + + * go-gcc.cc (Gcc_backend::call_expression): Handle a void + argument, as for f(g()) where g returns a zero-sized type. + 2022-06-02 David Malcolm * go-lang.cc (go_get_sarif_source_language): New. -- cgit v1.1 From 2b5baaef0b6e4d1d8e36cda091be26649163ffdb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 16 Jul 2022 16:29:38 -0700 Subject: go: fix f().x where f returns zero-sized type Test case is https://go.dev/cl/417874. Fixes golang/go#23870 * go-gcc.cc (Gcc_backend::struct_field_expression): Handle a void expression, as for f().x where f returns a zero-sized type. --- gcc/go/go-gcc.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 7b4b2ad..1ba7206 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -1707,6 +1707,13 @@ Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index, if (struct_tree == error_mark_node || TREE_TYPE(struct_tree) == error_mark_node) return this->error_expression(); + + // A function call that returns a zero-sized object will have been + // changed to return void. A zero-sized object can have a + // (zero-sized) field, so support that case. + if (TREE_TYPE(struct_tree) == void_type_node) + return bstruct; + gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE); tree field = TYPE_FIELDS(TREE_TYPE(struct_tree)); if (field == NULL_TREE) -- cgit v1.1 From 7bcd7f47359b903bf7a193b95d4450d9d69c60ba Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 17 Jul 2022 00:16:23 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 6ad883f..5dbcb29 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2022-07-16 Ian Lance Taylor + + * go-gcc.cc (Gcc_backend::struct_field_expression): Handle a void + expression, as for f().x where f returns a zero-sized type. + 2022-07-15 Ian Lance Taylor * go-gcc.cc (Gcc_backend::call_expression): Handle a void -- cgit v1.1 From cf1725610526fe347d2530455b32affc033fd7fc Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 22 Jul 2022 11:38:20 -0700 Subject: libgo: use POSIX shell arithmetic expansion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid bash-specific ((expression)) syntax. As the bash syntax converts a non-zero value to a zero status (and a zero value to a 1 status), and POSIX arithmetic expansion does not, we have to negate the result. Based on patch by Sören Tempel. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/419154 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5ea0406..2f2fafd 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ff68b1a147eb60082fd60c198db0ef5477ade938 +a62f20ae78ddd41be682dde8cab075ca4f5dbb2a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1