diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-04 05:17:54 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-04 05:17:54 +0000 |
commit | 4f2138d7c4a565dd82d92953535d07742feeb993 (patch) | |
tree | fc45f7b721523284e00758f9174c0e8d2878b20d /gcc/go | |
parent | 55dcfde90c2dc80a5832596aef876844b876f3dd (diff) | |
download | gcc-4f2138d7c4a565dd82d92953535d07742feeb993.tar.gz |
compiler: Fix crash in go/defer of some builtin functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194114 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 30 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 19 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 16 |
3 files changed, 38 insertions, 27 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index a2a76d9ce30..bfc1b625d71 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -80,10 +80,11 @@ Expression::do_traverse(Traverse*) // expression is being discarded. By default, we give an error. // Expressions with side effects override. -void +bool Expression::do_discarding_value() { this->unused_value_error(); + return false; } // This virtual function is called to export expressions. This will @@ -100,7 +101,7 @@ Expression::do_export(Export*) const void Expression::unused_value_error() { - error_at(this->location(), "value computed is not used"); + this->report_error(_("value computed is not used")); } // Note that this expression is an error. This is called by children @@ -786,9 +787,9 @@ class Error_expression : public Expression return true; } - void + bool do_discarding_value() - { } + { return true; } Type* do_type() @@ -1149,9 +1150,9 @@ class Sink_expression : public Expression { } protected: - void + bool do_discarding_value() - { } + { return true; } Type* do_type(); @@ -5326,13 +5327,16 @@ Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const // Note that the value is being discarded. -void +bool Binary_expression::do_discarding_value() { if (this->op_ == OPERATOR_OROR || this->op_ == OPERATOR_ANDAND) - this->right_->discarding_value(); + return this->right_->discarding_value(); else - this->unused_value_error(); + { + this->unused_value_error(); + return false; + } } // Get type. @@ -6536,7 +6540,7 @@ class Builtin_call_expression : public Call_expression bool do_numeric_constant_value(Numeric_constant*) const; - void + bool do_discarding_value(); Type* @@ -7338,7 +7342,7 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const // discarding the value of an ordinary function call, but we do for // builtin functions, purely for consistency with the gc compiler. -void +bool Builtin_call_expression::do_discarding_value() { switch (this->code_) @@ -7359,7 +7363,7 @@ Builtin_call_expression::do_discarding_value() case BUILTIN_OFFSETOF: case BUILTIN_SIZEOF: this->unused_value_error(); - break; + return false; case BUILTIN_CLOSE: case BUILTIN_COPY: @@ -7368,7 +7372,7 @@ Builtin_call_expression::do_discarding_value() case BUILTIN_PRINT: case BUILTIN_PRINTLN: case BUILTIN_RECOVER: - break; + return true; } } diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index eb4406dc9eb..66e05a7bcfd 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -360,10 +360,11 @@ class Expression // This is called if the value of this expression is being // discarded. This issues warnings about computed values being - // unused. - void + // unused. This returns true if all is well, false if it issued an + // error message. + bool discarding_value() - { this->do_discarding_value(); } + { return this->do_discarding_value(); } // Return whether this is an error expression. bool @@ -689,7 +690,7 @@ class Expression { return false; } // Called by the parser if the value is being discarded. - virtual void + virtual bool do_discarding_value(); // Child class holds type. @@ -1205,7 +1206,7 @@ class Binary_expression : public Expression bool do_numeric_constant_value(Numeric_constant*) const; - void + bool do_discarding_value(); Type* @@ -1373,9 +1374,9 @@ class Call_expression : public Expression virtual Expression* do_lower(Gogo*, Named_object*, Statement_inserter*, int); - void + bool do_discarding_value() - { } + { return true; } virtual Type* do_type(); @@ -2056,9 +2057,9 @@ class Receive_expression : public Expression do_traverse(Traverse* traverse) { return Expression::traverse(&this->channel_, traverse); } - void + bool do_discarding_value() - { } + { return true; } Type* do_type(); diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index ad249f6ac57..fb1322f42f3 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -2006,6 +2006,8 @@ Thunk_statement::do_determine_types() void Thunk_statement::do_check_types(Gogo*) { + if (!this->call_->discarding_value()) + return; Call_expression* ce = this->call_->call_expression(); if (ce == NULL) { @@ -2471,11 +2473,15 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name) Expression_statement* es = static_cast<Expression_statement*>(call_statement); Call_expression* ce = es->expr()->call_expression(); - go_assert(ce != NULL); - if (may_call_recover) - ce->set_is_deferred(); - if (recover_arg != NULL) - ce->set_recover_arg(recover_arg); + if (ce == NULL) + go_assert(saw_errors()); + else + { + if (may_call_recover) + ce->set_is_deferred(); + if (recover_arg != NULL) + ce->set_recover_arg(recover_arg); + } } // That is all the thunk has to do. |