diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-14 18:37:11 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-14 18:37:11 +0000 |
commit | 7cd79676facfebe15f040912f35f048e6b0d0d89 (patch) | |
tree | 38a6a8e791d47a0e4f0ca6573ff2d1fefe65704a /gcc/go | |
parent | 60a16309e63839d13efd95cd33f0731b14a5d589 (diff) | |
download | gcc-7cd79676facfebe15f040912f35f048e6b0d0d89.tar.gz |
2010-12-14 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 167801
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@167808 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 25 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 17 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 3 | ||||
-rw-r--r-- | gcc/go/gospec.c | 45 |
5 files changed, 78 insertions, 17 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 380c70955f1..c98bb279db5 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2010-12-13 Ian Lance Taylor <iant@google.com> + + * gospec.c (lang_specific_driver): Add a -o option if not linking + and there is no -o option already. + 2010-12-07 Ian Lance Taylor <iant@google.com> PR tree-optimization/46805 diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 022f5ce3f0d..6320f09fc11 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -11620,24 +11620,29 @@ Type_guard_expression::do_check_types(Gogo*) this->report_error(_("invalid unsafe.Pointer conversion")); } else if (expr_type->interface_type() == NULL) - this->report_error(_("type assertion only valid for interface types")); + { + if (!expr_type->is_error_type() && !this->type_->is_error_type()) + this->report_error(_("type assertion only valid for interface types")); + this->set_is_error(); + } else if (this->type_->interface_type() == NULL) { std::string reason; if (!expr_type->interface_type()->implements_interface(this->type_, &reason)) { - if (reason.empty()) - this->report_error(_("impossible type assertion: " - "type does not implement interface")); - else + if (!this->type_->is_error_type()) { - error_at(this->location(), - ("impossible type assertion: " - "type does not implement interface (%s)"), - reason.c_str()); - this->set_is_error(); + if (reason.empty()) + this->report_error(_("impossible type assertion: " + "type does not implement interface")); + else + error_at(this->location(), + ("impossible type assertion: " + "type does not implement interface (%s)"), + reason.c_str()); } + this->set_is_error(); } } } diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index c8b55c56214..5f4cef5015d 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -2647,12 +2647,18 @@ Parse::selector(Expression* left, bool* is_type_switch) { this->advance_token(); Type* type = NULL; - if (is_type_switch == NULL - || !this->peek_token()->is_keyword(KEYWORD_TYPE)) + if (!this->peek_token()->is_keyword(KEYWORD_TYPE)) type = this->type(); else { - *is_type_switch = true; + if (is_type_switch != NULL) + *is_type_switch = true; + else + { + error_at(this->location(), + "use of %<.(type)%> outside type switch"); + type = Type::make_error_type(); + } this->advance_token(); } if (!this->peek_token()->is_op(OPERATOR_RPAREN)) @@ -2866,7 +2872,7 @@ Parse::expression(Precedence precedence, bool may_be_sink, left = this->verify_not_sink(left); Expression* right = this->expression(right_precedence, false, may_be_composite_lit, - is_type_switch); + NULL); if (op == OPERATOR_CHANOP) left = Expression::make_send(left, right, binop_location); else @@ -2959,8 +2965,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit, return Expression::make_type(this->type(), location); } - Expression* expr = this->unary_expr(false, may_be_composite_lit, - is_type_switch); + Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL); if (expr->is_error_expression()) ; else if (op == OPERATOR_MULT && expr->is_type_expression()) diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 10fe7e41c56..2d17797c9dd 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -1296,7 +1296,8 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing) Type* expr_type = this->expr_->type(); if (expr_type->interface_type() == NULL) { - this->report_error(_("type assertion only valid for interface types")); + if (!expr_type->is_error_type() && !this->type_->is_error_type()) + this->report_error(_("type assertion only valid for interface types")); return Statement::make_error_statement(loc); } diff --git a/gcc/go/gospec.c b/gcc/go/gospec.c index c8f2badb709..7d21ace46be 100644 --- a/gcc/go/gospec.c +++ b/gcc/go/gospec.c @@ -106,6 +106,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, /* The total number of arguments with the new stuff. */ int num_args = 1; + /* Whether the -o option was used. */ + bool saw_opt_o = false; + + /* The first input file with an extension of .go. */ + const char *first_go_file = NULL; + argc = *in_decoded_options_count; decoded_options = *in_decoded_options; added_libraries = *in_added_libraries; @@ -167,6 +173,10 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, library = -1; break; + case OPT_o: + saw_opt_o = true; + break; + case OPT_static: static_link = 1; break; @@ -183,6 +193,16 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, case OPT_SPECIAL_input_file: if (library == 0) library = 1; + + if (first_go_file == NULL) + { + int len; + + len = strlen (arg); + if (len > 3 && strcmp (arg + len - 3, ".go") == 0) + first_go_file = arg; + } + break; } } @@ -245,6 +265,31 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, j++; } + /* If we are not linking, add a -o option. This is because we need + the driver to pass all .go files to go1. Without a -o option the + driver will invoke go1 separately for each input file. */ + if (library < 0 && first_go_file != NULL && !saw_opt_o) + { + const char *base; + int baselen; + int alen; + char *out; + + base = lbasename (first_go_file); + baselen = strlen (base) - 3; + alen = baselen + 3; + out = XNEWVEC (char, alen); + memcpy (out, base, baselen); + /* The driver will convert .o to some other suffix if + appropriate. */ + out[baselen] = '.'; + out[baselen + 1] = 'o'; + out[baselen + 2] = '\0'; + generate_option (OPT_o, out, 1, CL_DRIVER, + &new_decoded_options[j]); + j++; + } + /* Add `-lgo' if we haven't already done so. */ if (library > 0) { |