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: Bugfixes:
* Inline Assembly: Fix internal error when accessing incorrect constant variables.
### 0.6.4 (2020-03-10) ### 0.6.4 (2020-03-10)

View File

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

View File

@ -21,7 +21,7 @@
namespace solidity::frontend namespace solidity::frontend
{ {
VariableDeclaration const* rootVariableDeclaration(VariableDeclaration const& _varDecl) VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl)
{ {
solAssert(_varDecl.isConstant(), "Constant variable expected"); 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()))) while ((identifier = dynamic_cast<Identifier const*>(rootDecl->value().get())))
{ {
auto referencedVarDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration); 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; rootDecl = referencedVarDecl;
} }
return rootDecl; return rootDecl;

View File

@ -22,8 +22,9 @@ namespace solidity::frontend
class VariableDeclaration; 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. /// 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()) 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; u256 value;
if (variable->value()->annotation().type->category() == Type::Category::RationalNumber) 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.