diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 0b69d5d9887feecdfa1aa4983e13de60221838ed..4e5bd44783157606f0a03ee085133bfca758fd4e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -3133,7 +3133,8 @@ Check_return_statements_traverse::function(Named_object* no) return TRAVERSE_CONTINUE; if (func->block()->may_fall_through()) - error_at(func->location(), "control reaches end of non-void function"); + error_at(func->block()->end_location(), + "missing return at end of function"); return TRAVERSE_CONTINUE; } diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index ca1ad07af6cb8f9059522daf9efe730ee3748c1a..7314918a9a16e2516e7f41f18f89ba6ae47e79eb 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -4093,6 +4093,16 @@ Type_case_clauses::Type_case_clause::lower(Type* switch_val_type, bool Type_case_clauses::Type_case_clause::may_fall_through() const { + if (this->is_fallthrough_) + { + // This case means that we automatically fall through to the + // next case (it's used for T1 in case T1, T2:). It does not + // mean that we fall through to the end of the type switch as a + // whole. There is sure to be a next case and that next case + // will determine whether we fall through to the statements + // after the type switch. + return false; + } if (this->statements_ == NULL) return true; return this->statements_->may_fall_through(); diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug086.go b/gcc/testsuite/go.test/test/fixedbugs/bug086.go index fc69e0e3fc7a34cdc20b04993032d0de767bc97d..40d236206696005965e94ea3353912763e287a90 100644 --- a/gcc/testsuite/go.test/test/fixedbugs/bug086.go +++ b/gcc/testsuite/go.test/test/fixedbugs/bug086.go @@ -6,12 +6,12 @@ package main -func f() int { // ERROR "return|control" +func f() int { if false { return 0; } // we should not be able to return successfully w/o a return statement -} +} // ERROR "return" func main() { print(f(), "\n");