aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-31 18:35:58 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-31 18:35:58 +0000
commit3008f0ffe9c36c60b5f08710daecb1832197c69f (patch)
treee072e4b47427a16a75f2c2ade64df7464c0bacff
parent9734500e9b7e9303e1d8bd4785cca4a82d9656af (diff)
downloadgcc-3008f0ffe9c36c60b5f08710daecb1832197c69f.zip
gcc-3008f0ffe9c36c60b5f08710daecb1832197c69f.tar.gz
gcc-3008f0ffe9c36c60b5f08710daecb1832197c69f.tar.bz2
compiler: lower expression types in lowering pass
Ensure that array types with complicated length expressions are handled correctly by lowering expression types in the lowering pass. This required some adjustment of constant expression types to not report too many errors for circular constant expressions. We now record error types in the Named_constant type. If we find the circularity due to lowering the Named_constant, we use that location for the error message; this retains the error location we used to use. Fixes golang/go#23545 Reviewed-on: https://go-review.googlesource.com/91035 From-SVN: r257250
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc13
-rw-r--r--gcc/go/gofrontend/gogo.cc18
-rw-r--r--gcc/go/gofrontend/gogo.h3
4 files changed, 34 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index bcc8136..c115b2e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-17325c96ccbee4ad6bed1cd3d9517f7dfbdf3ea7
+65eaa9003db4effc9c5ffe9c955e9534ba5d7d15
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 534b61f..c90ef8d 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -2847,8 +2847,16 @@ Const_expression::do_type()
if (this->seen_ || nc->lowering())
{
- this->report_error(_("constant refers to itself"));
+ if (nc->type() == NULL || !nc->type()->is_error_type())
+ {
+ Location loc = this->location();
+ if (!this->seen_)
+ loc = nc->location();
+ go_error_at(loc, "constant refers to itself");
+ }
+ this->set_is_error();
this->type_ = Type::make_error_type();
+ nc->set_type(this->type_);
return this->type_;
}
@@ -2868,6 +2876,9 @@ Const_expression::do_type()
this->seen_ = false;
+ if (ret->is_error_type())
+ nc->set_type(ret);
+
return ret;
}
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index f89099e..3f784dd 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -2751,6 +2751,14 @@ Lower_parse_tree::expression(Expression** pexpr)
return TRAVERSE_EXIT;
*pexpr = enew;
}
+
+ // Lower the type of this expression before the parent looks at it,
+ // in case the type contains an array that has expressions in its
+ // length. Skip an Unknown_expression, as at this point that means
+ // a composite literal key that does not have a type.
+ if ((*pexpr)->unknown_expression() == NULL)
+ Type::traverse((*pexpr)->type(), this);
+
return TRAVERSE_SKIP_COMPONENTS;
}
@@ -6855,6 +6863,16 @@ Result_variable::get_backend_variable(Gogo* gogo, Named_object* function,
// Class Named_constant.
+// Set the type of a named constant. This is only used to set the
+// type to an error type.
+
+void
+Named_constant::set_type(Type* t)
+{
+ go_assert(this->type_ == NULL || t->is_error_type());
+ this->type_ = t;
+}
+
// Traverse the initializer expression.
int
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 5135042..dfff5c1 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -2147,6 +2147,9 @@ class Named_constant
type() const
{ return this->type_; }
+ void
+ set_type(Type* t);
+
Expression*
expr() const
{ return this->expr_; }