Merge pull request #7068 from ethereum/asmConstNoValue

Cope with constants without value in inline assembly.
This commit is contained in:
chriseth 2019-07-09 12:13:56 +02:00 committed by GitHub
commit 8d006d2017
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 16 deletions

View File

@ -629,27 +629,36 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (auto var = dynamic_cast<VariableDeclaration const*>(declaration))
{
solAssert(var->type(), "Expected variable type!");
if (var->isConstant() && (!type(*var)->isValueType() || (
type(*var->value())->category() != Type::Category::RationalNumber &&
dynamic_cast<Literal const*>(var->value().get()) == nullptr
)))
if (var->isConstant())
{
m_errorReporter.typeError(_identifier.location, "Only direct number constants are supported by inline assembly.");
return size_t(-1);
}
else if (var->isConstant() && _context == yul::IdentifierContext::LValue)
{
m_errorReporter.typeError(_identifier.location, "Constant variables cannot be assigned to.");
return size_t(-1);
}
else if (requiresStorage)
{
if (var->isConstant())
if (!var->value())
{
m_errorReporter.typeError(_identifier.location, "Constant has no value.");
return size_t(-1);
}
else if (!type(*var)->isValueType() || (
dynamic_cast<Literal const*>(var->value().get()) == nullptr &&
type(*var->value())->category() != Type::Category::RationalNumber
))
{
m_errorReporter.typeError(_identifier.location, "Only direct number constants are supported by inline assembly.");
return size_t(-1);
}
else if (_context == yul::IdentifierContext::LValue)
{
m_errorReporter.typeError(_identifier.location, "Constant variables cannot be assigned to.");
return size_t(-1);
}
else if (requiresStorage)
{
m_errorReporter.typeError(_identifier.location, "The suffixes _offset and _slot can only be used on non-constant storage variables.");
return size_t(-1);
}
else if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage))
}
if (requiresStorage)
{
if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage))
{
m_errorReporter.typeError(_identifier.location, "The suffixes _offset and _slot can only be used on storage variables.");
return size_t(-1);

View File

@ -0,0 +1,11 @@
contract C {
uint constant x;
function f() public pure {
assembly {
let c1 := x
}
}
}
// ----
// TypeError: (17-32): Uninitialized "constant" variable.
// TypeError: (106-107): Constant has no value.