[PATCH] Fix an ICE when compiling Go with LTO (PR go/89019)
Richard Biener
richard.guenther@gmail.com
Thu Jan 24 11:52:00 GMT 2019
On Thu, Jan 24, 2019 at 2:18 AM Nikhil Benesch <nikhil.benesch@gmail.com> wrote:
>
> This patch fixes an ICE I reported earlier today as PR go/89019, which
> occurs when compiling sufficiently complicated Go code with link-time
> optimization (i.e., -flto) enabled.
>
> Both of these simple test programs are sufficient to trigger the ICE:
>
> $ cat crash1.go
> package main
>
> type fcanary func()
>
> $ cat crash2.go
> package main
>
> func f() {
> var canary func()
> func() {
> canary()
> }()
> }
>
> The cause appears to be that the propagation of structural equality
> requirements is mishandled during the handoff from the Go frontend to
> the middle-end. Pointers to types that required structural equality
> were not always marked as requiring structural equality themselves.
> Remarkably, the only code that notices the mistake is the free_lang_data
> IPA pass, which is only active when LTO is enabled.
>
> The enclosed patch fixes the issue and provides test coverage by adding
> a subtest to the Go torture test suite that compiles with -flto.
> Bootstrapped and ran Go test suite on x86_64-pc-linux-gnu.
>
> 2018-01-23 Nikhil Benesch <nikhil.benesch@gmail.com>
>
> PR go/89019
> * go-gcc.cc (Gcc_backend::placeholder_struct_type): Mark
> placeholder structs as requiring structural equality.
> (Gcc_backend::set_placeholder_pointer_type): Propagate
> the canonical type from the referenced type to the pointer type.
> * lib/go-torture.exp: Test compiling with -flto.
>
> diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
> index 7fbdd074119..4e9e0e3026a 100644
> --- a/gcc/go/go-gcc.cc
> +++ b/gcc/go/go-gcc.cc
> @@ -1049,6 +1049,7 @@ Gcc_backend::set_placeholder_pointer_type(Btype* placeholder,
> }
> gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
> TREE_TYPE(pt) = TREE_TYPE(tt);
> + TYPE_CANONICAL(pt) = TYPE_CANONICAL(tt);
This doesn't make sense - it says to the middle-end that
T* is equal to T?
> if (TYPE_NAME(pt) != NULL_TREE)
> {
> // Build the data structure gcc wants to see for a typedef.
> @@ -1080,6 +1081,12 @@ Gcc_backend::placeholder_struct_type(const std::string& name,
> get_identifier_from_string(name),
> ret);
> TYPE_NAME(ret) = decl;
> +
> + // The struct type that eventually replaces this placeholder will require
> + // structural equality. The placeholder must too, so that the requirement
> + // for structural equality propagates to references that are constructed
> + // before the replacement occurs.
> + SET_TYPE_STRUCTURAL_EQUALITY(ret);
> }
> return this->make_type(ret);
> }
> diff --git a/gcc/testsuite/lib/go-torture.exp b/gcc/testsuite/lib/go-torture.exp
> index 213711e41df..a7eca184416 100644
> --- a/gcc/testsuite/lib/go-torture.exp
> +++ b/gcc/testsuite/lib/go-torture.exp
> @@ -34,7 +34,8 @@ if ![info exists TORTURE_OPTIONS] {
> { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \
> { -O2 -fbounds-check } \
> { -O3 -g } \
> - { -Os }]
> + { -Os } \
> + { -flto }]
> }
>
>
>
More information about the Gcc-patches
mailing list