Inline assembly without memory effects is implicitly memory safe.

This commit is contained in:
Daniel Kirchner
2022-03-02 16:42:28 +01:00
parent e6848caac1
commit 9bcfcc61a7
6 changed files with 18 additions and 5 deletions
+1 -1
View File
@@ -202,7 +202,7 @@ bool DocStringTagParser::visit(InlineAssembly const& _assembly)
if (valuesSeen.insert(value).second)
{
if (value == "memory-safe-assembly")
_assembly.annotation().memorySafe = true;
_assembly.annotation().markedMemorySafe = true;
else
m_errorReporter.warning(
8787_error,
+8 -2
View File
@@ -763,6 +763,7 @@ void TypeChecker::endVisit(FunctionTypeName const& _funType)
bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
bool lvalueAccessToMemoryVariable = false;
// External references have already been resolved in a prior stage and stored in the annotation.
// We run the resolve step again regardless.
yul::ExternalIdentifierAccess::Resolver identifierAccess = [&](
@@ -787,6 +788,8 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (auto var = dynamic_cast<VariableDeclaration const*>(declaration))
{
solAssert(var->type(), "Expected variable type!");
if (_context == yul::IdentifierContext::LValue && var->type()->dataStoredIn(DataLocation::Memory))
lvalueAccessToMemoryVariable = true;
if (var->immutable())
{
m_errorReporter.typeError(3773_error, nativeLocationOf(_identifier), "Assembly access to immutable variables is not supported.");
@@ -974,8 +977,11 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
identifierAccess
);
if (!analyzer.analyze(_inlineAssembly.operations()))
return false;
return true;
solAssert(m_errorReporter.hasErrors());
_inlineAssembly.annotation().hasMemoryEffects =
lvalueAccessToMemoryVariable ||
(analyzer.sideEffects().memory != yul::SideEffects::None);
return false;
}
bool TypeChecker::visit(IfStatement const& _ifStatement)
+3 -1
View File
@@ -221,7 +221,9 @@ struct InlineAssemblyAnnotation: StatementAnnotation
/// Information generated during analysis phase.
std::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
/// True, if the assembly block was annotated to be memory-safe.
bool memorySafe = false;
bool markedMemorySafe = false;
/// True, if the assembly block involves any memory opcode or assigns to variables in memory.
SetOnce<bool> hasMemoryEffects;
};
struct BlockAnnotation: StatementAnnotation, ScopableAnnotation
@@ -2138,7 +2138,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
{
setLocation(_inlineAsm);
if (!_inlineAsm.annotation().memorySafe)
if (*_inlineAsm.annotation().hasMemoryEffects && !_inlineAsm.annotation().markedMemorySafe)
m_context.setMemoryUnsafeInlineAssemblySeen();
CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences};