mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Validate expected literal kind for yul::Dialect builtins
Co-authored-by: Daniel Kirchner <daniel@ekpyron.org>
This commit is contained in:
parent
f6a57af809
commit
3a617f9cf2
@ -4,7 +4,7 @@ Language Features:
|
|||||||
|
|
||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
|
* Yul: Report error when using non-string literals for ``datasize()``, ``dataoffset()``, ``linkersymbol()``, ``loadimmutable()``, ``setimmutable()``.
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Optimizer: Keep side-effects of ``x`` in ``byte(a, shr(b, x))`` even if the constants ``a`` and ``b`` would make the expression zero unconditionally. This optimizer rule is very hard if not impossible to trigger in a way that it can result in invalid code, though.
|
* Optimizer: Keep side-effects of ``x`` in ``byte(a, shr(b, x))`` even if the constants ``a`` and ``b`` would make the expression zero unconditionally. This optimizer rule is very hard if not impossible to trigger in a way that it can result in invalid code, though.
|
||||||
|
@ -44,6 +44,20 @@ using namespace solidity::yul;
|
|||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline string to_string(LiteralKind _kind)
|
||||||
|
{
|
||||||
|
switch (_kind)
|
||||||
|
{
|
||||||
|
case LiteralKind::Number: return "number";
|
||||||
|
case LiteralKind::Boolean: return "boolean";
|
||||||
|
case LiteralKind::String: return "string";
|
||||||
|
default: yulAssert(false, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AsmAnalyzer::analyze(Block const& _block)
|
bool AsmAnalyzer::analyze(Block const& _block)
|
||||||
{
|
{
|
||||||
auto watcher = m_errorReporter.errorWatcher();
|
auto watcher = m_errorReporter.errorWatcher();
|
||||||
@ -318,15 +332,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
for (size_t i = _funCall.arguments.size(); i > 0; i--)
|
for (size_t i = _funCall.arguments.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
Expression const& arg = _funCall.arguments[i - 1];
|
Expression const& arg = _funCall.arguments[i - 1];
|
||||||
bool isLiteralArgument = literalArguments && (*literalArguments)[i - 1].has_value();
|
if (auto literalArgumentKind = literalArguments ? literalArguments->at(i - 1) : std::nullopt)
|
||||||
bool isStringLiteral = holds_alternative<Literal>(arg) && get<Literal>(arg).kind == LiteralKind::String;
|
|
||||||
|
|
||||||
if (isLiteralArgument && isStringLiteral)
|
|
||||||
argTypes.emplace_back(expectUnlimitedStringLiteral(get<Literal>(arg)));
|
|
||||||
else
|
|
||||||
argTypes.emplace_back(expectExpression(arg));
|
|
||||||
|
|
||||||
if (isLiteralArgument)
|
|
||||||
{
|
{
|
||||||
if (!holds_alternative<Literal>(arg))
|
if (!holds_alternative<Literal>(arg))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
@ -334,18 +340,30 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
_funCall.functionName.location,
|
_funCall.functionName.location,
|
||||||
"Function expects direct literals as arguments."
|
"Function expects direct literals as arguments."
|
||||||
);
|
);
|
||||||
else if (
|
else if (*literalArgumentKind != get<Literal>(arg).kind)
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
5859_error,
|
||||||
|
get<Literal>(arg).location,
|
||||||
|
"Function expects " + to_string(*literalArgumentKind) + " literal."
|
||||||
|
);
|
||||||
|
else if (*literalArgumentKind == LiteralKind::String)
|
||||||
|
{
|
||||||
|
if (
|
||||||
_funCall.functionName.name.str() == "datasize" ||
|
_funCall.functionName.name.str() == "datasize" ||
|
||||||
_funCall.functionName.name.str() == "dataoffset"
|
_funCall.functionName.name.str() == "dataoffset"
|
||||||
)
|
)
|
||||||
if (!m_dataNames.count(std::get<Literal>(arg).value))
|
if (!m_dataNames.count(get<Literal>(arg).value))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3517_error,
|
3517_error,
|
||||||
_funCall.functionName.location,
|
get<Literal>(arg).location,
|
||||||
"Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
|
"Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
|
||||||
);
|
);
|
||||||
|
argTypes.emplace_back(expectUnlimitedStringLiteral(get<Literal>(arg)));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
argTypes.emplace_back(expectExpression(arg));
|
||||||
|
}
|
||||||
std::reverse(argTypes.begin(), argTypes.end());
|
std::reverse(argTypes.begin(), argTypes.end());
|
||||||
|
|
||||||
if (parameterTypes && parameterTypes->size() == argTypes.size())
|
if (parameterTypes && parameterTypes->size() == argTypes.size())
|
||||||
|
Loading…
Reference in New Issue
Block a user