Chromium Code Reviews| Index: src/asmjs/asm-typer.cc | 
| diff --git a/src/asmjs/asm-typer.cc b/src/asmjs/asm-typer.cc | 
| index b265884bd0b8eb26c91f6ab30669edd25e1f2d87..ce23dc22bbe8b526eaa64224f827fb75f0a3e220 100644 | 
| --- a/src/asmjs/asm-typer.cc | 
| +++ b/src/asmjs/asm-typer.cc | 
| @@ -1225,10 +1225,12 @@ AsmType* AsmTyper::ValidateFunction(FunctionDeclaration* fun_decl) { | 
| if (as_block != nullptr) { | 
| statements = as_block->statements(); | 
| } else { | 
| - // We don't check whether AsReturnStatement() below returns non-null -- | 
| - // we leave that to the ReturnTypeAnnotations method. | 
| - RECURSE(return_type_ = | 
| - ReturnTypeAnnotations(last_statement->AsReturnStatement())); | 
| + if (auto* ret_statement = last_statement->AsReturnStatement()) { | 
| + RECURSE(return_type_ = | 
| + ReturnTypeAnnotations(ret_statement->expression())); | 
| + } else { | 
| + return_type_ = AsmType::Void(); | 
| + } | 
| } | 
| } | 
| } while (return_type_ == AsmType::None()); | 
| @@ -2747,15 +2749,8 @@ AsmType* AsmTyper::ParameterTypeAnnotations(Variable* parameter, | 
| } | 
| // 5.2 ReturnTypeAnnotations | 
| -AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) { | 
| - if (statement == nullptr) { | 
| - return AsmType::Void(); | 
| - } | 
| - | 
| - auto* ret_expr = statement->expression(); | 
| - if (ret_expr == nullptr) { | 
| - return AsmType::Void(); | 
| - } | 
| +AsmType* AsmTyper::ReturnTypeAnnotations(Expression* ret_expr) { | 
| + DCHECK_NOT_NULL(ret_expr); | 
| if (auto* binop = ret_expr->AsBinaryOperation()) { | 
| if (IsDoubleAnnotation(binop)) { | 
| @@ -2763,14 +2758,14 @@ AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) { | 
| } else if (IsIntAnnotation(binop)) { | 
| return AsmType::Signed(); | 
| } | 
| - FAIL(statement, "Invalid return type annotation."); | 
| + FAIL(ret_expr, "Invalid return type annotation."); | 
| } | 
| if (auto* call = ret_expr->AsCall()) { | 
| if (IsCallToFround(call)) { | 
| return AsmType::Float(); | 
| } | 
| - FAIL(statement, "Invalid function call in return statement."); | 
| + FAIL(ret_expr, "Invalid function call in return statement."); | 
| } | 
| if (auto* literal = ret_expr->AsLiteral()) { | 
| @@ -2789,28 +2784,46 @@ AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) { | 
| // return undefined | 
| return AsmType::Void(); | 
| } | 
| - FAIL(statement, "Invalid literal in return statement."); | 
| + FAIL(ret_expr, "Invalid literal in return statement."); | 
| } | 
| if (auto* proxy = ret_expr->AsVariableProxy()) { | 
| auto* var_info = Lookup(proxy->var()); | 
| if (var_info == nullptr) { | 
| - FAIL(statement, "Undeclared identifier in return statement."); | 
| + FAIL(ret_expr, "Undeclared identifier in return statement."); | 
| } | 
| if (var_info->mutability() != VariableInfo::kConstGlobal) { | 
| - FAIL(statement, "Identifier in return statement is not const."); | 
| + FAIL(ret_expr, "Identifier in return statement is not const."); | 
| } | 
| if (!var_info->type()->IsReturnType()) { | 
| - FAIL(statement, "Constant in return must be signed, float, or double."); | 
| + FAIL(ret_expr, "Constant in return must be signed, float, or double."); | 
| } | 
| return var_info->type(); | 
| } | 
| - FAIL(statement, "Invalid return type expression."); | 
| + // NOTE: This is not strictly valid asm.js, but is emitted by some versions of | 
| + // Emscipten. | 
| 
 
Mircea Trofin
2017/01/26 07:47:27
Emscripten
 
bradn
2017/01/26 07:50:42
Done.
 
 | 
| + if (auto* cond = ret_expr->AsConditional()) { | 
| + AsmType* a; | 
| 
 
Mircea Trofin
2017/01/26 07:47:27
init a and b?
 
bradn
2017/01/26 07:50:42
Done.
 
 | 
| + AsmType* b; | 
| + RECURSE(a = ReturnTypeAnnotations(cond->then_expression())); | 
| + if (a->IsA(AsmType::None())) { | 
| + return a; | 
| + } | 
| + RECURSE(b = ReturnTypeAnnotations(cond->else_expression())); | 
| + if (b->IsA(AsmType::None())) { | 
| + return b; | 
| + } | 
| + if (a->IsExactly(b)) { | 
| + return a; | 
| + } | 
| + } | 
| + | 
| + FAIL(ret_expr, "Invalid return type expression."); | 
| } | 
| // 5.4 VariableTypeAnnotations |