mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -146,4 +146,3 @@ set(sources
|
||||
|
||||
add_library(solidity ${sources})
|
||||
target_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost)
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "");
|
||||
}
|
||||
|
||||
@@ -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)};
|
||||
|
||||
Reference in New Issue
Block a user