From patchwork Mon Oct 23 21:06:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 157098 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce89:0:b0:403:3b70:6f57 with SMTP id p9csp1553944vqx; Mon, 23 Oct 2023 14:06:50 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFjq/sf1tGW/4fQ7vDbIUbCfExVSja2be6Z5xV23ALnbSZ8YWn9rTO9d+EIXs+DJ79F/QYZ X-Received: by 2002:a67:a60f:0:b0:457:dbfc:5c69 with SMTP id p15-20020a67a60f000000b00457dbfc5c69mr10265862vse.12.1698095209850; Mon, 23 Oct 2023 14:06:49 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698095209; cv=pass; d=google.com; s=arc-20160816; b=UDTFHS5dXMK+lHdMVNAH/Tz3r+6S/MYgWrFkH9zm+Lve9XxL8Q+3RYwNgZi/T3J3rp EdRf1uURfDN1RRLBBe3MHwzU1ILLwXAu+3hdIF/xFLUuc+w3E03vmzJwrILcbJ8LB8tK 4QfU7R4XiQQCVpM1IEFTFeRFEJgFwFX8x1/hgd2WRmcPPvGxfGvItmS/95VE+bpeOYQv fUd0GDSuGcId+ATzTzYmtVTN52+R/EKFNul3PIKV4wk29vH5sGB9VFZ2Kr/8pvpcyolg UCIAgPDCQAdU3Oqqiyl0WM1b8aJ3ZMFv4blIYMI3goOoCrfwj+rMpxZnsbAL8iTEo6f2 DQtA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:to:subject:message-id:date:from :mime-version:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=zNcPKoUc8+KKP9xOFUESISLQ6cMH9rfb4kPJtUdXhy4=; fh=sx1AF6BoRLLvWrm7PiL2RBt/kekZxFGoFwZKL1Ho560=; b=wjPI3xUSgZfhLoItbfl1e7MYXm4J9eB0Uxt7MZ6mevzIdWWopBHBGPlBoQtir22kk3 b+iVpGuPhHIyt6klm5XKVm14kPy3pBAL6B8PSG/kQEzE7flnvYt7gO10y2inigcFN6G3 5GxfEigelqTa7Dj179wdRJRXsHakdT05flJPfhLTO7JoWUoqN+0nJsI7MGt8Ji70yRXH g1j18VwyiDAKGGVrz4mNCGTZWofpff7LbxHkym3avZ3ErV/7vjLo3vS9vJS9DzzzFEyo NVvbBdp7it4z9Iy9lzgy4bgVVsHwQlZLXKZlauU8FK/I0+p/GWbIT49gMPIaRKZsNshz G3Ng== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@golang-org.20230601.gappssmtp.com header.s=20230601 header.b=h3TNR8c6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=golang.org Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id h7-20020a0ceec7000000b0066d1348bddbsi5956583qvs.441.2023.10.23.14.06.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Oct 2023 14:06:49 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@golang-org.20230601.gappssmtp.com header.s=20230601 header.b=h3TNR8c6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=golang.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 97C0D38515D6 for ; Mon, 23 Oct 2023 21:06:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-yb1-xb35.google.com (mail-yb1-xb35.google.com [IPv6:2607:f8b0:4864:20::b35]) by sourceware.org (Postfix) with ESMTPS id 028053858413 for ; Mon, 23 Oct 2023 21:06:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 028053858413 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=golang.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=golang.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 028053858413 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698095187; cv=none; b=uHsNhUD6Favj4xFpQoxInu/lKi/lyeDlioy6oO8hp4TketrlyLBJpHUoeTz9Ck1HI1X03DS1PXE8UeVz4RL+UUWRNY+YwN5spi/t3B4+YFcnyVBiCFT2M5GaBYKoAf6re1oYTtwIftIhjp2UztJd6cxFnXUOqpayXhnJ7Uo9fDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698095187; c=relaxed/simple; bh=8KaV/AM5+jd0mxFodIqqNeNj5uFdlBfT/x6sJzsyWNo=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=nzXCLqVPF98/0gGS10ybjXIti2ayERvyyi4l6lOqilqVSDxVb07rpLzrha8GFnKVh1kdTpQjjQLpyMIdKDUTnkaaOtAW/Elbp0Wl7N7tE3Ej/DRRjVPshawpo0yV+G3qlUqcZWvHQA6vrFIvYmE3xqK0VzAUeKdhBrlJeXs/fvY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-yb1-xb35.google.com with SMTP id 3f1490d57ef6-d9ac9573274so3492049276.0 for ; Mon, 23 Oct 2023 14:06:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=golang-org.20230601.gappssmtp.com; s=20230601; t=1698095184; x=1698699984; darn=gcc.gnu.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=zNcPKoUc8+KKP9xOFUESISLQ6cMH9rfb4kPJtUdXhy4=; b=h3TNR8c658xWT5k2xs/Dr+wk854DAZs/GSyF5vflQSroAX+v2gPuke+Jkcw8fhiCI8 HvJx/MHw0kAhhZa3inhFlUxzA6PgOF1Ph5FDHuZdhnOKPUz2u8trS3ljuiS7Sy0RDoza jQWGT14QgKM15HXi9KDA57VrC8GamzGPqXLOAw7oqqE9Z+9ZHxRQFp3guR9iRMhcJ/13 i51MvSRuhhtrIw+YHH50aINyI03hrSuNNWJ+f1A+9z7Bee6ychtrlMWk3SLAKMKo9AKL cBxdXnb1Wv2kZ8Lrkb3td0koAqK16b3D6SF+2QkXz317mFumqNj0aW4/JEvEEP4qOCdz /XlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698095184; x=1698699984; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=zNcPKoUc8+KKP9xOFUESISLQ6cMH9rfb4kPJtUdXhy4=; b=X5ZGBOqIQkGg8zPlri8O/B9x3Ie9E3xawhg2O2iR5etoyVHyxwRLMBvpHz3VCQ5CVz w1DBypIIF9vAnlbSdkotm17jcjZDIojzzUJjR9h+17MoQVPicMbQmUXeshdnzcle+X0A A+aYAg95WO9rHcJYOL6u6/DS3AEvlAptVIGHR8WnBE1tWsdC4L3i0z5PhMibYZrZSeV4 xKowoqrX0HQHeOz87AA0YYh+LAP5RHnm//ulVA0oK/q3abLL7IvgcyUdIn9xn4ehhKpJ 3wuF7oPPRi89GDpGSmO7kl/Wk0AQrNuiD6FeQudV6DwZl47gZETzffheEyBnf6EjQClO fL5A== X-Gm-Message-State: AOJu0YwNOPQwReQWV/LRk0GSlKdyZIs9APvgOnVk2Se73kE3QaPLzyr6 iq2HiuzP0U+o3u71FdvXBmtTKVbw0U/ayV3QHD0zM/cWGjOuU9UUpRs= X-Received: by 2002:a05:6902:1890:b0:d9a:d91f:3888 with SMTP id cj16-20020a056902189000b00d9ad91f3888mr12727545ybb.13.1698095183872; Mon, 23 Oct 2023 14:06:23 -0700 (PDT) MIME-Version: 1.0 From: Ian Lance Taylor Date: Mon, 23 Oct 2023 14:06:13 -0700 Message-ID: Subject: Go patch committed: Add Expression::is_untyped method To: gcc-patches , gofrontend-dev X-Spam-Status: No, score=-9.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.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780581882806862598 X-GMAIL-MSGID: 1780581882806862598 This Go frontend patches adds an Expression::is_untyped method. This method is not currently used by anything, but it will be used by later changes in this series. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian ac50e9b72bf9bb6d5b28096bb164fb050db6e290 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0f961157dfd..d4095637cea 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -081ec9824a74ec9d82628d8d2f6b9a7a4c35a529 +1c0a7c9338801d15afba7e39109554ed3406654e 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 273831fabf3..5bea6238def 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -201,6 +201,19 @@ Expression::report_error(const char* msg) this->set_is_error(); } +// A convenience function for handling a type in do_is_untyped. If +// TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE +// and return true. + +bool +Expression::is_untyped_type(Type* type, Type** ptype) +{ + if (!type->is_abstract()) + return false; + *ptype = type; + return true; +} + // Set types of variables and constants. This is implemented by the // child class. @@ -826,6 +839,10 @@ class Error_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const + { return false; } + bool do_numeric_constant_value(Numeric_constant* nc) const { @@ -1965,6 +1982,9 @@ class Boolean_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const { return this->val_ == false; } @@ -2023,6 +2043,15 @@ Boolean_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +bool +Boolean_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + *ptype = Type::make_boolean_type(); + return true; +} + // Get the type. Type* @@ -2096,6 +2125,15 @@ String_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +bool +String_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + *ptype = Type::make_string_type(); + return true; +} + // Get the type. Type* @@ -2485,6 +2523,9 @@ class Integer_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const { return mpz_sgn(this->val_) == 0; } @@ -2568,6 +2609,18 @@ Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const return true; } +bool +Integer_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + if (this->is_character_constant_) + *ptype = Type::make_abstract_character_type(); + else + *ptype = Type::make_abstract_integer_type(); + return true; +} + // Return the current type. If we haven't set the type yet, we return // an abstract integer type. @@ -2913,6 +2966,9 @@ class Float_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const { @@ -2979,6 +3035,15 @@ Float_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +bool +Float_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + *ptype = Type::make_abstract_float_type(); + return true; +} + // Return the current type. If we haven't set the type yet, we return // an abstract float type. @@ -3135,6 +3200,9 @@ class Complex_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const { @@ -3205,6 +3273,15 @@ Complex_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +bool +Complex_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + *ptype = Type::make_abstract_complex_type(); + return true; +} + // Return the current type. If we haven't set the type yet, we return // an abstract complex type. @@ -3458,6 +3535,21 @@ Const_expression::do_boolean_constant_value(bool* val) const return ok; } +// Whether this is untyped. + +bool +Const_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + + Named_constant* nc = this->constant_->const_value(); + if (nc->type() != NULL) + return Expression::is_untyped_type(nc->type(), ptype); + + return nc->expr()->is_untyped(ptype); +} + // Return the type of the const reference. Type* @@ -3707,6 +3799,13 @@ class Nil_expression : public Expression do_is_constant() const { return true; } + bool + do_untyped_type(Type** ptype) const + { + *ptype = Type::make_nil_type(); + return true; + } + bool do_is_zero_value() const { return true; } @@ -4774,6 +4873,14 @@ Unary_expression::do_is_constant() const return this->expr_->is_constant(); } +bool +Unary_expression::do_is_untyped(Type** ptype) const +{ + if (this->op_ == OPERATOR_MULT || this->op_ == OPERATOR_AND) + return false; + return this->expr_->is_untyped(ptype); +} + // Return whether a unary expression can be used as a constant // initializer. @@ -5523,6 +5630,81 @@ Binary_expression::do_traverse(Traverse* traverse) return Expression::traverse(&this->right_, traverse); } +// Return whether a binary expression is untyped. + +bool +Binary_expression::do_is_untyped(Type** ptype) const +{ + if (this->type_ != NULL) + return Expression::is_untyped_type(this->type_, ptype); + + switch (this->op_) + { + case OPERATOR_EQEQ: + case OPERATOR_NOTEQ: + case OPERATOR_LT: + case OPERATOR_LE: + case OPERATOR_GT: + case OPERATOR_GE: + // Comparisons are untyped by default. + *ptype = Type::make_boolean_type(); + return true; + + case OPERATOR_LSHIFT: + case OPERATOR_RSHIFT: + // A shift operation is untyped if the left hand expression is + // untyped. The right hand expression is irrelevant. + return this->left_->is_untyped(ptype); + + default: + break; + } + + Type* tleft; + Type* tright; + if (!this->left_->is_untyped(&tleft) + || !this->right_->is_untyped(&tright)) + return false; + + // If both sides are numeric, pick a type based on the kind. + enum kind { INT, RUNE, FLOAT, COMPLEX }; + enum kind kleft, kright; + + if (tleft->integer_type() != NULL) + kleft = tleft->integer_type()->is_rune() ? RUNE : INT; + else if (tleft->float_type() != NULL) + kleft = FLOAT; + else if (tleft->complex_type() != NULL) + kleft = COMPLEX; + else + { + // Not numeric. If the types are different, we will report an + // error later. + *ptype = tleft; + return true; + } + + if (tright->integer_type() != NULL) + kright = tright->integer_type()->is_rune() ? RUNE : INT; + else if (tright->float_type() != NULL) + kright = FLOAT; + else if (tright->complex_type() != NULL) + kright = COMPLEX; + else + { + // Types are different. We will report an error later. + *ptype = tleft; + return true; + } + + if (kleft > kright) + *ptype = tleft; + else + *ptype = tright; + + return true; +} + // Return whether this expression may be used as a static initializer. bool @@ -7645,6 +7827,21 @@ String_concat_expression::do_is_constant() const return true; } +bool +String_concat_expression::do_is_untyped(Type** ptype) const +{ + for (Expression_list::iterator pe = this->exprs_->begin(); + pe != this->exprs_->end(); + ++pe) + { + if (!(*pe)->is_untyped(ptype)) + return false; + } + + *ptype = Type::make_string_type(); + return true; +} + bool String_concat_expression::do_is_zero_value() const { @@ -9671,6 +9868,47 @@ Builtin_call_expression::do_is_constant() const return false; } +// Return whether a builtin call is untyped. Most builtin functions +// have a known type, but complex, real, and imag can be untyped. + +bool +Builtin_call_expression::do_is_untyped(Type** ptype) const +{ + if (this->is_error_expression()) + return false; + + switch (this->code_) + { + default: + return false; + + case BUILTIN_COMPLEX: + { + const Expression_list* args = this->args(); + if (args == NULL || args->size() != 2) + return false; + Type* dummy; + if (!args->front()->is_untyped(&dummy) + || !args->back()->is_untyped(&dummy)) + return false; + *ptype = Type::make_abstract_complex_type(); + return true; + } + + case BUILTIN_REAL: + case BUILTIN_IMAG: + { + Expression* arg = this->one_arg(); + if (arg == NULL) + return false; + if (!arg->is_untyped(ptype)) + return false; + *ptype = Type::make_abstract_float_type(); + return true; + } + } +} + // Return a numeric constant if possible. bool diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 2abc9cb8425..49140d100a4 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -566,6 +566,15 @@ class Expression is_constant() const { return this->do_is_constant(); } + // Return whether this expression is untyped. This isn't quite the + // same as is_constant with an abstract type, as 1<do_is_untyped(ptype); } + // Return whether this is the zero value of its type. bool is_zero_value() const @@ -1169,6 +1178,11 @@ class Expression do_is_constant() const { return false; } + // Return whether this expression is untyped. + virtual bool + do_is_untyped(Type**) const + { return false; } + // Return whether this is the zero value of its type. virtual bool do_is_zero_value() const @@ -1274,6 +1288,12 @@ class Expression void report_error(const char*); + // A convenience function for handling a type in do_is_untyped. If + // TYPE is not abstract, return false. Otherwise set *PTYPE to TYPE + // and return true. + static bool + is_untyped_type(Type* type, Type** ptype); + // Write a name to export data. static void export_name(Export_function_body* efb, const Named_object*); @@ -1501,6 +1521,9 @@ class Const_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const; @@ -1830,6 +1853,9 @@ class String_expression : public Expression do_is_constant() const { return true; } + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const { return this->val_ == ""; } @@ -2136,6 +2162,9 @@ class Unary_expression : public Expression bool do_is_constant() const; + bool + do_is_untyped(Type**) const; + bool do_is_static_initializer() const; @@ -2293,6 +2322,9 @@ class Binary_expression : public Expression do_is_constant() const { return this->left_->is_constant() && this->right_->is_constant(); } + bool + do_is_untyped(Type**) const; + bool do_is_static_initializer() const; @@ -2415,6 +2447,9 @@ class String_concat_expression : public Expression bool do_is_constant() const; + bool + do_is_untyped(Type**) const; + bool do_is_zero_value() const; @@ -2767,6 +2802,9 @@ class Builtin_call_expression : public Call_expression bool do_is_constant() const; + bool + do_is_untyped(Type**) const; + bool do_numeric_constant_value(Numeric_constant*) const;