From patchwork Sat Nov 28 15:02:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 1407540 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Fd5lvE6X; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cjvqp0FTdz9s1l for ; Sun, 29 Nov 2020 02:02:43 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56504386EC23; Sat, 28 Nov 2020 15:02:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 56504386EC23 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1606575761; bh=i7FN/bvATcjCcOgvlBIJs9DhOhGa14QR32wc7P4Oa1k=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Fd5lvE6X/m8fsUonHv9F6cBw+14PJSetn28DrQyqc46xpxceGk5UHTPUcHU56haSq dFqqUgOUN+zce9cETkyH0sJFY1hE3F0Q+tg1QJZVAhB4bfQhcr5Ka5giMIryf1lbcZ cnqatTjCN4TPdIKXDvhmnF3VdAotnvJ9/+WX2bbA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id EC19F3858C27 for ; Sat, 28 Nov 2020 15:02:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EC19F3858C27 Received: by mail-ed1-x532.google.com with SMTP id m16so8824360edr.3 for ; Sat, 28 Nov 2020 07:02:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=i7FN/bvATcjCcOgvlBIJs9DhOhGa14QR32wc7P4Oa1k=; b=ptgLnFjG8POhy5+nrKzJLAEELNNnCdawNYttEB1QZln7p1pX2Fh0jFEADulEz23zQY J/98f+aW5oJdcLkHTPBG8PXyjPrEUFtW8ZntWHE7j1G/SY8jdZjRRxdO/ugOtjFq+L17 YQHt0rw8lP2cS41QJYmZqXviPdFwrPLFwRE6/JkXloHuMDol+A9g3tOZxIj3Lr03epT+ W2Jh+QcMAS5ixqPzNjk1NfcouKBedNYokUvxqcFVnC2PkSbM8cFLGl+LMUEWexGeuwu0 cfGmlhKFb+e41S2QOR4HrboPKr6UqrqMs/Qh1irVfs84BS9JPMpwKsMUR8CTCF+yyJ1H r8OA== X-Gm-Message-State: AOAM53099rQnUqBKVkqURpePfIOfSD/Xv9jyWs++xMz68cZtnWOa+Hdw CrQAFJmAdaHvUA/5UKD8wPaJTq/IJKiG0CIKLpYedUM01G3nRQ== X-Google-Smtp-Source: ABdhPJzPFF4Q6Buh/7N/ArySNw2o9HRT3LTWFRWzscFsJ2/Tr2xLZCHL3X/N4WTGrAfEvyVY6l7QsfPeZvA8DjKi32Q= X-Received: by 2002:a05:6402:1155:: with SMTP id g21mr13727700edw.53.1606575756662; Sat, 28 Nov 2020 07:02:36 -0800 (PST) MIME-Version: 1.0 Date: Sat, 28 Nov 2020 07:02:25 -0800 Message-ID: Subject: Go patch committed: Avoid follow-on errors for bad types To: gcc-patches , gofrontend-dev X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Ian Lance Taylor via Gcc-patches From: Ian Lance Taylor Reply-To: Ian Lance Taylor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch to the Go frontend marks bad types are erroneous, to avoid generating further errors. This required some code using array types to check for errors. This is for https://golang.org/issue/19880. This requires updating one of the tests in the testsuite. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian b1adbc27c4a85ded4db81ed65b1cefce4cee8d15 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 59648326fcc..46959070e85 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -66669bb6cae475eda6666a94f6ff4f616ffa77d7 +16ab9b001c214cf831bc52a7bca5a2d18e9e4f3c 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 448888b0ad7..dc7399ebb3a 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -15303,9 +15303,22 @@ Array_construction_expression::do_is_static_initializer() const void Array_construction_expression::do_determine_type(const Type_context*) { + if (this->is_error_expression()) + { + go_assert(saw_errors()); + return; + } + if (this->vals() == NULL) return; - Type_context subcontext(this->type_->array_type()->element_type(), false); + Array_type* at = this->type_->array_type(); + if (at == NULL || at->is_error() || at->element_type()->is_error()) + { + go_assert(saw_errors()); + this->set_is_error(); + return; + } + Type_context subcontext(at->element_type(), false); for (Expression_list::const_iterator pv = this->vals()->begin(); pv != this->vals()->end(); ++pv) @@ -15320,10 +15333,22 @@ Array_construction_expression::do_determine_type(const Type_context*) void Array_construction_expression::do_check_types(Gogo*) { + if (this->is_error_expression()) + { + go_assert(saw_errors()); + return; + } + if (this->vals() == NULL) return; Array_type* at = this->type_->array_type(); + if (at == NULL || at->is_error() || at->element_type()->is_error()) + { + go_assert(saw_errors()); + this->set_is_error(); + return; + } int i = 0; Type* element_type = at->element_type(); for (Expression_list::const_iterator pv = this->vals()->begin(); @@ -15348,6 +15373,12 @@ Expression* Array_construction_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) { + if (this->is_error_expression()) + { + go_assert(saw_errors()); + return this; + } + if (this->vals() == NULL) return this; @@ -15384,6 +15415,12 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*, void Array_construction_expression::do_add_conversions() { + if (this->is_error_expression()) + { + go_assert(saw_errors()); + return; + } + if (this->vals() == NULL) return; diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index c4570b41a71..286ecc16366 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -261,6 +261,15 @@ Type::is_error_type() const } } +// Note that this type is an error. This is called by children when +// they discover an error during the verify_types pass. + +void +Type::set_is_error() +{ + this->classification_ = TYPE_ERROR; +} + // If this is a pointer type, return the type to which it points. // Otherwise, return NULL. @@ -5871,6 +5880,7 @@ Struct_type::do_verify() { go_error_at(p->location(), "embedded type may not be a pointer"); p->set_type(Type::make_error_type()); + this->set_is_error(); } else if (t->points_to() != NULL && t->points_to()->interface_type() != NULL) @@ -5878,6 +5888,7 @@ Struct_type::do_verify() go_error_at(p->location(), "embedded type may not be pointer to interface"); p->set_type(Type::make_error_type()); + this->set_is_error(); } } } @@ -7236,6 +7247,13 @@ Array_type::verify_length() Type_context context(Type::lookup_integer_type("int"), false); this->length_->determine_type(&context); + if (this->length_->is_error_expression() + || this->length_->type()->is_error()) + { + go_assert(saw_errors()); + return false; + } + if (!this->length_->is_constant()) { go_error_at(this->length_->location(), "array bound is not constant"); @@ -7310,7 +7328,10 @@ Array_type::do_verify() if (this->element_type()->is_error_type()) return false; if (!this->verify_length()) - this->length_ = Expression::make_error(this->length_->location()); + { + this->length_ = Expression::make_error(this->length_->location()); + this->set_is_error(); + } return true; } @@ -8125,11 +8146,20 @@ Map_type::do_verify() { // The runtime support uses "map[void]void". if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type()) - go_error_at(this->location_, "invalid map key type"); + { + go_error_at(this->location_, "invalid map key type"); + this->set_is_error(); + } if (!this->key_type_->in_heap()) - go_error_at(this->location_, "go:notinheap map key not allowed"); + { + go_error_at(this->location_, "go:notinheap map key not allowed"); + this->set_is_error(); + } if (!this->val_type_->in_heap()) - go_error_at(this->location_, "go:notinheap map value not allowed"); + { + go_error_at(this->location_, "go:notinheap map value not allowed"); + this->set_is_error(); + } return true; } @@ -8660,8 +8690,11 @@ Channel_type::do_verify() // We have no location for this error, but this is not something the // ordinary user will see. if (!this->element_type_->in_heap()) - go_error_at(Linemap::unknown_location(), - "chan of go:notinheap type not allowed"); + { + go_error_at(Linemap::unknown_location(), + "chan of go:notinheap type not allowed"); + this->set_is_error(); + } return true; } diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 5965d5a3fde..d0970295d75 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1141,6 +1141,10 @@ class Type virtual void do_export(Export*) const; + // For children to call when they detect that they are in error. + void + set_is_error(); + // Return whether a method expects a pointer as the receiver. static bool method_expects_pointer(const Named_object*); diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug255.go b/gcc/testsuite/go.test/test/fixedbugs/bug255.go index acf4f23910d..458fb972b20 100644 --- a/gcc/testsuite/go.test/test/fixedbugs/bug255.go +++ b/gcc/testsuite/go.test/test/fixedbugs/bug255.go @@ -1,15 +1,20 @@ // errorcheck -// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main -var a [10]int // ok -var b [1e1]int // ok -var c [1.5]int // ERROR "truncated" -var d ["abc"]int // ERROR "invalid array bound|not numeric" -var e [nil]int // ERROR "invalid array bound|not numeric" -var f [e]int // ERROR "invalid array bound|not constant" -var g [1<<65]int // ERROR "array bound is too large|overflows" +var a [10]int // ok +var b [1e1]int // ok +var c [1.5]int // ERROR "truncated" +var d ["abc"]int // ERROR "invalid array bound|not numeric" +var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric" +var f [e]int // ok: error already reported for e +var g [1 << 65]int // ERROR "array bound is too large|overflows" +var h [len(a)]int // ok + +func ff() string + +var i [len([1]string{ff()})]int // ERROR "non-constant array bound|not constant"