mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include <liblangutil/Common.h>
|
||||
|
||||
#include <range/v3/algorithm/any_of.hpp>
|
||||
#include <range/v3/view/filter.hpp>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@@ -162,6 +163,81 @@ bool DocStringTagParser::visit(ErrorDefinition const& _error)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DocStringTagParser::visit(InlineAssembly const& _assembly)
|
||||
{
|
||||
if (!_assembly.documentation())
|
||||
return true;
|
||||
StructuredDocumentation documentation{-1, _assembly.location(), _assembly.documentation()};
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter{errors};
|
||||
auto docTags = DocStringParser{documentation, errorReporter}.parse();
|
||||
|
||||
if (!errors.empty())
|
||||
{
|
||||
SecondarySourceLocation ssl;
|
||||
for (auto const& error: errors)
|
||||
if (error->comment())
|
||||
ssl.append(
|
||||
*error->comment(),
|
||||
_assembly.location()
|
||||
);
|
||||
m_errorReporter.warning(
|
||||
7828_error,
|
||||
_assembly.location(),
|
||||
"Inline assembly has invalid NatSpec documentation.",
|
||||
ssl
|
||||
);
|
||||
}
|
||||
|
||||
for (auto const& [tagName, tagValue]: docTags)
|
||||
{
|
||||
if (tagName == "solidity")
|
||||
{
|
||||
vector<string> values;
|
||||
boost::split(values, tagValue.content, isWhiteSpace);
|
||||
|
||||
set<string> valuesSeen;
|
||||
set<string> duplicates;
|
||||
for (auto const& value: values | ranges::views::filter(not_fn(&string::empty)))
|
||||
if (valuesSeen.insert(value).second)
|
||||
{
|
||||
if (value == "memory-safe-assembly")
|
||||
{
|
||||
if (_assembly.annotation().markedMemorySafe)
|
||||
m_errorReporter.warning(
|
||||
8544_error,
|
||||
_assembly.location(),
|
||||
"Inline assembly marked as memory safe using both a NatSpec tag and an assembly flag. "
|
||||
"If you are not concerned with backwards compatibility, only use the assembly flag, "
|
||||
"otherwise only use the NatSpec tag."
|
||||
);
|
||||
_assembly.annotation().markedMemorySafe = true;
|
||||
}
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
8787_error,
|
||||
_assembly.location(),
|
||||
"Unexpected value for @solidity tag in inline assembly: " + value
|
||||
);
|
||||
}
|
||||
else if (duplicates.insert(value).second)
|
||||
m_errorReporter.warning(
|
||||
4377_error,
|
||||
_assembly.location(),
|
||||
"Value for @solidity tag in inline assembly specified multiple times: " + value
|
||||
);
|
||||
}
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
6269_error,
|
||||
_assembly.location(),
|
||||
"Unexpected NatSpec tag \"" + tagName + "\" with value \"" + tagValue.content + "\" in inline assembly."
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DocStringTagParser::checkParameters(
|
||||
CallableDeclaration const& _callable,
|
||||
StructurallyDocumented const& _node,
|
||||
|
||||
@@ -48,6 +48,7 @@ private:
|
||||
bool visit(ModifierDefinition const& _modifier) override;
|
||||
bool visit(EventDefinition const& _event) override;
|
||||
bool visit(ErrorDefinition const& _error) override;
|
||||
bool visit(InlineAssembly const& _assembly) override;
|
||||
|
||||
void checkParameters(
|
||||
CallableDeclaration const& _callable,
|
||||
|
||||
@@ -334,6 +334,27 @@ bool SyntaxChecker::visit(UnaryOperation const& _operation)
|
||||
|
||||
bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
{
|
||||
if (_inlineAssembly.flags())
|
||||
for (auto flag: *_inlineAssembly.flags())
|
||||
{
|
||||
if (*flag == "memory-safe")
|
||||
{
|
||||
if (_inlineAssembly.annotation().markedMemorySafe)
|
||||
m_errorReporter.syntaxError(
|
||||
7026_error,
|
||||
_inlineAssembly.location(),
|
||||
"Inline assembly marked memory-safe multiple times."
|
||||
);
|
||||
_inlineAssembly.annotation().markedMemorySafe = true;
|
||||
}
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
4430_error,
|
||||
_inlineAssembly.location(),
|
||||
"Unknown inline assembly flag: \"" + *flag + "\""
|
||||
);
|
||||
}
|
||||
|
||||
if (!m_useYulOptimizer)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -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 = [&](
|
||||
@@ -780,6 +781,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.");
|
||||
@@ -967,8 +970,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)
|
||||
|
||||
@@ -256,10 +256,9 @@ void ViewPureChecker::reportMutability(
|
||||
m_errorReporter.typeError(
|
||||
8961_error,
|
||||
_location,
|
||||
"Function declared as " +
|
||||
"Function cannot be declared as " +
|
||||
stateMutabilityToString(m_currentFunction->stateMutability()) +
|
||||
", but this expression (potentially) modifies the state and thus "
|
||||
"requires non-payable (the default) or payable."
|
||||
" because this expression (potentially) modifies the state."
|
||||
);
|
||||
m_errors = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user