compiler: Error if type switch case can not implement switch value.

From-SVN: r183500
This commit is contained in:
Ian Lance Taylor 2012-01-24 23:26:20 +00:00
parent 5fca1e3f90
commit d1cab3a615
2 changed files with 25 additions and 7 deletions

View File

@ -3940,7 +3940,8 @@ Type_case_clauses::Type_case_clause::traverse(Traverse* traverse)
// statements.
void
Type_case_clauses::Type_case_clause::lower(Block* b,
Type_case_clauses::Type_case_clause::lower(Type* switch_val_type,
Block* b,
Temporary_statement* descriptor_temp,
Unnamed_label* break_label,
Unnamed_label** stmts_label) const
@ -3952,6 +3953,20 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
{
Type* type = this->type_;
std::string reason;
if (switch_val_type->interface_type() != NULL
&& !type->is_nil_constant_as_type()
&& type->interface_type() == NULL
&& !switch_val_type->interface_type()->implements_interface(type,
&reason))
{
if (reason.empty())
error_at(this->location_, "impossible type switch case");
else
error_at(this->location_, "impossible type switch case (%s)",
reason.c_str());
}
Expression* ref = Expression::make_temporary_reference(descriptor_temp,
loc);
@ -4102,7 +4117,8 @@ Type_case_clauses::check_duplicates() const
// BREAK_LABEL is the label at the end of the type switch.
void
Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
Type_case_clauses::lower(Type* switch_val_type, Block* b,
Temporary_statement* descriptor_temp,
Unnamed_label* break_label) const
{
const Type_case_clause* default_case = NULL;
@ -4113,7 +4129,8 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
++p)
{
if (!p->is_default())
p->lower(b, descriptor_temp, break_label, &stmts_label);
p->lower(switch_val_type, b, descriptor_temp, break_label,
&stmts_label);
else
{
// We are generating a series of tests, which means that we
@ -4124,7 +4141,8 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
go_assert(stmts_label == NULL);
if (default_case != NULL)
default_case->lower(b, descriptor_temp, break_label, NULL);
default_case->lower(switch_val_type, b, descriptor_temp, break_label,
NULL);
}
// Dump the AST representation for case clauses (from a switch statement)
@ -4222,7 +4240,7 @@ Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
}
if (this->clauses_ != NULL)
this->clauses_->lower(b, descriptor_temp, this->break_label());
this->clauses_->lower(val_type, b, descriptor_temp, this->break_label());
Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
b->add_statement(s);

View File

@ -1441,7 +1441,7 @@ class Type_case_clauses
// Lower to if and goto statements.
void
lower(Block*, Temporary_statement* descriptor_temp,
lower(Type*, Block*, Temporary_statement* descriptor_temp,
Unnamed_label* break_label) const;
// Dump the AST representation to a dump context.
@ -1485,7 +1485,7 @@ class Type_case_clauses
// Lower to if and goto statements.
void
lower(Block*, Temporary_statement* descriptor_temp,
lower(Type*, Block*, Temporary_statement* descriptor_temp,
Unnamed_label* break_label, Unnamed_label** stmts_label) const;
// Dump the AST representation to a dump context.