diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-06-25 16:34:28 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-06-25 16:34:28 +0000 |
commit | 69d8df443906f77be079de8c9bb2c52da69351a2 (patch) | |
tree | edc9cac0bb05376c0ed0a909eb2eb4608140892a /gcc | |
parent | 7292300cda0d1457baa43ef5e65fb6a7cabd25c9 (diff) | |
download | gcc-69d8df443906f77be079de8c9bb2c52da69351a2.zip gcc-69d8df443906f77be079de8c9bb2c52da69351a2.tar.gz gcc-69d8df443906f77be079de8c9bb2c52da69351a2.tar.bz2 |
compiler: Fix type determination issues.
From-SVN: r200398
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 20 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 5 |
2 files changed, 22 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 1e40882..9085a46 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -5668,6 +5668,7 @@ Binary_expression::do_determine_type(const Type_context* context) if (tleft->is_abstract() && subcontext.type != NULL && !subcontext.may_be_abstract + && subcontext.type->interface_type() == NULL && subcontext.type->integer_type() == NULL) this->report_error(("invalid context-determined non-integer type " "for left operand of shift")); @@ -7383,6 +7384,8 @@ Builtin_call_expression::lower_make() Type* uintptr_type = Type::lookup_integer_type("uintptr"); int uintptr_bits = uintptr_type->integer_type()->bits(); + Type_context int_context(Type::lookup_integer_type("int"), false); + ++parg; Expression* len_arg; if (parg == args->end()) @@ -7401,6 +7404,7 @@ Builtin_call_expression::lower_make() else { len_arg = *parg; + len_arg->determine_type(&int_context); if (!this->check_int_value(len_arg, true)) return Expression::make_error(this->location()); if (len_arg->type()->integer_type() != NULL @@ -7413,6 +7417,7 @@ Builtin_call_expression::lower_make() if (is_slice && parg != args->end()) { cap_arg = *parg; + cap_arg->determine_type(&int_context); if (!this->check_int_value(cap_arg, false)) return Expression::make_error(this->location()); @@ -8030,6 +8035,8 @@ Builtin_call_expression::do_determine_type(const Type_context* context) case BUILTIN_REAL: case BUILTIN_IMAG: arg_type = Builtin_call_expression::complex_type(context->type); + if (arg_type == NULL) + arg_type = Type::lookup_complex_type("complex128"); is_print = false; break; @@ -8038,6 +8045,8 @@ Builtin_call_expression::do_determine_type(const Type_context* context) // For the complex function the type of one operand can // determine the type of the other, as in a binary expression. arg_type = Builtin_call_expression::real_imag_type(context->type); + if (arg_type == NULL) + arg_type = Type::lookup_float_type("float64"); if (args != NULL && args->size() == 2) { Type* t1 = args->front()->type(); @@ -10379,13 +10388,20 @@ Array_index_expression::do_determine_type(const Type_context*) void Array_index_expression::do_check_types(Gogo*) { - if (this->start_->type()->integer_type() == NULL) + Numeric_constant nc; + unsigned long v; + if (this->start_->type()->integer_type() == NULL + && !this->start_->type()->is_error() + && (!this->start_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("index must be integer")); if (this->end_ != NULL && this->end_->type()->integer_type() == NULL && !this->end_->type()->is_error() && !this->end_->is_nil_expression() - && !this->end_->is_error_expression()) + && !this->end_->is_error_expression() + && (!this->end_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("slice end must be integer")); Array_type* array_type = this->array_->type()->array_type(); diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 880d5c8..ca1ad07 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -569,7 +569,10 @@ void Assignment_statement::do_determine_types() { this->lhs_->determine_type_no_context(); - Type_context context(this->lhs_->type(), false); + Type* rhs_context_type = this->lhs_->type(); + if (rhs_context_type->is_sink_type()) + rhs_context_type = NULL; + Type_context context(rhs_context_type, false); this->rhs_->determine_type(&context); } |