aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-12-28 03:46:20 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-12-28 03:46:20 +0000
commit1358551fc61841e7a78b6f04919d96a54dc24bd1 (patch)
tree0620cac8fee9b74e18be59d7bcc70a0982606b41 /gcc/go
parent9437ab32a5b5d62b625680eaca90b189f8728ec5 (diff)
downloadgcc-1358551fc61841e7a78b6f04919d96a54dc24bd1.zip
gcc-1358551fc61841e7a78b6f04919d96a54dc24bd1.tar.gz
gcc-1358551fc61841e7a78b6f04919d96a54dc24bd1.tar.bz2
compiler: Prohibit comparisons of funcs, maps, and slices to non-nil.
From-SVN: r182703
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/expressions.cc19
-rw-r--r--gcc/go/gofrontend/expressions.h4
-rw-r--r--gcc/go/gofrontend/types.cc8
3 files changed, 23 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 3c75f8a..dfe9b51 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -6052,11 +6052,11 @@ Binary_expression::do_determine_type(const Type_context* context)
}
// Report an error if the binary operator OP does not support TYPE.
-// Return whether the operation is OK. This should not be used for
-// shift.
+// OTYPE is the type of the other operand. Return whether the
+// operation is OK. This should not be used for shift.
bool
-Binary_expression::check_operator_type(Operator op, Type* type,
+Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
Location location)
{
switch (op)
@@ -6092,6 +6092,16 @@ Binary_expression::check_operator_type(Operator op, Type* type,
"or function type"));
return false;
}
+ if ((type->is_slice_type()
+ || type->map_type() != NULL
+ || type->function_type() != NULL)
+ && !otype->is_nil_type())
+ {
+ error_at(location,
+ ("slice, map, and function types may only "
+ "be compared to nil"));
+ return false;
+ }
break;
case OPERATOR_LT:
@@ -6189,8 +6199,10 @@ Binary_expression::do_check_types(Gogo*)
return;
}
if (!Binary_expression::check_operator_type(this->op_, left_type,
+ right_type,
this->location())
|| !Binary_expression::check_operator_type(this->op_, right_type,
+ left_type,
this->location()))
{
this->set_is_error();
@@ -6205,6 +6217,7 @@ Binary_expression::do_check_types(Gogo*)
return;
}
if (!Binary_expression::check_operator_type(this->op_, left_type,
+ right_type,
this->location()))
{
this->set_is_error();
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 6da507b..4e06b24 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -1147,9 +1147,9 @@ class Binary_expression : public Expression
do_import(Import*);
// Report an error if OP can not be applied to TYPE. Return whether
- // it can.
+ // it can. OTYPE is the type of the other operand.
static bool
- check_operator_type(Operator op, Type* type, Location);
+ check_operator_type(Operator op, Type* type, Type* otype, Location);
protected:
int
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 45545df..d1901e1 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1235,8 +1235,6 @@ Type::type_functions(const char** hash_fn, const char** equal_fn) const
case Type::TYPE_FLOAT:
case Type::TYPE_COMPLEX:
case Type::TYPE_POINTER:
- case Type::TYPE_FUNCTION:
- case Type::TYPE_MAP:
case Type::TYPE_CHANNEL:
*hash_fn = "__go_type_hash_identity";
*equal_fn = "__go_type_equal_identity";
@@ -1249,6 +1247,8 @@ Type::type_functions(const char** hash_fn, const char** equal_fn) const
case Type::TYPE_STRUCT:
case Type::TYPE_ARRAY:
+ case Type::TYPE_FUNCTION:
+ case Type::TYPE_MAP:
// These types can not be hashed or compared.
*hash_fn = "__go_type_hash_error";
*equal_fn = "__go_type_equal_error";
@@ -4731,7 +4731,9 @@ bool
Map_type::do_verify()
{
if (this->key_type_->struct_type() != NULL
- || this->key_type_->array_type() != NULL)
+ || this->key_type_->array_type() != NULL
+ || this->key_type_->function_type() != NULL
+ || this->key_type_->map_type() != NULL)
{
error_at(this->location_, "invalid map key type");
return false;