aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-05 21:16:13 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-08 10:22:12 -0800
commitf1b6e17b3f753980527721aa8e949d2481b2560b (patch)
tree1d9071fcfcbf9832e58b86f14812d4d017cdb654
parentf41dd93ade24f22f8cd1863129ab20c821000134 (diff)
downloadgcc-f1b6e17b3f753980527721aa8e949d2481b2560b.zip
gcc-f1b6e17b3f753980527721aa8e949d2481b2560b.tar.gz
gcc-f1b6e17b3f753980527721aa8e949d2481b2560b.tar.bz2
compiler: use correct location for iota errors
Also check for valid array length when reducing len/cap to a constant. For golang/go#8183 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/275654
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc91
-rw-r--r--gcc/go/gofrontend/expressions.h10
-rw-r--r--gcc/go/gofrontend/parse.cc7
4 files changed, 99 insertions, 11 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d4c8e30..619f1c0 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-3363fc239f642d3c3fb9a138d2833985d85dc083
+f4069d94a25893afc9f2fcf641359366f3ede017
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 6d484d9..79ed445 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -59,6 +59,67 @@ Expression::traverse_subexpressions(Traverse* traverse)
return this->do_traverse(traverse);
}
+// A traversal used to set the location of subexpressions.
+
+class Set_location : public Traverse
+{
+ public:
+ Set_location(Location loc)
+ : Traverse(traverse_expressions),
+ loc_(loc)
+ { }
+
+ int
+ expression(Expression** pexpr);
+
+ private:
+ Location loc_;
+};
+
+// Set the location of an expression.
+
+int
+Set_location::expression(Expression** pexpr)
+{
+ // Some expressions are shared or don't have an independent
+ // location, so we shouldn't change their location. This is the set
+ // of expressions for which do_copy is just "return this" or
+ // otherwise does not pass down the location.
+ switch ((*pexpr)->classification())
+ {
+ case Expression::EXPRESSION_ERROR:
+ case Expression::EXPRESSION_VAR_REFERENCE:
+ case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
+ case Expression::EXPRESSION_STRING:
+ case Expression::EXPRESSION_FUNC_DESCRIPTOR:
+ case Expression::EXPRESSION_TYPE:
+ case Expression::EXPRESSION_BOOLEAN:
+ case Expression::EXPRESSION_CONST_REFERENCE:
+ case Expression::EXPRESSION_NIL:
+ case Expression::EXPRESSION_TYPE_DESCRIPTOR:
+ case Expression::EXPRESSION_GC_SYMBOL:
+ case Expression::EXPRESSION_PTRMASK_SYMBOL:
+ case Expression::EXPRESSION_TYPE_INFO:
+ case Expression::EXPRESSION_STRUCT_FIELD_OFFSET:
+ return TRAVERSE_CONTINUE;
+ default:
+ break;
+ }
+
+ (*pexpr)->location_ = this->loc_;
+ return TRAVERSE_CONTINUE;
+}
+
+// Set the location of an expression and its subexpressions.
+
+void
+Expression::set_location(Location loc)
+{
+ this->location_ = loc;
+ Set_location sl(loc);
+ this->traverse_subexpressions(&sl);
+}
+
// Default implementation for do_traverse for child classes.
int
@@ -9389,6 +9450,8 @@ Builtin_call_expression::do_is_constant() const
if (arg == NULL)
return false;
Type* arg_type = arg->type();
+ if (arg_type->is_error())
+ return true;
if (arg_type->points_to() != NULL
&& arg_type->points_to()->array_type() != NULL
@@ -9460,6 +9523,8 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
if (arg == NULL)
return false;
Type* arg_type = arg->type();
+ if (arg_type->is_error())
+ return false;
if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
{
@@ -9482,17 +9547,25 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
if (this->seen_)
return false;
- Expression* e = arg_type->array_type()->length();
- this->seen_ = true;
- bool r = e->numeric_constant_value(nc);
- this->seen_ = false;
- if (r)
+
+ // We may be replacing this expression with a constant
+ // during lowering, so verify the type to report any errors.
+ // It's OK to verify an array type more than once.
+ arg_type->verify();
+ if (!arg_type->is_error())
{
- if (!nc->set_type(Type::lookup_integer_type("int"), false,
- this->location()))
- r = false;
+ Expression* e = arg_type->array_type()->length();
+ this->seen_ = true;
+ bool r = e->numeric_constant_value(nc);
+ this->seen_ = false;
+ if (r)
+ {
+ if (!nc->set_type(Type::lookup_integer_type("int"), false,
+ this->location()))
+ r = false;
+ }
+ return r;
}
- return r;
}
}
else if (this->code_ == BUILTIN_SIZEOF
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 259eeb6..712f687 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -549,6 +549,16 @@ class Expression
location() const
{ return this->location_; }
+ // Set the location of an expression and all its subexpressions.
+ // This is used for const declarations where the expression is
+ // copied from an earlier declaration.
+ void
+ set_location(Location loc);
+
+ // For set_location. This should really be a local class in
+ // Expression, but it needs types defined in gogo.h.
+ friend class Set_location;
+
// Return whether this is a constant expression.
bool
is_constant() const
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index b1925ed..a4740cf 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -1442,6 +1442,7 @@ Parse::const_decl()
void
Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list)
{
+ Location loc = this->location();
Typed_identifier_list til;
this->identifier_list(&til);
@@ -1466,7 +1467,11 @@ Parse::const_spec(int iota, Type** last_type, Expression_list** last_expr_list)
for (Expression_list::const_iterator p = (*last_expr_list)->begin();
p != (*last_expr_list)->end();
++p)
- expr_list->push_back((*p)->copy());
+ {
+ Expression* copy = (*p)->copy();
+ copy->set_location(loc);
+ expr_list->push_back(copy);
+ }
}
else
{