diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index d93ebbd1c..2914472af 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -961,7 +961,8 @@ void TypeChecker::endVisit(EmitStatement const& _emit) _emit.eventCall().annotation().kind != FunctionCallKind::FunctionCall || dynamic_cast(*type(_emit.eventCall().expression())).kind() != FunctionType::Kind::Event ) - m_errorReporter.typeError(_emit.eventCall().expression().location(), "Expression has to be an event."); + m_errorReporter.typeError(_emit.eventCall().expression().location(), "Expression has to be an event invocation."); + m_insideEmitStatement = false; } bool TypeChecker::visit(VariableDeclarationStatement const& _statement) @@ -1540,6 +1541,13 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) else if (functionName->name() == "suicide" && functionType->kind() == FunctionType::Kind::Selfdestruct) m_errorReporter.warning(_functionCall.location(), "\"suicide\" has been deprecated in favour of \"selfdestruct\""); } + if (!m_insideEmitStatement && functionType->kind() == FunctionType::Kind::Event) + { + if (m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + m_errorReporter.typeError(_functionCall.location(), "Event invocations have to be prefixed by \"emit\"."); + else + m_errorReporter.warning(_functionCall.location(), "Invoking events without \"emit\" prefix is deprecated."); + } TypePointers parameterTypes = functionType->parameterTypes(); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index fc4ec6f06..16796b63f 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -94,6 +94,7 @@ private: virtual bool visit(WhileStatement const& _whileStatement) override; virtual bool visit(ForStatement const& _forStatement) override; virtual void endVisit(Return const& _return) override; + virtual bool visit(EmitStatement const&) override { m_insideEmitStatement = true; return true; } virtual void endVisit(EmitStatement const& _emit) override; virtual bool visit(VariableDeclarationStatement const& _variable) override; virtual void endVisit(ExpressionStatement const& _statement) override; @@ -131,6 +132,9 @@ private: ContractDefinition const* m_scope = nullptr; + /// Flag indicating whether we are currently inside an EmitStatement. + bool m_insideEmitStatement = false; + ErrorReporter& m_errorReporter; };