Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2020-12-08 21:00:09 +01:00
60 changed files with 245 additions and 179 deletions
-1
View File
@@ -146,4 +146,3 @@ set(sources
add_library(solidity ${sources})
target_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost)
+1 -2
View File
@@ -71,8 +71,7 @@ public:
using KindCompareType = std::underlying_type<VariableOccurrence::Kind>::type;
return
std::make_pair(m_declaration.id(), static_cast<KindCompareType>(m_occurrenceKind)) <
std::make_pair(_rhs.m_declaration.id(), static_cast<KindCompareType>(_rhs.m_occurrenceKind))
;
std::make_pair(_rhs.m_declaration.id(), static_cast<KindCompareType>(_rhs.m_occurrenceKind));
}
VariableDeclaration const& declaration() const { return m_declaration; }
+3 -3
View File
@@ -155,14 +155,14 @@ private:
static std::string literalTokenKind(Token _token);
static std::string type(Expression const& _expression);
static std::string type(VariableDeclaration const& _varDecl);
static int nodeId(ASTNode const& _node)
static int64_t nodeId(ASTNode const& _node)
{
return _node.id();
}
template<class Container>
static Json::Value getContainerIds(Container const& _container, bool _order = false)
{
std::vector<int> tmp;
std::vector<int64_t> tmp;
for (auto const& element: _container)
{
@@ -173,7 +173,7 @@ private:
std::sort(tmp.begin(), tmp.end());
Json::Value json(Json::arrayValue);
for (int val: tmp)
for (int64_t val: tmp)
json.append(val);
return json;
+1 -1
View File
@@ -368,7 +368,7 @@ RationalNumberType const* TypeProvider::rationalNumber(Literal const& _literal)
{
size_t const digitCount = _literal.valueWithoutUnderscores().length() - 2;
if (digitCount % 2 == 0 && (digitCount / 2) <= 32)
compatibleBytesType = fixedBytes(digitCount / 2);
compatibleBytesType = fixedBytes(static_cast<unsigned>(digitCount / 2));
}
return rationalNumber(std::get<1>(validLiteral), compatibleBytesType);
+1 -1
View File
@@ -781,7 +781,7 @@ tuple<bool, rational> RationalNumberType::parseRational(string const& _value)
denominator = bigint(string(fractionalBegin, _value.end()));
denominator /= boost::multiprecision::pow(
bigint(10),
static_cast<size_t>(distance(radixPoint + 1, _value.end()))
static_cast<unsigned>(distance(radixPoint + 1, _value.end()))
);
numerator = bigint(string(_value.begin(), radixPoint));
value = numerator + denominator;
+2 -1
View File
@@ -294,6 +294,7 @@ public:
return *m_stackItems;
}
/// Total number of stack slots occupied by this type. This is the sum of ``sizeOnStack`` of all ``stackItems()``.
// TODO: consider changing the return type to be size_t
unsigned sizeOnStack() const
{
if (!m_stackSize)
@@ -306,7 +307,7 @@ public:
++sizeOnStack;
m_stackSize = sizeOnStack;
}
return *m_stackSize;
return static_cast<unsigned>(*m_stackSize);
}
/// If it is possible to initialize such a value in memory by just writing zeros
/// of the size memoryHeadSize().
+3 -3
View File
@@ -249,7 +249,7 @@ void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight)
unsigned CompilerContext::numberOfLocalVariables() const
{
return m_localVariables.size();
return static_cast<unsigned>(m_localVariables.size());
}
shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const
@@ -430,10 +430,10 @@ void CompilerContext::appendInlineAssembly(
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
);
if (_context == yul::IdentifierContext::RValue)
_assembly.appendInstruction(dupInstruction(stackDiff));
_assembly.appendInstruction(dupInstruction(static_cast<unsigned>(stackDiff)));
else
{
_assembly.appendInstruction(swapInstruction(stackDiff));
_assembly.appendInstruction(swapInstruction(static_cast<unsigned>(stackDiff)));
_assembly.appendInstruction(Instruction::POP);
}
};
+1 -1
View File
@@ -928,7 +928,7 @@ void CompilerUtils::convertType(
{
auto const& arrayType = dynamic_cast<ArrayType const&>(_targetType);
solAssert(arrayType.isByteArray(), "");
unsigned storageSize = 32 + ((data.size() + 31) / 32) * 32;
size_t storageSize = 32 + ((data.size() + 31) / 32) * 32;
allocateMemory(storageSize);
// stack: mempos
m_context << Instruction::DUP1 << u256(data.size());
+2 -2
View File
@@ -193,7 +193,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont
auto const& immutables = contractType.immutableVariables();
// Push all immutable values on the stack.
for (auto const& immutable: immutables)
CompilerUtils(m_context).loadFromMemory(m_context.immutableMemoryOffset(*immutable), *immutable->annotation().type);
CompilerUtils(m_context).loadFromMemory(static_cast<unsigned>(m_context.immutableMemoryOffset(*immutable)), *immutable->annotation().type);
m_context.pushSubroutineSize(m_context.runtimeSub());
if (immutables.empty())
m_context << Instruction::DUP1;
@@ -673,7 +673,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
}
else
{
m_context << swapInstruction(stackLayout.size() - static_cast<unsigned>(stackLayout.back()) - 1u);
m_context << swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u);
swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
}
for (size_t i = 0; i < stackLayout.size(); ++i)
+7 -7
View File
@@ -131,7 +131,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
// stack: <keys..> <slot position>
// copy key[i] to top.
utils().copyToStackTop(paramTypes.size() - i + 1, 1);
utils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i + 1), 1);
m_context.appendInlineAssembly(R"({
let key_len := mload(key_ptr)
@@ -155,7 +155,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
utils().storeInMemory(32);
// move key to memory.
utils().copyToStackTop(paramTypes.size() - i, 1);
utils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i), 1);
utils().storeInMemory(0);
m_context << u256(64) << u256(0);
m_context << Instruction::KECCAK256;
@@ -169,7 +169,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
{
// pop offset
m_context << Instruction::POP;
utils().copyToStackTop(paramTypes.size() - i + 1, 1);
utils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i + 1), 1);
ArrayUtils(m_context).retrieveLength(*arrayType, 1);
// Stack: ref [length] index length
@@ -190,9 +190,9 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
m_context << Instruction::SWAP2 << Instruction::POP << Instruction::SWAP1;
else if (paramTypes.size() >= 2)
{
m_context << swapInstruction(paramTypes.size());
m_context << swapInstruction(static_cast<unsigned>(paramTypes.size()));
m_context << Instruction::POP;
m_context << swapInstruction(paramTypes.size());
m_context << swapInstruction(static_cast<unsigned>(paramTypes.size()));
utils().popStackSlots(paramTypes.size() - 1);
}
unsigned retSizeOnStack = 0;
@@ -840,7 +840,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
unsigned numIndexed = 0;
TypePointers paramTypes = function.parameterTypes();
// All indexed arguments go to the stack
for (unsigned arg = arguments.size(); arg > 0; --arg)
for (size_t arg = arguments.size(); arg > 0; --arg)
if (event.parameters()[arg - 1]->isIndexed())
{
++numIndexed;
@@ -1292,7 +1292,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions)
solAssert(!contains(presentOptions, newOption), "");
ptrdiff_t insertPos = presentOptions.end() - lower_bound(presentOptions.begin(), presentOptions.end(), newOption);
utils().moveIntoStack(static_cast<size_t>(insertPos), 1);
utils().moveIntoStack(static_cast<unsigned>(insertPos), 1);
presentOptions.insert(presentOptions.end() - insertPos, newOption);
}
+20 -5
View File
@@ -437,17 +437,32 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
ContractDefinition const& _contract
)
{
struct InheritanceOrder
{
bool operator()(ContractDefinition const* _c1, ContractDefinition const* _c2) const
{
solAssert(contains(linearizedBaseContracts, _c1) && contains(linearizedBaseContracts, _c2), "");
auto it1 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c1);
auto it2 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c2);
return it1 < it2;
}
vector<ContractDefinition const*> const& linearizedBaseContracts;
} inheritanceOrder{_contract.annotation().linearizedBaseContracts};
map<ContractDefinition const*, vector<string>> constructorParams;
vector<pair<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *>> baseConstructorArguments;
map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder>
baseConstructorArguments(inheritanceOrder);
;
for (ASTPointer<InheritanceSpecifier> const& base: _contract.baseContracts())
if (FunctionDefinition const* baseConstructor = dynamic_cast<ContractDefinition const*>(
base->name().annotation().referencedDeclaration
)->constructor(); baseConstructor && base->arguments())
baseConstructorArguments.emplace_back(
solAssert(baseConstructorArguments.emplace(
dynamic_cast<ContractDefinition const*>(baseConstructor->scope()),
base->arguments()
);
).second, "");
if (FunctionDefinition const* constructor = _contract.constructor())
for (ASTPointer<ModifierInvocation> const& modifier: constructor->modifiers())
@@ -458,10 +473,10 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
FunctionDefinition const* baseConstructor = baseContract->constructor();
baseConstructor && modifier->arguments()
)
baseConstructorArguments.emplace_back(
solAssert(baseConstructorArguments.emplace(
dynamic_cast<ContractDefinition const*>(baseConstructor->scope()),
modifier->arguments()
);
).second, "");
IRGeneratorForStatements generator{m_context, m_utils};
for (auto&& [baseContract, arguments]: baseConstructorArguments)
+32 -1
View File
@@ -302,7 +302,15 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
auto const& tupleSort = dynamic_cast<TupleSort const&>(*_expr.sort);
solAssert(tupleSort.components.size() == 2, "");
auto length = stoul(_expr.arguments.at(1).name);
unsigned long length;
try
{
length = stoul(_expr.arguments.at(1).name);
}
catch(out_of_range const&)
{
return {};
}
// Limit this counterexample size to 1k.
// Some OSs give you "unlimited" memory through swap and other virtual memory,
// so purely relying on bad_alloc being thrown is not a good idea.
@@ -321,6 +329,22 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
// Solver gave a concrete array but length is too large.
}
}
if (smt::isNonRecursiveStruct(*_type))
{
auto const& structType = dynamic_cast<StructType const&>(*_type);
solAssert(_expr.name == "tuple_constructor", "");
auto const& tupleSort = dynamic_cast<TupleSort const&>(*_expr.sort);
auto members = structType.structDefinition().members();
solAssert(tupleSort.components.size() == members.size(), "");
solAssert(_expr.arguments.size() == members.size(), "");
vector<string> elements;
for (unsigned i = 0; i < members.size(); ++i)
{
optional<string> elementStr = expressionToString(_expr.arguments.at(i), members[i]->type());
elements.push_back(members[i]->name() + (elementStr.has_value() ? ": " + elementStr.value() : ""));
}
return "{" + boost::algorithm::join(elements, ", ") + "}";
}
return {};
}
@@ -366,5 +390,12 @@ bool Predicate::fillArray(smtutil::Expression const& _expr, vector<string>& _arr
return true;
}
// Special base case, not supported yet.
if (_expr.name.rfind("(_ as-array") == 0)
{
// Z3 expression representing reinterpretation of a different term as an array
return false;
}
solAssert(false, "");
}
+3 -3
View File
@@ -1489,7 +1489,7 @@ public:
bytes serialise() const
{
unsigned size = m_data.size() + 1;
size_t size = m_data.size() + 1;
solAssert(size <= 0xffff, "Metadata too large.");
solAssert(m_entryCount <= 0x1f, "Too many map entries.");
@@ -1505,7 +1505,7 @@ public:
private:
void pushTextString(string const& key)
{
unsigned length = key.size();
size_t length = key.size();
if (length < 24)
{
m_data += bytes{static_cast<unsigned char>(0x60 + length)};
@@ -1521,7 +1521,7 @@ private:
}
void pushByteString(bytes const& key)
{
unsigned length = key.size();
size_t length = key.size();
if (length < 24)
{
m_data += bytes{static_cast<unsigned char>(0x40 + length)};