This patch to the Go frontend changes it to not cast an index expression to int before checking whether the value is in bounds. This fixes PR 61866: on a 32-bit system, casting an int64 index to int drops the upper 32 bits of the value, and thus can cause an out-of-range index to appear to be in range. This undoes part of change 1318:fa6e0c716dba (https://codereview.appspot.com/104610044) and therefore breaks PR 61308 again. I have a separate patch for that, coming soon (http://codereview.appspot.com/122020043). In addition to undoing part of that change, this patch adds code to avoid a compiler crash. This changes PR 61308 from a compiler crash to an incorrect error message.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian
diff -r 8263b1ea5ea9 go/expressions.cc --- a/go/expressions.cc Mon Aug 04 10:53:47 2014 -0700 +++ b/go/expressions.cc Mon Aug 04 17:20:19 2014 -0700 @@ -3620,6 +3620,16 @@ return Expression::make_error(this->location()); } + // Check for an invalid pointer dereference. We need to do this + // here because Unary_expression::do_type will return an error type + // in this case. That can cause code to appear erroneous, and + // therefore disappear at lowering time, without any error message. + if (op == OPERATOR_MULT && expr->type()->points_to() == NULL) + { + this->report_error(_("expected pointer")); + return Expression::make_error(this->location()); + } + if (op == OPERATOR_PLUS || op == OPERATOR_MINUS || op == OPERATOR_XOR) { Numeric_constant nc; @@ -9811,7 +9821,10 @@ Type* type = left->type(); if (type->is_error()) - return Expression::make_error(location); + { + go_assert(saw_errors()); + return Expression::make_error(location); + } else if (left->is_type_expression()) { error_at(location, "attempt to index type expression"); @@ -10298,9 +10311,9 @@ go_assert(saw_errors()); return context->backend()->error_expression(); } - Expression* start_expr = Expression::make_cast(int_type, this->start_, loc); + Bexpression* bad_index = - Expression::check_bounds(start_expr, loc)->get_backend(context); + Expression::check_bounds(this->start_, loc)->get_backend(context); Bexpression* start = this->start_->get_backend(context); start = gogo->backend()->convert_expression(int_btype, start, loc);