compiler: Error if type switch case can not implement switch value.
From-SVN: r183500
This commit is contained in:
parent
5fca1e3f90
commit
d1cab3a615
|
@ -3940,7 +3940,8 @@ Type_case_clauses::Type_case_clause::traverse(Traverse* traverse)
|
||||||
// statements.
|
// statements.
|
||||||
|
|
||||||
void
|
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,
|
Temporary_statement* descriptor_temp,
|
||||||
Unnamed_label* break_label,
|
Unnamed_label* break_label,
|
||||||
Unnamed_label** stmts_label) const
|
Unnamed_label** stmts_label) const
|
||||||
|
@ -3952,6 +3953,20 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
|
||||||
{
|
{
|
||||||
Type* type = this->type_;
|
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,
|
Expression* ref = Expression::make_temporary_reference(descriptor_temp,
|
||||||
loc);
|
loc);
|
||||||
|
|
||||||
|
@ -4102,7 +4117,8 @@ Type_case_clauses::check_duplicates() const
|
||||||
// BREAK_LABEL is the label at the end of the type switch.
|
// BREAK_LABEL is the label at the end of the type switch.
|
||||||
|
|
||||||
void
|
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
|
Unnamed_label* break_label) const
|
||||||
{
|
{
|
||||||
const Type_case_clause* default_case = NULL;
|
const Type_case_clause* default_case = NULL;
|
||||||
|
@ -4113,7 +4129,8 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
|
||||||
++p)
|
++p)
|
||||||
{
|
{
|
||||||
if (!p->is_default())
|
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
|
else
|
||||||
{
|
{
|
||||||
// We are generating a series of tests, which means that we
|
// 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);
|
go_assert(stmts_label == NULL);
|
||||||
|
|
||||||
if (default_case != 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)
|
// 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)
|
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_);
|
Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
|
||||||
b->add_statement(s);
|
b->add_statement(s);
|
||||||
|
|
|
@ -1441,7 +1441,7 @@ class Type_case_clauses
|
||||||
|
|
||||||
// Lower to if and goto statements.
|
// Lower to if and goto statements.
|
||||||
void
|
void
|
||||||
lower(Block*, Temporary_statement* descriptor_temp,
|
lower(Type*, Block*, Temporary_statement* descriptor_temp,
|
||||||
Unnamed_label* break_label) const;
|
Unnamed_label* break_label) const;
|
||||||
|
|
||||||
// Dump the AST representation to a dump context.
|
// Dump the AST representation to a dump context.
|
||||||
|
@ -1485,7 +1485,7 @@ class Type_case_clauses
|
||||||
|
|
||||||
// Lower to if and goto statements.
|
// Lower to if and goto statements.
|
||||||
void
|
void
|
||||||
lower(Block*, Temporary_statement* descriptor_temp,
|
lower(Type*, Block*, Temporary_statement* descriptor_temp,
|
||||||
Unnamed_label* break_label, Unnamed_label** stmts_label) const;
|
Unnamed_label* break_label, Unnamed_label** stmts_label) const;
|
||||||
|
|
||||||
// Dump the AST representation to a dump context.
|
// Dump the AST representation to a dump context.
|
||||||
|
|
Loading…
Reference in New Issue