OSDN Git Service

compiler: Reject type switch using non-interface type.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Aug 2012 04:09:31 +0000 (04:09 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Aug 2012 04:09:31 +0000 (04:09 +0000)
Fixes issue 16.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@190311 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/gofrontend/statements.cc

index 7f91e55..fa7f208 100644 (file)
@@ -4192,55 +4192,41 @@ Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                    ? this->var_->var_value()->type()
                    : this->expr_->type());
 
+  if (val_type->interface_type() == NULL)
+    {
+      if (!val_type->is_error())
+       this->report_error(_("cannot type switch on non-interface value"));
+      return Statement::make_error_statement(loc);
+    }
+
   // var descriptor_temp DESCRIPTOR_TYPE
   Type* descriptor_type = Type::make_type_descriptor_ptr_type();
   Temporary_statement* descriptor_temp =
     Statement::make_temporary(descriptor_type, NULL, loc);
   b->add_statement(descriptor_temp);
 
-  if (val_type->interface_type() == NULL)
-    {
-      // Doing a type switch on a non-interface type.  Should we issue
-      // a warning for this case?
-      Expression* lhs = Expression::make_temporary_reference(descriptor_temp,
-                                                            loc);
-      Expression* rhs;
-      if (val_type->is_nil_type())
-       rhs = Expression::make_nil(loc);
-      else
-       {
-         if (val_type->is_abstract())
-           val_type = val_type->make_non_abstract_type();
-         rhs = Expression::make_type_descriptor(val_type, loc);
-       }
-      Statement* s = Statement::make_assignment(lhs, rhs, loc);
-      b->add_statement(s);
-    }
+  // descriptor_temp = ifacetype(val_temp) FIXME: This should be
+  // inlined.
+  bool is_empty = val_type->interface_type()->is_empty();
+  Expression* ref;
+  if (this->var_ == NULL)
+    ref = this->expr_;
   else
-    {
-      // descriptor_temp = ifacetype(val_temp)
-      // FIXME: This should be inlined.
-      bool is_empty = val_type->interface_type()->is_empty();
-      Expression* ref;
-      if (this->var_ == NULL)
-       ref = this->expr_;
-      else
-       ref = Expression::make_var_reference(this->var_, loc);
-      Expression* call = Runtime::make_call((is_empty
-                                            ? Runtime::EFACETYPE
-                                            : Runtime::IFACETYPE),
-                                           loc, 1, ref);
-      Temporary_reference_expression* lhs =
-       Expression::make_temporary_reference(descriptor_temp, loc);
-      lhs->set_is_lvalue();
-      Statement* s = Statement::make_assignment(lhs, call, loc);
-      b->add_statement(s);
-    }
+    ref = Expression::make_var_reference(this->var_, loc);
+  Expression* call = Runtime::make_call((is_empty
+                                        ? Runtime::EFACETYPE
+                                        : Runtime::IFACETYPE),
+                                       loc, 1, ref);
+  Temporary_reference_expression* lhs =
+    Expression::make_temporary_reference(descriptor_temp, loc);
+  lhs->set_is_lvalue();
+  Statement* s = Statement::make_assignment(lhs, call, loc);
+  b->add_statement(s);
 
   if (this->clauses_ != NULL)
     this->clauses_->lower(val_type, b, descriptor_temp, this->break_label());
 
-  Statement* s = Statement::make_unnamed_label_statement(this->break_label_);
+  s = Statement::make_unnamed_label_statement(this->break_label_);
   b->add_statement(s);
 
   return Statement::make_block_statement(b, loc);