diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-12-28 03:46:20 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-12-28 03:46:20 +0000 |
commit | 1358551fc61841e7a78b6f04919d96a54dc24bd1 (patch) | |
tree | 0620cac8fee9b74e18be59d7bcc70a0982606b41 /gcc/go | |
parent | 9437ab32a5b5d62b625680eaca90b189f8728ec5 (diff) | |
download | gcc-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.cc | 19 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 8 |
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; |