summaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-14 17:54:08 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-14 17:54:08 +0000
commitc999c2a78bd5898cbc73b3a3402d5fbb6004e6a1 (patch)
tree2c86b3223c4eba8a77141ab30c23d32233a1007f /gcc/go
parent10340a85d4123d57db461ddf4de3b8c6a3a72713 (diff)
downloadgcc-c999c2a78bd5898cbc73b3a3402d5fbb6004e6a1.tar.gz
compiler: Ignore result context in constant expressions.
When evaluating a constant expression, the gofrontend would incorrectly force each operand to be represented as the resulting type before checking if the operation was valid with the untyped constants. According to the language specification on constant expressions(http://golang.org/ref/spec#Constant_expressions): "Untyped boolean, numeric, and string constants may be used as operands wherever it is legal to use an operand of boolean, numeric, or string type, respectively." Fixes golang/go#11566. Reviewed-on: https://go-review.googlesource.com/12716 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227758 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc29
2 files changed, 19 insertions, 12 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ef21b544a5f..cc7db664265 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-aea4360ca9c37f8e929f177ae7e42593ee62aa79
+1d9d92ab09996d2f7795481d2876a21194502b89
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 dc37cf0b01e..488c76ca6bc 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -5307,6 +5307,14 @@ Binary_expression::do_determine_type(const Type_context* context)
|| this->op_ == OPERATOR_GT
|| this->op_ == OPERATOR_GE);
+ // For constant expressions, the context of the result is not useful in
+ // determining the types of the operands. It is only legal to use abstract
+ // boolean, numeric, and string constants as operands where it is legal to
+ // use non-abstract boolean, numeric, and string constants, respectively.
+ // Any issues with the operation will be resolved in the check_types pass.
+ bool is_constant_expr = (this->left_->is_constant()
+ && this->right_->is_constant());
+
Type_context subcontext(*context);
if (is_comparison)
@@ -5351,7 +5359,8 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.type = subcontext.type->make_non_abstract_type();
}
- this->left_->determine_type(&subcontext);
+ if (!is_constant_expr)
+ this->left_->determine_type(&subcontext);
if (is_shift_op)
{
@@ -5371,7 +5380,8 @@ Binary_expression::do_determine_type(const Type_context* context)
subcontext.may_be_abstract = false;
}
- this->right_->determine_type(&subcontext);
+ if (!is_constant_expr)
+ this->right_->determine_type(&subcontext);
if (is_comparison)
{
@@ -5396,7 +5406,8 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
{
case OPERATOR_OROR:
case OPERATOR_ANDAND:
- if (!type->is_boolean_type())
+ if (!type->is_boolean_type()
+ || !otype->is_boolean_type())
{
error_at(location, "expected boolean type");
return false;
@@ -5431,10 +5442,8 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
case OPERATOR_PLUS:
case OPERATOR_PLUSEQ:
- if (type->integer_type() == NULL
- && type->float_type() == NULL
- && type->complex_type() == NULL
- && !type->is_string_type())
+ if ((!type->is_numeric_type() && !type->is_string_type())
+ || (!otype->is_numeric_type() && !otype->is_string_type()))
{
error_at(location,
"expected integer, floating, complex, or string type");
@@ -5448,9 +5457,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
case OPERATOR_MULTEQ:
case OPERATOR_DIV:
case OPERATOR_DIVEQ:
- if (type->integer_type() == NULL
- && type->float_type() == NULL
- && type->complex_type() == NULL)
+ if (!type->is_numeric_type() || !otype->is_numeric_type())
{
error_at(location, "expected integer, floating, or complex type");
return false;
@@ -5467,7 +5474,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
case OPERATOR_XOREQ:
case OPERATOR_BITCLEAR:
case OPERATOR_BITCLEAREQ:
- if (type->integer_type() == NULL)
+ if (type->integer_type() == NULL || otype->integer_type() == NULL)
{
error_at(location, "expected integer type");
return false;