From patchwork Tue Oct 8 23:54:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 281687 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2E2F32C0086 for ; Wed, 9 Oct 2013 10:54:47 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=sPy3EyPHcuZiGkEnSrDZM2Hr0pcvwgkDCjymx3Em8n9iIIbOSs2UJ I7H9UlZDsPw7nvKSN4vzzRCcfSNjjwZHr5S7E9guzuqTCM5/U7QyPA2cxZC8VHUp u89Pv+yGJkcT+t+fg8VzRGHjI6btZvg9QYMGm4yZccvyHG6iQosaHE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=nl6TpNAs6UhTe/QjA5dWA6b5kUM=; b=MtyhQYKt8Atf/lrVIWJ6 E3raoS93xqT8D+/meHzLTkk8S7wT9kMAxYAe2mJAVKob8/QcTHJpZaoyBOw3DzGA 4JCJ0nBOFyeWHNIb1VPT70c0i+Nts3X4Vz/Lgucd17FiMMuqSgttwy2BQ319lyV4 4ruviPW08OMcWT1dSAp5Wuc= Received: (qmail 30228 invoked by alias); 8 Oct 2013 23:54:40 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 30216 invoked by uid 89); 8 Oct 2013 23:54:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS, T_FILL_THIS_FORM_SHORT, T_TVD_MIME_NO_HEADERS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f46.google.com Received: from mail-pa0-f46.google.com (HELO mail-pa0-f46.google.com) (209.85.220.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 08 Oct 2013 23:54:38 +0000 Received: by mail-pa0-f46.google.com with SMTP id fa1so188866pad.5 for ; Tue, 08 Oct 2013 16:54:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version:content-type; bh=MIfLi6of2VW3Xg2eUl2WgOiBAzsCeRvekta8EtPzlTs=; b=dtigsfd3pHjd45s9VCvvmg7pgcs8OQi4mQCHWJrrw/h3eY7kA/3TKzqesMVK0JBJ4Z Y0HQfzK98yTKWcbfVihs4rEs3TZzyU+Q15OecqAf890+0UFIb1zzkdKhZlZ0IG3WcM7q CPdDQLd56mOlVwYEdA5HnfkawVZ+oEmGCLi1eOIFsBWlghBwtBhbvvHJC8C7XBAuw2z0 H0I11U2W/Rsxcs0ZCXFnaUiVCbwnJGcQG8hU9a+XR8fo/Yr54GzjO+CC3VACxxBWKQo/ TctaAQDAdsGqFE5oqYtdxeFY0fDbgCgILXNjAWg7pJepaMaL3nSQryEv/vsp/HYOllBo T49g== X-Gm-Message-State: ALoCoQkUktjTta3KbICBlgmgPcWrUSIaVo8P41ryQEyEMenHWWizFK6jdSRSDck8NMRjhPhscrhSe4iwLgbtw/aQnL/jC9wmv8TT7zCg9oVb1iw7MbeUDujKm7yXZPzaLoO0jk9sD3VdW5P/EcfI91v2gsFDmuq4XHu0Q8ul1tEFEjaBwNv8tY5NgkvhDXCPvXAPTyxitAlNhKkg6UOIoyTCrCJAuPUGPg== X-Received: by 10.68.0.101 with SMTP id 5mr4686764pbd.106.1381276476080; Tue, 08 Oct 2013 16:54:36 -0700 (PDT) Received: from iant-glaptop.roam.corp.google.com.google.com ([207.198.105.20]) by mx.google.com with ESMTPSA id jj1sm42620762pbb.17.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 08 Oct 2013 16:54:35 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: Go patch committed: Error for qualified ID in struct composite lit Date: Tue, 08 Oct 2013 16:54:33 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes This patch to the Go frontend gives an error if a qualified identifier is used as a field name in a struct composite literal. This is trickier than one might expect since qualified identifiers are fine as keys in a slice or map composite literal. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 branch. Ian diff -r 29fef9fa5a41 go/expressions.cc --- a/go/expressions.cc Mon Oct 07 08:31:41 2013 -0700 +++ b/go/expressions.cc Tue Oct 08 16:48:26 2013 -0700 @@ -11293,7 +11293,7 @@ } Expression* e = Expression::make_composite_literal(array_type, 0, false, - bytes, loc); + bytes, false, loc); Variable* var = new Variable(array_type, e, true, false, false, loc); @@ -13236,9 +13236,11 @@ { public: Composite_literal_expression(Type* type, int depth, bool has_keys, - Expression_list* vals, Location location) + Expression_list* vals, bool all_are_names, + Location location) : Parser_expression(EXPRESSION_COMPOSITE_LITERAL, location), - type_(type), depth_(depth), vals_(vals), has_keys_(has_keys) + type_(type), depth_(depth), vals_(vals), has_keys_(has_keys), + all_are_names_(all_are_names) { } protected: @@ -13256,6 +13258,7 @@ (this->vals_ == NULL ? NULL : this->vals_->copy()), + this->all_are_names_, this->location()); } @@ -13285,6 +13288,9 @@ // If this is true, then VALS_ is a list of pairs: a key and a // value. In an array initializer, a missing key will be NULL. bool has_keys_; + // If this is true, then HAS_KEYS_ is true, and every key is a + // simple identifier. + bool all_are_names_; }; // Traversal. @@ -13387,6 +13393,8 @@ std::vector vals(field_count); std::vector* traverse_order = new(std::vector); Expression_list::const_iterator p = this->vals_->begin(); + Expression* external_expr = NULL; + const Named_object* external_no = NULL; while (p != this->vals_->end()) { Expression* name_expr = *p; @@ -13492,6 +13500,12 @@ if (no != NULL) { + if (no->package() != NULL && external_expr == NULL) + { + external_expr = name_expr; + external_no = no; + } + name = no->name(); // A predefined name won't be packed. If it starts with a @@ -13541,6 +13555,23 @@ traverse_order->push_back(index); } + if (!this->all_are_names_) + { + // This is a weird case like bug462 in the testsuite. + if (external_expr == NULL) + error_at(this->location(), "unknown field in %qs literal", + (type->named_type() != NULL + ? type->named_type()->message_name().c_str() + : "unnamed struct")); + else + error_at(external_expr->location(), "unknown field %qs in %qs", + external_no->message_name().c_str(), + (type->named_type() != NULL + ? type->named_type()->message_name().c_str() + : "unnamed struct")); + return Expression::make_error(location); + } + Expression_list* list = new Expression_list; list->reserve(field_count); for (size_t i = 0; i < field_count; ++i) @@ -13830,11 +13861,11 @@ Expression* Expression::make_composite_literal(Type* type, int depth, bool has_keys, - Expression_list* vals, + Expression_list* vals, bool all_are_names, Location location) { return new Composite_literal_expression(type, depth, has_keys, vals, - location); + all_are_names, location); } // Return whether this expression is a composite literal. diff -r 29fef9fa5a41 go/expressions.h --- a/go/expressions.h Mon Oct 07 08:31:41 2013 -0700 +++ b/go/expressions.h Tue Oct 08 16:48:26 2013 -0700 @@ -291,10 +291,13 @@ make_unsafe_cast(Type*, Expression*, Location); // Make a composite literal. The DEPTH parameter is how far down we - // are in a list of composite literals with omitted types. + // are in a list of composite literals with omitted types. HAS_KEYS + // is true if the expression list has keys alternating with values. + // ALL_ARE_NAMES is true if all the keys could be struct field + // names. static Expression* make_composite_literal(Type*, int depth, bool has_keys, Expression_list*, - Location); + bool all_are_names, Location); // Make a struct composite literal. static Expression* diff -r 29fef9fa5a41 go/parse.cc --- a/go/parse.cc Mon Oct 07 08:31:41 2013 -0700 +++ b/go/parse.cc Tue Oct 08 16:48:26 2013 -0700 @@ -2690,15 +2690,17 @@ { this->advance_token(); return Expression::make_composite_literal(type, depth, false, NULL, - location); + false, location); } bool has_keys = false; + bool all_are_names = true; Expression_list* vals = new Expression_list; while (true) { Expression* val; bool is_type_omitted = false; + bool is_name = false; const Token* token = this->peek_token(); @@ -2719,6 +2721,7 @@ val = this->id_to_expression(gogo->pack_hidden_name(identifier, is_exported), location); + is_name = true; } else { @@ -2744,6 +2747,7 @@ { if (has_keys) vals->push_back(NULL); + is_name = false; } else { @@ -2790,6 +2794,9 @@ vals->push_back(val); + if (!is_name) + all_are_names = false; + if (token->is_op(OPERATOR_COMMA)) { if (this->advance_token()->is_op(OPERATOR_RCURLY)) @@ -2830,7 +2837,7 @@ } return Expression::make_composite_literal(type, depth, has_keys, vals, - location); + all_are_names, location); } // FunctionLit = "func" Signature Block .