Merge pull request #8480 from a3d4/fix-8418-astutils-compiler-error

Replaced "assert" with "if"
This commit is contained in:
chriseth 2020-03-12 15:19:54 +01:00 committed by GitHub
commit f8f18f2e55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 8 deletions

View File

@ -8,6 +8,7 @@ Compiler Features:
Bugfixes:
* Inline Assembly: Fix internal error when accessing incorrect constant variables.
### 0.6.4 (2020-03-10)

View File

@ -643,14 +643,14 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(var->type(), "Expected variable type!");
if (var->isConstant())
{
var = rootVariableDeclaration(*var);
var = rootConstVariableDeclaration(*var);
if (!var->value())
if (var && !var->value())
{
m_errorReporter.typeError(_identifier.location, "Constant has no value.");
return size_t(-1);
}
else if (!type(*var)->isValueType() || (
else if (!var || !type(*var)->isValueType() || (
dynamic_cast<Literal const*>(var->value().get()) == nullptr &&
type(*var->value())->category() != Type::Category::RationalNumber
))

View File

@ -21,7 +21,7 @@
namespace solidity::frontend
{
VariableDeclaration const* rootVariableDeclaration(VariableDeclaration const& _varDecl)
VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl)
{
solAssert(_varDecl.isConstant(), "Constant variable expected");
@ -30,7 +30,8 @@ VariableDeclaration const* rootVariableDeclaration(VariableDeclaration const& _v
while ((identifier = dynamic_cast<Identifier const*>(rootDecl->value().get())))
{
auto referencedVarDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration);
solAssert(referencedVarDecl && referencedVarDecl->isConstant(), "Identifier is not referencing a variable declaration");
if (!referencedVarDecl || !referencedVarDecl->isConstant())
return nullptr;
rootDecl = referencedVarDecl;
}
return rootDecl;

View File

@ -22,8 +22,9 @@ namespace solidity::frontend
class VariableDeclaration;
/// Find the topmost referenced variable declaration when the given variable
/// Find the topmost referenced constant variable declaration when the given variable
/// declaration value is an identifier. Works only for constant variable declarations.
VariableDeclaration const* rootVariableDeclaration(VariableDeclaration const& _varDecl);
/// Returns nullptr if an identifier in the chain is not referencing a constant variable declaration.
VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl);
}

View File

@ -682,7 +682,12 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
{
if (variable->isConstant())
{
variable = rootVariableDeclaration(*variable);
variable = rootConstVariableDeclaration(*variable);
// If rootConstVariableDeclaration fails and returns nullptr,
// it should have failed in TypeChecker already, causing a compilation error.
// In such case we should not get here.
solAssert(variable, "");
u256 value;
if (variable->value()->annotation().type->category() == Type::Category::RationalNumber)
{

View File

@ -0,0 +1,12 @@
contract C {
bool nc = false;
bool constant c = nc;
function f() public {
assembly {
let t := c
}
}
}
// ----
// TypeError: (52-54): Initial value for constant variable has to be compile-time constant.
// TypeError: (112-113): Only direct number constants and references to such constants are supported by inline assembly.

View File

@ -0,0 +1,12 @@
contract C {
bool constant c = this;
function f() public {
assembly {
let t := c
}
}
}
// ----
// TypeError: (33-37): Type contract C is not implicitly convertible to expected type bool.
// TypeError: (33-37): Initial value for constant variable has to be compile-time constant.
// TypeError: (95-96): Only direct number constants and references to such constants are supported by inline assembly.