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:
|
||||
|
||||
* Yul: Report error when using non-string literals for ``datasize()``, ``dataoffset()``, ``linkersymbol()``, ``loadimmutable()``, ``setimmutable()``.
|
||||
|
||||
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.
|
||||
|
@ -44,6 +44,20 @@ using namespace solidity::yul;
|
||||
using namespace solidity::util;
|
||||
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)
|
||||
{
|
||||
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--)
|
||||
{
|
||||
Expression const& arg = _funCall.arguments[i - 1];
|
||||
bool isLiteralArgument = literalArguments && (*literalArguments)[i - 1].has_value();
|
||||
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 (auto literalArgumentKind = literalArguments ? literalArguments->at(i - 1) : std::nullopt)
|
||||
{
|
||||
if (!holds_alternative<Literal>(arg))
|
||||
m_errorReporter.typeError(
|
||||
@ -334,17 +340,29 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
||||
_funCall.functionName.location,
|
||||
"Function expects direct literals as arguments."
|
||||
);
|
||||
else if (
|
||||
_funCall.functionName.name.str() == "datasize" ||
|
||||
_funCall.functionName.name.str() == "dataoffset"
|
||||
)
|
||||
if (!m_dataNames.count(std::get<Literal>(arg).value))
|
||||
m_errorReporter.typeError(
|
||||
3517_error,
|
||||
_funCall.functionName.location,
|
||||
"Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
|
||||
);
|
||||
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() == "dataoffset"
|
||||
)
|
||||
if (!m_dataNames.count(get<Literal>(arg).value))
|
||||
m_errorReporter.typeError(
|
||||
3517_error,
|
||||
get<Literal>(arg).location,
|
||||
"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());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user