Merge pull request #9967 from ethereum/develop

Merge develop into breaking.
This commit is contained in:
chriseth 2020-10-06 17:45:53 +02:00 committed by GitHub
commit b401093679
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
161 changed files with 6537 additions and 259 deletions

View File

@ -55,5 +55,9 @@ then
wget https://github.com/ethereum/evmone/releases/download/v0.4.0/evmone-0.4.0-darwin-x86_64.tar.gz
tar xzpf evmone-0.4.0-darwin-x86_64.tar.gz -C /usr/local
rm -f evmone-0.4.0-darwin-x86_64.tar.gz
fi
# hera
wget https://github.com/ewasm/hera/releases/download/v0.3.0/hera-0.3.0-darwin-x86_64.tar.gz
tar xzpf hera-0.3.0-darwin-x86_64.tar.gz -C /usr/local
rm -f hera-0.3.0-darwin-x86_64.tar.gz
fi

View File

@ -69,7 +69,11 @@ for OPTIMIZE in ${OPTIMIZE_VALUES[@]}
do
for EVM in ${EVM_VALUES[@]}
do
[[ " $RUN_STEPS " =~ " $STEP " ]] && EVM="$EVM" OPTIMIZE="$OPTIMIZE" BOOST_TEST_ARGS="-t !@nooptions" "${REPODIR}/.circleci/soltest.sh"
# run tests against hera ewasm evmc vm, only if OPTIMIZE == 0 and evm version is byzantium
EWASM_ARGS=""
[ "${EVM}" = "byzantium" ] && [ "${OPTIMIZE}" = "0" ] && EWASM_ARGS="--ewasm"
[[ " $RUN_STEPS " =~ " $STEP " ]] && EVM="$EVM" OPTIMIZE="$OPTIMIZE" SOLTEST_FLAGS="$SOLTEST_FLAGS $EWASM_ARGS" BOOST_TEST_ARGS="-t !@nooptions" "${REPODIR}/.circleci/soltest.sh"
STEP=$(($STEP + 1))
done
done

View File

@ -5,6 +5,15 @@ Breaking Changes:
Compiler Features:
* SMTChecker: Support ``addmod`` and ``mulmod``.
* SMTChecker: Support array slices.
* SMTChecker: Support type conversions.
* Optimizer: Optimize ``exp`` when base is -1.
* Code generator: Implemented events with function type as one of its indexed parameters.
* General: Option to stop compilation after parsing stage. Can be used with ``solc --stop-after parsing``
Bugfixes:
* Type Checker: Fix internal compiler error when calling `.push(<arg>)` for a storage array with a nested mapping.
### 0.7.3 (unreleased)

View File

@ -21,6 +21,10 @@ Both kinds of source mappings use integer identifiers to refer to source files.
The identifier of a source file is stored in
``output['sources'][sourceName]['id']`` where ``output`` is the output of the
standard-json compiler interface parsed as JSON.
For some utility routines, the compiler generates "internal" source files
that are not part of the original input but are referenced from the source
mappings. These source files together with their identifiers can be
obtained via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``.
.. note ::
In the case of instructions that are not associated with any particular source file,

View File

@ -200,6 +200,8 @@ Input Description
// Optional
"settings":
{
// Optional: Stop compilation after the given stage. Currently only "parsing" is valid here
"stopAfter": "parsing",
// Optional: Sorted list of remappings
"remappings": [ ":g=/dir" ],
// Optional: Optimizer settings

View File

@ -643,6 +643,16 @@ std::vector<SimplificationRule<Pattern>> evmRuleList(
Builtins::EXP(2, X),
[=]() -> Pattern { return Builtins::SHL(X, 1); }
);
rules.emplace_back(
Builtins::EXP(Word(-1), X),
[=]() -> Pattern
{
return Builtins::SUB(
Builtins::ISZERO(Builtins::AND(X, Word(1))),
Builtins::AND(X, Word(1))
);
}
);
return rules;
}

View File

@ -318,7 +318,7 @@ namespace TokenTraits
constexpr bool isEtherSubdenomination(Token op) { return op >= Token::SubWei && op <= Token::SubEther; }
constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }
constexpr bool isReservedKeyword(Token op) { return (Token::After <= op && op <= Token::Unchecked); }
constexpr bool isReservedKeyword(Token op) { return (Token::After <= op && op <= Token::Var); }
constexpr bool isYulKeyword(Token tok)
{

View File

@ -94,6 +94,8 @@ set(sources
codegen/ir/IRLValue.h
codegen/ir/IRVariable.cpp
codegen/ir/IRVariable.h
formal/ArraySlicePredicate.cpp
formal/ArraySlicePredicate.h
formal/BMC.cpp
formal/BMC.h
formal/CHC.cpp

View File

@ -2684,10 +2684,20 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
"Using \"." + memberName + "(...)\" is deprecated. Use \"{" + memberName + ": ...}\" instead."
);
if (
funType->kind() == FunctionType::Kind::ArrayPush &&
arguments.value().numArguments() != 0 &&
exprType->containsNestedMapping()
)
m_errorReporter.typeError(
8871_error,
_memberAccess.location(),
"Storage arrays with nested mappings do not support .push(<arg>)."
);
if (!funType->bound())
if (auto contractType = dynamic_cast<ContractType const*>(exprType))
requiredLookup = contractType->isSuper() ? VirtualLookup::Super : VirtualLookup::Virtual;
}
annotation.requiredLookup = requiredLookup;

View File

@ -23,6 +23,7 @@
#include <libsolidity/ast/ASTJsonConverter.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libyul/AsmJsonConverter.h>
#include <libyul/AsmData.h>
@ -69,8 +70,9 @@ void addIfSet(std::vector<pair<string, Json::Value>>& _attributes, string const&
namespace solidity::frontend
{
ASTJsonConverter::ASTJsonConverter(bool _legacy, map<string, unsigned> _sourceIndices):
ASTJsonConverter::ASTJsonConverter(bool _legacy, CompilerStack::State _stackState, map<string, unsigned> _sourceIndices):
m_legacy(_legacy),
m_stackState(_stackState),
m_sourceIndices(std::move(_sourceIndices))
{
}
@ -204,7 +206,6 @@ void ASTJsonConverter::appendExpressionAttributes(
{
std::vector<pair<string, Json::Value>> exprAttributes = {
make_pair("typeDescriptions", typePointerToJson(_annotation.type)),
make_pair("lValueRequested", _annotation.willBeWrittenTo),
make_pair("argumentTypes", typePointerToJson(_annotation.arguments))
};
@ -212,6 +213,9 @@ void ASTJsonConverter::appendExpressionAttributes(
addIfSet(exprAttributes, "isPure", _annotation.isPure);
addIfSet(exprAttributes, "isConstant", _annotation.isConstant);
if (m_stackState > CompilerStack::State::ParsedAndImported)
exprAttributes.emplace_back("lValueRequested", _annotation.willBeWrittenTo);
_attributes += exprAttributes;
}
@ -260,6 +264,7 @@ bool ASTJsonConverter::visit(SourceUnit const& _node)
addIfSet(attributes, "absolutePath", _node.annotation().path);
setJsonNode(_node, "SourceUnit", std::move(attributes));
return false;
}
@ -268,7 +273,7 @@ bool ASTJsonConverter::visit(PragmaDirective const& _node)
Json::Value literals(Json::arrayValue);
for (auto const& literal: _node.literals())
literals.append(literal);
setJsonNode( _node, "PragmaDirective", {
setJsonNode(_node, "PragmaDirective", {
make_pair("literals", std::move(literals))
});
return false;
@ -278,7 +283,7 @@ bool ASTJsonConverter::visit(ImportDirective const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("file", _node.path()),
make_pair(m_legacy ? "SourceUnit" : "sourceUnit", nodeId(*_node.annotation().sourceUnit)),
make_pair(m_legacy ? "SourceUnit" : "sourceUnit", idOrNull(_node.annotation().sourceUnit)),
make_pair("scope", idOrNull(_node.scope()))
};
@ -395,18 +400,11 @@ bool ASTJsonConverter::visit(OverrideSpecifier const& _node)
bool ASTJsonConverter::visit(FunctionDefinition const& _node)
{
Visibility visibility;
if (_node.isConstructor())
visibility = _node.annotation().contract->abstract() ? Visibility::Internal : Visibility::Public;
else
visibility = _node.visibility();
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())),
make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
make_pair("visibility", Declaration::visibilityToString(visibility)),
make_pair("virtual", _node.markedVirtual()),
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
make_pair("parameters", toJson(_node.parameterList())),
@ -417,7 +415,19 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
make_pair("scope", idOrNull(_node.scope()))
};
if (_node.isPartOfExternalInterface())
optional<Visibility> visibility;
if (_node.isConstructor())
{
if (_node.annotation().contract)
visibility = _node.annotation().contract->abstract() ? Visibility::Internal : Visibility::Public;
}
else
visibility = _node.visibility();
if (visibility)
attributes.emplace_back("visibility", Declaration::visibilityToString(*visibility));
if (_node.isPartOfExternalInterface() && m_stackState > CompilerStack::State::ParsedAndImported)
attributes.emplace_back("functionSelector", _node.externalIdentifierHex());
if (!_node.annotation().baseFunctions.empty())
attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
@ -718,7 +728,7 @@ bool ASTJsonConverter::visit(Assignment const& _node)
make_pair("rightHandSide", toJson(_node.rightHandSide()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode( _node, "Assignment", std::move(attributes));
setJsonNode(_node, "Assignment", std::move(attributes));
return false;
}
@ -770,15 +780,19 @@ bool ASTJsonConverter::visit(FunctionCall const& _node)
make_pair("tryCall", _node.annotation().tryCall)
};
FunctionCallKind nodeKind = *_node.annotation().kind;
if (m_legacy)
if (_node.annotation().kind.set())
{
attributes.emplace_back("isStructConstructorCall", nodeKind == FunctionCallKind::StructConstructorCall);
attributes.emplace_back("type_conversion", nodeKind == FunctionCallKind::TypeConversion);
FunctionCallKind nodeKind = *_node.annotation().kind;
if (m_legacy)
{
attributes.emplace_back("isStructConstructorCall", nodeKind == FunctionCallKind::StructConstructorCall);
attributes.emplace_back("type_conversion", nodeKind == FunctionCallKind::TypeConversion);
}
else
attributes.emplace_back("kind", functionCallKind(nodeKind));
}
else
attributes.emplace_back("kind", functionCallKind(nodeKind));
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "FunctionCall", std::move(attributes));
return false;

View File

@ -25,6 +25,7 @@
#include <libsolidity/ast/ASTAnnotations.h>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/interface/CompilerStack.h>
#include <liblangutil/Exceptions.h>
#include <json/json.h>
@ -51,9 +52,11 @@ class ASTJsonConverter: public ASTConstVisitor
public:
/// Create a converter to JSON for the given abstract syntax tree.
/// @a _legacy if true, use legacy format
/// @a _stackState state of the compiler stack to avoid outputting incomplete data
/// @a _sourceIndices is used to abbreviate source names in source locations.
explicit ASTJsonConverter(
bool _legacy,
CompilerStack::State _stackState,
std::map<std::string, unsigned> _sourceIndices = std::map<std::string, unsigned>()
);
/// Output the json representation of the AST to _stream.
@ -189,6 +192,7 @@ private:
}
bool m_legacy = false; ///< if true, use legacy format
CompilerStack::State m_stackState = CompilerStack::State::Empty; ///< Used to only access information that already exists
bool m_inEvent = false; ///< whether we are currently inside an event or not
Json::Value m_currentValue;
std::map<std::string, unsigned> m_sourceIndices;

View File

@ -140,7 +140,9 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
for (auto const& type: _parameters)
{
if (TypePointer ext = type->interfaceType(_inLibrary).get())
if (!type)
return util::Result<TypePointers>::err("Type information not present.");
else if (TypePointer ext = type->interfaceType(_inLibrary).get())
transformed.push_back(ext);
else
return util::Result<TypePointers>::err("Parameter should have external type.");

View File

@ -867,11 +867,26 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
else
{
solAssert(paramTypes[arg - 1]->isValueType(), "");
utils().convertType(
*arguments[arg - 1]->annotation().type,
*paramTypes[arg - 1],
true
);
if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[arg - 1]))
{
auto argumentType =
dynamic_cast<FunctionType const*>(arguments[arg-1]->annotation().type);
solAssert(
argumentType &&
functionType->kind() == FunctionType::Kind::External &&
argumentType->kind() == FunctionType::Kind::External &&
!argumentType->bound(),
""
);
utils().combineExternalFunctionType(true);
}
else
utils().convertType(
*arguments[arg - 1]->annotation().type,
*paramTypes[arg - 1],
true
);
}
}
if (!event.isAnonymous())

View File

@ -291,7 +291,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack: value storage_ref multiplier
// fetch old value
m_context << Instruction::DUP2 << Instruction::SLOAD;
// stack: value storege_ref multiplier old_full_value
// stack: value storage_ref multiplier old_full_value
// clear bytes in old value
m_context
<< Instruction::DUP2 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1)
@ -461,7 +461,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const
// stack: storage_ref multiplier
// fetch old value
m_context << Instruction::DUP2 << Instruction::SLOAD;
// stack: storege_ref multiplier old_full_value
// stack: storage_ref multiplier old_full_value
// clear bytes in old value
m_context
<< Instruction::SWAP1 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1)

View File

@ -873,6 +873,12 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
let arrayDataStart := <dataPosition>(array)
let deleteStart := add(arrayDataStart, newSlotCount)
let deleteEnd := add(arrayDataStart, oldSlotCount)
<?packed>
// if we are dealing with packed array and offset is greater than zero
// we have to partially clear last slot that is still used, so decreasing start by one
let offset := mul(mod(newLen, <itemsPerSlot>), <storageBytes>)
if gt(offset, 0) { <partialClearStorageSlot>(sub(deleteStart, 1), offset) }
</packed>
<clearStorageRange>(deleteStart, deleteEnd)
}
})")
@ -883,6 +889,10 @@ std::string YulUtilFunctions::resizeDynamicArrayFunction(ArrayType const& _type)
("dataPosition", arrayDataAreaFunction(_type))
("clearStorageRange", clearStorageRangeFunction(*_type.baseType()))
("maxArrayLength", (u256(1) << 64).str())
("packed", _type.baseType()->storageBytes() <= 16)
("itemsPerSlot", to_string(32 / _type.baseType()->storageBytes()))
("storageBytes", to_string(_type.baseType()->storageBytes()))
("partialClearStorageSlot", partialClearStorageSlotFunction())
.render();
});
}
@ -1037,8 +1047,6 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
solUnimplementedAssert(!_type.isByteArray(), "Byte Arrays not yet implemented!");
solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented.");
solAssert(_type.baseType()->isValueType(), "");
string functionName = "array_push_zero_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() {
return Whiskers(R"(
@ -1047,24 +1055,39 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)
if iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }
sstore(array, add(oldLen, 1))
slot, offset := <indexAccess>(array, oldLen)
<storeValue>(slot, offset, <zeroValueFunction>())
})")
("functionName", functionName)
("panic", panicFunction())
("fetchLength", arrayLengthFunction(_type))
("indexAccess", storageArrayIndexAccessFunction(_type))
("storeValue", updateStorageValueFunction(*_type.baseType(), *_type.baseType()))
("maxArrayLength", (u256(1) << 64).str())
("zeroValueFunction", zeroValueFunction(*_type.baseType()))
.render();
});
}
string YulUtilFunctions::partialClearStorageSlotFunction()
{
string functionName = "partial_clear_storage_slot";
return m_functionCollector.createFunction(functionName, [&]() {
return Whiskers(R"(
function <functionName>(slot, offset) {
let mask := <shr>(mul(8, sub(32, offset)), <ones>)
sstore(slot, and(mask, sload(slot)))
}
)")
("functionName", functionName)
("ones", formatNumber((bigint(1) << 256) - 1))
("shr", shiftRightFunctionDynamic())
.render();
});
}
string YulUtilFunctions::clearStorageRangeFunction(Type const& _type)
{
string functionName = "clear_storage_range_" + _type.identifier();
if (_type.storageBytes() < 32)
solAssert(_type.isValueType(), "");
solAssert(_type.storageBytes() >= 32, "Expected smaller value for storage bytes");
string functionName = "clear_storage_range_" + _type.identifier();
return m_functionCollector.createFunction(functionName, [&]() {
return Whiskers(R"(
@ -1076,7 +1099,7 @@ string YulUtilFunctions::clearStorageRangeFunction(Type const& _type)
}
)")
("functionName", functionName)
("setToZero", storageSetToZeroFunction(_type))
("setToZero", storageSetToZeroFunction(_type.storageBytes() < 32 ? *TypeProvider::uint256() : _type))
("increment", _type.storageSize().str())
.render();
});

View File

@ -422,6 +422,11 @@ private:
/// @returns a function that reads a reference type from storage to memory (performing a deep copy).
std::string readFromStorageReferenceType(Type const& _type);
/// @returns the name of a function that will clear given storage slot
/// starting with given offset until the end of the slot
/// signature: (slot, offset)
std::string partialClearStorageSlotFunction();
langutil::EVMVersion m_evmVersion;
RevertStrings m_revertStrings;
MultiUseYulFunctionCollector& m_functionCollector;

View File

@ -929,6 +929,20 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
"(" <<
IRVariable(arg).commaSeparatedList() <<
")";
else if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[i]))
{
solAssert(
IRVariable(arg).type() == *functionType &&
functionType->kind() == FunctionType::Kind::External &&
!functionType->bound(),
""
);
define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::fixedBytes(32))) <<
m_utils.combineExternalFunctionIdFunction() <<
"(" <<
IRVariable(arg).commaSeparatedList() <<
")\n";
}
else
indexedArgs.emplace_back(convert(arg, *paramTypes[i]));
}

View File

@ -0,0 +1,91 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <libsolidity/formal/ArraySlicePredicate.h>
#include <liblangutil/Exceptions.h>
using namespace std;
using namespace solidity;
using namespace solidity::smtutil;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;
map<string, ArraySlicePredicate::SliceData> ArraySlicePredicate::m_slicePredicates;
pair<bool, ArraySlicePredicate::SliceData const&> ArraySlicePredicate::create(SortPointer _sort, EncodingContext& _context)
{
solAssert(_sort->kind == Kind::Tuple, "");
auto tupleSort = dynamic_pointer_cast<TupleSort>(_sort);
solAssert(tupleSort, "");
auto tupleName = tupleSort->name;
if (m_slicePredicates.count(tupleName))
return {true, m_slicePredicates.at(tupleName)};
auto sort = tupleSort->components.at(0);
solAssert(sort->kind == Kind::Array, "");
smt::SymbolicArrayVariable aVar{sort, "a_" + tupleName, _context };
smt::SymbolicArrayVariable bVar{sort, "b_" + tupleName, _context};
smt::SymbolicIntVariable startVar{TypeProvider::uint256(), TypeProvider::uint256(), "start_" + tupleName, _context};
smt::SymbolicIntVariable endVar{TypeProvider::uint256(), TypeProvider::uint256(), "end_" + tupleName, _context };
smt::SymbolicIntVariable iVar{TypeProvider::uint256(), TypeProvider::uint256(), "i_" + tupleName, _context};
vector<SortPointer> domain{sort, sort, startVar.sort(), endVar.sort()};
auto sliceSort = make_shared<FunctionSort>(domain, SortProvider::boolSort);
Predicate const& slice = *Predicate::create(sliceSort, "array_slice_" + tupleName, PredicateType::Custom, _context);
domain.emplace_back(iVar.sort());
auto predSort = make_shared<FunctionSort>(domain, SortProvider::boolSort);
Predicate const& header = *Predicate::create(predSort, "array_slice_header_" + tupleName, PredicateType::Custom, _context);
Predicate const& loop = *Predicate::create(predSort, "array_slice_loop_" + tupleName, PredicateType::Custom, _context);
auto a = aVar.elements();
auto b = bVar.elements();
auto start = startVar.currentValue();
auto end = endVar.currentValue();
auto i = iVar.currentValue();
auto rule1 = smtutil::Expression::implies(
end > start,
header({a, b, start, end, 0})
);
auto rule2 = smtutil::Expression::implies(
header({a, b, start, end, i}) && i >= (end - start),
slice({a, b, start, end})
);
auto rule3 = smtutil::Expression::implies(
header({a, b, start, end, i}) && i >= 0 && i < (end - start),
loop({a, b, start, end, i})
);
auto b_i = smtutil::Expression::select(b, i);
auto a_start_i = smtutil::Expression::select(a, start + i);
auto rule4 = smtutil::Expression::implies(
loop({a, b, start, end, i}) && b_i == a_start_i,
header({a, b, start, end, i + 1})
);
return {false, m_slicePredicates[tupleName] = {
{&slice, &header, &loop},
{move(rule1), move(rule2), move(rule3), move(rule4)}
}};
}

View File

@ -0,0 +1,62 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <libsolidity/formal/EncodingContext.h>
#include <libsolidity/formal/Predicate.h>
#include <libsolidity/formal/SymbolicVariables.h>
#include <libsmtutil/Sorts.h>
#include <vector>
namespace solidity::frontend
{
/**
* Contains the set of rules to compute an array slice.
* Rules:
* 1. end > start => ArraySliceHeader(a, b, start, end, 0)
* 2. ArraySliceHeader(a, b, start, end, i) && i >= (end - start) => ArraySlice(a, b, start, end)
* 3. ArraySliceHeader(a, b, start, end, i) && i >= 0 && i < (end - start) => ArraySliceLoop(a, b, start, end, i)
* 4. ArraySliceLoop(a, b, start, end, i) && b[i] = a[start + i] => ArraySliceHeader(a, b, start, end, i + 1)
*
* The rule to be used by CHC is ArraySlice(a, b, start, end).
*/
struct ArraySlicePredicate
{
/// Contains the predicates and rules created to compute
/// array slices for a given sort.
struct SliceData
{
std::vector<Predicate const*> predicates;
std::vector<smtutil::Expression> rules;
};
/// @returns a flag representing whether the array slice predicates had already been created before for this sort,
/// and the corresponding slice data.
static std::pair<bool, SliceData const&> create(smtutil::SortPointer _sort, smt::EncodingContext& _context);
static void reset() { m_slicePredicates.clear(); }
private:
/// Maps a unique sort name to its slice data.
static std::map<std::string, SliceData> m_slicePredicates;
};
}

View File

@ -22,6 +22,7 @@
#include <libsmtutil/Z3CHCInterface.h>
#endif
#include <libsolidity/formal/ArraySlicePredicate.h>
#include <libsolidity/formal/PredicateInstance.h>
#include <libsolidity/formal/PredicateSort.h>
#include <libsolidity/formal/SymbolicTypes.h>
@ -470,6 +471,36 @@ void CHC::endVisit(Continue const& _continue)
m_currentBlock = predicate(*continueGhost);
}
void CHC::endVisit(IndexRangeAccess const& _range)
{
createExpr(_range);
auto baseArray = dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range.baseExpression()));
auto sliceArray = dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range));
solAssert(baseArray && sliceArray, "");
auto const& sliceData = ArraySlicePredicate::create(sliceArray->sort(), m_context);
if (!sliceData.first)
{
for (auto pred: sliceData.second.predicates)
m_interface->registerRelation(pred->functor());
for (auto const& rule: sliceData.second.rules)
addRule(rule, "");
}
auto start = _range.startExpression() ? expr(*_range.startExpression()) : 0;
auto end = _range.endExpression() ? expr(*_range.endExpression()) : baseArray->length();
auto slicePred = (*sliceData.second.predicates.at(0))({
baseArray->elements(),
sliceArray->elements(),
start,
end
});
m_context.addAssertion(slicePred);
m_context.addAssertion(sliceArray->length() == end - start);
}
void CHC::visitAssert(FunctionCall const& _funCall)
{
auto const& args = _funCall.arguments();
@ -688,6 +719,7 @@ void CHC::resetSourceAnalysis()
m_interfaces.clear();
m_nondetInterfaces.clear();
Predicate::reset();
ArraySlicePredicate::reset();
m_blockCounter = 0;
bool usesZ3 = false;
@ -994,6 +1026,9 @@ smtutil::Expression CHC::predicate(Predicate const& _block)
case PredicateType::NondetInterface:
// Nondeterministic interface predicates are handled differently.
solAssert(false, "");
case PredicateType::Custom:
// Custom rules are handled separately.
solAssert(false, "");
}
solAssert(false, "");
}

View File

@ -81,6 +81,7 @@ private:
void endVisit(FunctionCall const& _node) override;
void endVisit(Break const& _node) override;
void endVisit(Continue const& _node) override;
void endVisit(IndexRangeAccess const& _node) override;
void visitAssert(FunctionCall const& _funCall);
void visitAddMulMod(FunctionCall const& _funCall) override;

View File

@ -39,7 +39,8 @@ enum class PredicateType
FunctionEntry,
FunctionSummary,
FunctionBlock,
Error
Error,
Custom
};
/**

View File

@ -817,43 +817,125 @@ void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall)
{
solAssert(*_funCall.annotation().kind == FunctionCallKind::TypeConversion, "");
solAssert(_funCall.arguments().size() == 1, "");
auto argument = _funCall.arguments().front();
auto const& argType = argument->annotation().type;
unsigned argSize = argument->annotation().type->storageBytes();
unsigned castSize = _funCall.annotation().type->storageBytes();
auto const& funCallCategory = _funCall.annotation().type->category();
// Allow casting number literals to address.
// TODO: remove the isNegative() check once the type checker disallows this
if (
auto const* numberType = dynamic_cast<RationalNumberType const*>(argument->annotation().type);
numberType && !numberType->isNegative() && (funCallCategory == Type::Category::Address)
)
defineExpr(_funCall, numberType->literalValue(nullptr));
else if (argSize == castSize)
defineExpr(_funCall, expr(*argument));
else
{
m_context.setUnknownValue(*m_context.expression(_funCall));
// TODO: truncating and bytesX needs a different approach because of right padding.
if (funCallCategory == Type::Category::Integer || funCallCategory == Type::Category::Address)
{
if (argSize < castSize)
defineExpr(_funCall, expr(*argument));
else
{
auto const& intType = dynamic_cast<IntegerType const&>(*m_context.expression(_funCall)->type());
defineExpr(_funCall, smtutil::Expression::ite(
expr(*argument) >= smt::minValue(intType) && expr(*argument) <= smt::maxValue(intType),
expr(*argument),
expr(_funCall)
));
}
}
m_errorReporter.warning(
5084_error,
_funCall.location(),
"Type conversion is not yet fully supported and might yield false positives."
);
auto const& funCallType = _funCall.annotation().type;
// TODO Simplify this whole thing for 0.8.0 where weird casts are disallowed.
auto symbArg = expr(*argument, funCallType);
bool castIsSigned = smt::isNumber(*funCallType) && smt::isSigned(funCallType);
bool argIsSigned = smt::isNumber(*argType) && smt::isSigned(argType);
optional<smtutil::Expression> symbMin;
optional<smtutil::Expression> symbMax;
if (smt::isNumber(*funCallType))
{
symbMin = smt::minValue(funCallType);
symbMax = smt::maxValue(funCallType);
}
if (argSize == castSize)
{
// If sizes are the same, it's possible that the signs are different.
if (smt::isNumber(*funCallType))
{
solAssert(smt::isNumber(*argType), "");
// castIsSigned && !argIsSigned => might overflow if arg > castType.max
// !castIsSigned && argIsSigned => might underflow if arg < castType.min
// !castIsSigned && !argIsSigned => ok
// castIsSigned && argIsSigned => ok
if (castIsSigned && !argIsSigned)
{
auto wrap = smtutil::Expression::ite(
symbArg > *symbMax,
symbArg - (*symbMax - *symbMin + 1),
symbArg
);
defineExpr(_funCall, wrap);
}
else if (!castIsSigned && argIsSigned)
{
auto wrap = smtutil::Expression::ite(
symbArg < *symbMin,
symbArg + (*symbMax + 1),
symbArg
);
defineExpr(_funCall, wrap);
}
else
defineExpr(_funCall, symbArg);
}
else
defineExpr(_funCall, symbArg);
}
else if (castSize > argSize)
{
solAssert(smt::isNumber(*funCallType), "");
// RationalNumbers have size 32.
solAssert(argType->category() != Type::Category::RationalNumber, "");
// castIsSigned && !argIsSigned => ok
// castIsSigned && argIsSigned => ok
// !castIsSigned && !argIsSigned => ok except for FixedBytesType, need to adjust padding
// !castIsSigned && argIsSigned => might underflow if arg < castType.min
if (!castIsSigned && argIsSigned)
{
auto wrap = smtutil::Expression::ite(
symbArg < *symbMin,
symbArg + (*symbMax + 1),
symbArg
);
defineExpr(_funCall, wrap);
}
else if (!castIsSigned && !argIsSigned)
{
if (auto const* fixedCast = dynamic_cast<FixedBytesType const*>(funCallType))
{
auto const* fixedArg = dynamic_cast<FixedBytesType const*>(argType);
solAssert(fixedArg, "");
auto diff = fixedCast->numBytes() - fixedArg->numBytes();
solAssert(diff > 0, "");
auto bvSize = fixedCast->numBytes() * 8;
defineExpr(
_funCall,
smtutil::Expression::bv2int(smtutil::Expression::int2bv(symbArg, bvSize) << smtutil::Expression::int2bv(diff * 8, bvSize))
);
}
else
defineExpr(_funCall, symbArg);
}
else
defineExpr(_funCall, symbArg);
}
else // castSize < argSize
{
solAssert(smt::isNumber(*funCallType), "");
auto const* fixedCast = dynamic_cast<FixedBytesType const*>(funCallType);
auto const* fixedArg = dynamic_cast<FixedBytesType const*>(argType);
if (fixedCast && fixedArg)
{
createExpr(_funCall);
auto diff = argSize - castSize;
solAssert(fixedArg->numBytes() - fixedCast->numBytes() == diff, "");
auto argValueBV = smtutil::Expression::int2bv(symbArg, argSize * 8);
auto shr = smtutil::Expression::int2bv(diff * 8, argSize * 8);
solAssert(!castIsSigned, "");
defineExpr(_funCall, smtutil::Expression::bv2int(argValueBV >> shr));
}
else
{
auto argValueBV = smtutil::Expression::int2bv(symbArg, castSize * 8);
defineExpr(_funCall, smtutil::Expression::bv2int(argValueBV, castIsSigned));
}
}
}
@ -1095,11 +1177,7 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
void SMTEncoder::endVisit(IndexRangeAccess const& _indexRangeAccess)
{
createExpr(_indexRangeAccess);
m_errorReporter.warning(
2923_error,
_indexRangeAccess.location(),
"Assertion checker does not yet implement this expression."
);
/// The actual slice is created by CHC which also assigns the length.
}
void SMTEncoder::arrayAssignment()

View File

@ -389,11 +389,47 @@ smtutil::Expression minValue(frontend::IntegerType const& _type)
return smtutil::Expression(_type.minValue());
}
smtutil::Expression minValue(frontend::TypePointer _type)
{
solAssert(isNumber(*_type), "");
if (auto const* intType = dynamic_cast<IntegerType const*>(_type))
return intType->minValue();
if (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))
return fixedType->minIntegerValue();
if (
dynamic_cast<AddressType const*>(_type) ||
dynamic_cast<ContractType const*>(_type) ||
dynamic_cast<EnumType const*>(_type) ||
dynamic_cast<FixedBytesType const*>(_type)
)
return 0;
solAssert(false, "");
}
smtutil::Expression maxValue(frontend::IntegerType const& _type)
{
return smtutil::Expression(_type.maxValue());
}
smtutil::Expression maxValue(frontend::TypePointer _type)
{
solAssert(isNumber(*_type), "");
if (auto const* intType = dynamic_cast<IntegerType const*>(_type))
return intType->maxValue();
if (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))
return fixedType->maxIntegerValue();
if (
dynamic_cast<AddressType const*>(_type) ||
dynamic_cast<ContractType const*>(_type)
)
return TypeProvider::uint(160)->maxValue();
if (auto const* enumType = dynamic_cast<EnumType const*>(_type))
return enumType->numberOfMembers();
if (auto const* bytesType = dynamic_cast<FixedBytesType const*>(_type))
return TypeProvider::uint(bytesType->numBytes() * 8)->maxValue();
solAssert(false, "");
}
void setSymbolicZeroValue(SymbolicVariable const& _variable, EncodingContext& _context)
{
setSymbolicZeroValue(_variable.currentValue(), _variable.type(), _context);
@ -458,6 +494,29 @@ smtutil::Expression zeroValue(frontend::TypePointer const& _type)
return 0;
}
bool isSigned(TypePointer const& _type)
{
solAssert(smt::isNumber(*_type), "");
bool isSigned = false;
if (auto const* numberType = dynamic_cast<RationalNumberType const*>(_type))
isSigned |= numberType->isNegative();
else if (auto const* intType = dynamic_cast<IntegerType const*>(_type))
isSigned |= intType->isSigned();
else if (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))
isSigned |= fixedType->isSigned();
else if (
dynamic_cast<AddressType const*>(_type) ||
dynamic_cast<ContractType const*>(_type) ||
dynamic_cast<EnumType const*>(_type) ||
dynamic_cast<FixedBytesType const*>(_type)
)
return false;
else
solAssert(false, "");
return isSigned;
}
pair<unsigned, bool> typeBvSizeAndSignedness(frontend::TypePointer const& _type)
{
if (auto const* intType = dynamic_cast<IntegerType const*>(_type))

View File

@ -65,8 +65,11 @@ bool isNonRecursiveStruct(frontend::Type const& _type);
std::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(frontend::Type const& _type, std::string const& _uniqueName, EncodingContext& _context);
smtutil::Expression minValue(frontend::IntegerType const& _type);
smtutil::Expression minValue(frontend::TypePointer _type);
smtutil::Expression maxValue(frontend::IntegerType const& _type);
smtutil::Expression maxValue(frontend::TypePointer _type);
smtutil::Expression zeroValue(frontend::TypePointer const& _type);
bool isSigned(frontend::TypePointer const& _type);
std::pair<unsigned, bool> typeBvSizeAndSignedness(frontend::TypePointer const& type);

View File

@ -124,7 +124,7 @@ std::optional<CompilerStack::Remapping> CompilerStack::parseRemapping(string con
void CompilerStack::setRemappings(vector<Remapping> const& _remappings)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set remappings before parsing."));
for (auto const& remapping: _remappings)
solAssert(!remapping.prefix.empty(), "");
@ -133,21 +133,21 @@ void CompilerStack::setRemappings(vector<Remapping> const& _remappings)
void CompilerStack::setEVMVersion(langutil::EVMVersion _version)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set EVM version before parsing."));
m_evmVersion = _version;
}
void CompilerStack::setSMTSolverChoice(smtutil::SMTSolverChoice _enabledSMTSolvers)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set enabled SMT solvers before parsing."));
m_enabledSMTSolvers = _enabledSMTSolvers;
}
void CompilerStack::setLibraries(std::map<std::string, util::h160> const& _libraries)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set libraries before parsing."));
m_libraries = _libraries;
}
@ -161,14 +161,14 @@ void CompilerStack::setOptimiserSettings(bool _optimize, unsigned _runs)
void CompilerStack::setOptimiserSettings(OptimiserSettings _settings)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set optimiser settings before parsing."));
m_optimiserSettings = std::move(_settings);
}
void CompilerStack::setRevertStringBehaviour(RevertStrings _revertStrings)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set revert string settings before parsing."));
solUnimplementedAssert(_revertStrings != RevertStrings::VerboseDebug, "");
m_revertStrings = _revertStrings;
@ -176,21 +176,21 @@ void CompilerStack::setRevertStringBehaviour(RevertStrings _revertStrings)
void CompilerStack::useMetadataLiteralSources(bool _metadataLiteralSources)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set use literal sources before parsing."));
m_metadataLiteralSources = _metadataLiteralSources;
}
void CompilerStack::setMetadataHash(MetadataHash _metadataHash)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set metadata hash before parsing."));
m_metadataHash = _metadataHash;
}
void CompilerStack::addSMTLib2Response(h256 const& _hash, string const& _response)
{
if (m_stackState >= ParsingPerformed)
if (m_stackState >= ParsedAndImported)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must add SMTLib2 responses before parsing."));
m_smtlib2Responses[_hash] = _response;
}
@ -214,6 +214,7 @@ void CompilerStack::reset(bool _keepSettings)
m_optimiserSettings = OptimiserSettings::minimal();
m_metadataLiteralSources = false;
m_metadataHash = MetadataHash::IPFS;
m_stopAfter = State::CompilationSuccessful;
}
m_globalContext.reset();
m_sourceOrder.clear();
@ -247,6 +248,7 @@ bool CompilerStack::parse()
vector<string> sourcesToParse;
for (auto const& s: m_sources)
sourcesToParse.push_back(s.first);
for (size_t i = 0; i < sourcesToParse.size(); ++i)
{
string const& path = sourcesToParse[i];
@ -258,19 +260,26 @@ bool CompilerStack::parse()
else
{
source.ast->annotation().path = path;
for (auto const& newSource: loadMissingSources(*source.ast, path))
{
string const& newPath = newSource.first;
string const& newContents = newSource.second;
m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents, newPath));
sourcesToParse.push_back(newPath);
}
if (m_stopAfter >= ParsedAndImported)
for (auto const& newSource: loadMissingSources(*source.ast, path))
{
string const& newPath = newSource.first;
string const& newContents = newSource.second;
m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents, newPath));
sourcesToParse.push_back(newPath);
}
}
}
m_stackState = ParsingPerformed;
if (m_stopAfter <= Parsed)
m_stackState = Parsed;
else
m_stackState = ParsedAndImported;
if (!Error::containsOnlyWarnings(m_errorReporter.errors()))
m_hasError = true;
storeContractDefinitions();
return !m_hasError;
}
@ -290,13 +299,15 @@ void CompilerStack::importASTs(map<string, Json::Value> const& _sources)
source.scanner = scanner;
m_sources[path] = source;
}
m_stackState = ParsingPerformed;
m_stackState = ParsedAndImported;
m_importedSources = true;
storeContractDefinitions();
}
bool CompilerStack::analyze()
{
if (m_stackState != ParsingPerformed || m_stackState >= AnalysisPerformed)
if (m_stackState != ParsedAndImported || m_stackState >= AnalysisPerformed)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must call analyze only after parsing was performed."));
resolveImports();
@ -336,26 +347,6 @@ bool CompilerStack::analyze()
if (source->ast && !resolver.resolveNamesAndTypes(*source->ast))
return false;
// Store contract definitions.
for (Source const* source: m_sourceOrder)
if (source->ast)
for (
ContractDefinition const* contract:
ASTNode::filteredNodes<ContractDefinition>(source->ast->nodes())
)
{
// Note that we now reference contracts by their fully qualified names, and
// thus contracts can only conflict if declared in the same source file. This
// should already cause a double-declaration error elsewhere.
if (!m_contracts.count(contract->fullyQualifiedName()))
m_contracts[contract->fullyQualifiedName()].contract = contract;
else
solAssert(
m_errorReporter.hasErrors(),
"Contract already present (name clash?), but no error was reported."
);
}
DeclarationTypeChecker declarationTypeChecker(m_errorReporter, m_evmVersion);
for (Source const* source: m_sourceOrder)
if (source->ast && !declarationTypeChecker.check(*source->ast))
@ -469,9 +460,13 @@ bool CompilerStack::analyze()
return !m_hasError;
}
bool CompilerStack::parseAndAnalyze()
bool CompilerStack::parseAndAnalyze(State _stopAfter)
{
m_stopAfter = _stopAfter;
bool success = parse();
if (m_stackState >= m_stopAfter)
return success;
if (success || m_parserErrorRecovery)
success = analyze();
return success;
@ -502,12 +497,16 @@ bool CompilerStack::isRequestedContract(ContractDefinition const& _contract) con
return false;
}
bool CompilerStack::compile()
bool CompilerStack::compile(State _stopAfter)
{
m_stopAfter = _stopAfter;
if (m_stackState < AnalysisPerformed)
if (!parseAndAnalyze())
if (!parseAndAnalyze(_stopAfter))
return false;
if (m_stackState >= m_stopAfter)
return true;
if (m_hasError)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Called compile with errors."));
@ -574,7 +573,7 @@ void CompilerStack::link()
vector<string> CompilerStack::contractNames() const
{
if (m_stackState < AnalysisPerformed)
if (m_stackState < Parsed)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
vector<string> contractNames;
for (auto const& contract: m_contracts)
@ -921,7 +920,7 @@ Scanner const& CompilerStack::scanner(string const& _sourceName) const
SourceUnit const& CompilerStack::ast(string const& _sourceName) const
{
if (m_stackState < ParsingPerformed)
if (m_stackState < Parsed)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing not yet performed."));
if (!source(_sourceName).ast && !m_parserErrorRecovery)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
@ -994,7 +993,7 @@ string const& CompilerStack::Source::ipfsUrl() const
StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath)
{
solAssert(m_stackState < ParsingPerformed, "");
solAssert(m_stackState < ParsedAndImported, "");
StringMap newSources;
try
{
@ -1038,7 +1037,7 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string
string CompilerStack::applyRemapping(string const& _path, string const& _context)
{
solAssert(m_stackState < ParsingPerformed, "");
solAssert(m_stackState < ParsedAndImported, "");
// Try to find the longest prefix match in all remappings that are active in the current context.
auto isPrefixOf = [](string const& _a, string const& _b)
{
@ -1080,7 +1079,7 @@ string CompilerStack::applyRemapping(string const& _path, string const& _context
void CompilerStack::resolveImports()
{
solAssert(m_stackState == ParsingPerformed, "");
solAssert(m_stackState == ParsedAndImported, "");
// topological sorting (depth first search) of the import graph, cutting potential cycles
vector<Source const*> sourceOrder;
@ -1110,6 +1109,24 @@ void CompilerStack::resolveImports()
swap(m_sourceOrder, sourceOrder);
}
void CompilerStack::storeContractDefinitions()
{
for (auto const& pair: m_sources)
if (pair.second.ast)
for (
ContractDefinition const* contract:
ASTNode::filteredNodes<ContractDefinition>(pair.second.ast->nodes())
)
{
string fullyQualifiedName = *pair.second.ast->annotation().path + ":" + contract->name();
// Note that we now reference contracts by their fully qualified names, and
// thus contracts can only conflict if declared in the same source file. This
// should already cause a double-declaration error elsewhere.
if (!m_contracts.count(fullyQualifiedName))
m_contracts[fullyQualifiedName].contract = contract;
}
}
namespace
{
bool onlySafeExperimentalFeaturesActivated(set<ExperimentalFeature> const& features)

View File

@ -90,7 +90,8 @@ public:
enum State {
Empty,
SourcesSet,
ParsingPerformed,
Parsed,
ParsedAndImported,
AnalysisPerformed,
CompilationSuccessful
};
@ -216,11 +217,11 @@ public:
/// Parses and analyzes all source units that were added
/// @returns false on error.
bool parseAndAnalyze();
bool parseAndAnalyze(State _stopAfter = State::CompilationSuccessful);
/// Compiles the source units that were previously added and parsed.
/// @returns false on error.
bool compile();
bool compile(State _stopAfter = State::CompilationSuccessful);
/// @returns the list of sources (paths) used
std::vector<std::string> sourceNames() const;
@ -373,6 +374,9 @@ private:
std::string applyRemapping(std::string const& _path, std::string const& _context);
void resolveImports();
/// Store the contract definitions in m_contracts.
void storeContractDefinitions();
/// @returns true if the source is requested to be compiled.
bool isRequestedSource(std::string const& _sourceName) const;
@ -446,6 +450,7 @@ private:
ReadCallback::Callback m_readFile;
OptimiserSettings m_optimiserSettings;
RevertStrings m_revertStrings = RevertStrings::Default;
State m_stopAfter = State::CompilationSuccessful;
langutil::EVMVersion m_evmVersion;
smtutil::SMTSolverChoice m_enabledSMTSolvers;
std::map<std::string, std::set<std::string>> m_requestedContractNames;

View File

@ -414,7 +414,7 @@ std::optional<Json::Value> checkAuxiliaryInputKeys(Json::Value const& _input)
std::optional<Json::Value> checkSettingsKeys(Json::Value const& _input)
{
static set<string> keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings"};
static set<string> keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings", "stopAfter"};
return checkKeys(_input, keys, "settings");
}
@ -724,6 +724,17 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (auto result = checkSettingsKeys(settings))
return *result;
if (settings.isMember("stopAfter"))
{
if (!settings["stopAfter"].isString())
return formatFatalError("JSONError", "\"settings.stopAfter\" must be a string.");
if (settings["stopAfter"].asString() != "parsing")
return formatFatalError("JSONError", "Invalid value for \"settings.stopAfter\". Only valid value is \"parsing\".");
ret.stopAfter = CompilerStack::State::Parsed;
}
if (settings.isMember("parserErrorRecovery"))
{
if (!settings["parserErrorRecovery"].isBool())
@ -849,6 +860,12 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
ret.outputSelection = std::move(outputSelection);
if (ret.stopAfter != CompilerStack::State::CompilationSuccessful && isBinaryRequested(ret.outputSelection))
return formatFatalError(
"JSONError",
"Requested output selection conflicts with \"settings.stopAfter\"."
);
return { std::move(ret) };
}
@ -883,7 +900,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
if (binariesRequested)
compilerStack.compile();
else
compilerStack.parseAndAnalyze();
compilerStack.parseAndAnalyze(_inputsAndSettings.stopAfter);
for (auto const& error: compilerStack.errors())
{
@ -1005,7 +1022,10 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
analysisPerformed = false;
/// Inconsistent state - stop here to receive error reports from users
if (((binariesRequested && !compilationSuccess) || !analysisPerformed) && errors.empty())
if (
((binariesRequested && !compilationSuccess) || !analysisPerformed) &&
(errors.empty() && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisPerformed)
)
return formatFatalError("InternalCompilerError", "No error reported, but compilation failed.");
Json::Value output = Json::objectValue;
@ -1021,16 +1041,17 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
for (string const& sourceName: analysisPerformed ? compilerStack.sourceNames() : vector<string>())
{
Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++;
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "ast", wildcardMatchesExperimental))
sourceResult["ast"] = ASTJsonConverter(false, compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName));
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "legacyAST", wildcardMatchesExperimental))
sourceResult["legacyAST"] = ASTJsonConverter(true, compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName));
output["sources"][sourceName] = sourceResult;
}
if (compilerStack.state() >= CompilerStack::State::Parsed && (!compilerStack.hasError() || _inputsAndSettings.parserErrorRecovery))
for (string const& sourceName: compilerStack.sourceNames())
{
Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++;
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "ast", wildcardMatchesExperimental))
sourceResult["ast"] = ASTJsonConverter(false, compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName));
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "legacyAST", wildcardMatchesExperimental))
sourceResult["legacyAST"] = ASTJsonConverter(true, compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName));
output["sources"][sourceName] = sourceResult;
}
Json::Value contractsOutput = Json::objectValue;
for (string const& contractName: analysisPerformed ? compilerStack.contractNames() : vector<string>())

View File

@ -60,6 +60,7 @@ private:
std::string language;
Json::Value errors;
bool parserErrorRecovery = false;
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
std::map<std::string, std::string> sources;
std::map<util::h256, std::string> smtLib2Responses;
langutil::EVMVersion evmVersion;

View File

@ -223,8 +223,8 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
"1123", "1133", "1220", "1584", "1823", "1950",
"1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856",
"3263", "3356", "3441", "3682", "3876",
"3893", "3997", "4010", "4281", "4802", "4805", "4828",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5333", "5347", "5473",
"3893", "4010", "4281", "4802", "4805", "4828",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5347", "5473",
"5622", "6041", "6052", "6272", "6708", "6792", "6931", "7110", "7128", "7186",
"7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140",
"8261", "8312", "8592", "8758", "9011",

View File

@ -114,7 +114,7 @@ do
SOL_FILES+=("$line")
done < <(
grep -riL -E \
"^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (6275|3716|6281|2837|6933)|^==== Source:" \
"^\/\/ (Syntax|Type|Declaration)Error|^\/\/ ParserError (2837|3716|3997|5333|6275|6281|6933|7319)|^==== Source:" \
"${ROOT_DIR}/test/libsolidity/syntaxTests" \
"${ROOT_DIR}/test/libsolidity/semanticTests" \
)

View File

@ -115,8 +115,11 @@ do
fi
fi
EWASM_ARGS=""
[ "${vm}" = "byzantium" ] && [ "${optimize}" = "" ] && EWASM_ARGS="--ewasm"
set +e
"${SOLIDITY_BUILD_DIR}"/test/soltest --show-progress $log -- --testpath "$REPO_ROOT"/test "$optimize" --evm-version "$vm" $SMT_FLAGS $force_abiv2_flag
"${SOLIDITY_BUILD_DIR}"/test/soltest --show-progress $log -- ${EWASM_ARGS} --testpath "$REPO_ROOT"/test "$optimize" --evm-version "$vm" $SMT_FLAGS $force_abiv2_flag
if test "0" -ne "$?"; then
exit 1

View File

@ -159,6 +159,8 @@ static string const g_strOutputDir = "output-dir";
static string const g_strOverwrite = "overwrite";
static string const g_strRevertStrings = "revert-strings";
static string const g_strStorageLayout = "storage-layout";
static string const g_strStopAfter = "stop-after";
static string const g_strParsing = "parsing";
/// Possible arguments to for --revert-strings
static set<string> const g_revertStringsArgs
@ -320,6 +322,17 @@ static bool needsHumanTargetedStdout(po::variables_map const& _args)
return false;
}
bool checkMutuallyExclusive(boost::program_options::variables_map const& args, std::string const& _optionA, std::string const& _optionB)
{
if (args.count(_optionA) && args.count(_optionB))
{
serr() << "Option " << _optionA << " and " << _optionB << " are mutually exclusive." << endl;
return false;
}
return true;
}
void CommandLineInterface::handleBinary(string const& _contract)
{
if (m_args.count(g_argBinary))
@ -804,6 +817,11 @@ General Information)").c_str(),
po::value<string>()->value_name(boost::join(g_revertStringsArgs, ",")),
"Strip revert (and require) reason strings or add additional debugging information."
)
(
g_strStopAfter.c_str(),
po::value<string>()->value_name("stage"),
"Stop execution after the given compiler stage. Valid options: \"parsing\"."
)
;
desc.add(outputOptions);
@ -996,11 +1014,23 @@ General Information)").c_str(),
return false;
}
if (m_args.count(g_argColor) && m_args.count(g_argNoColor))
{
serr() << "Option " << g_argColor << " and " << g_argNoColor << " are mutualy exclusive." << endl;
if (!checkMutuallyExclusive(m_args, g_argColor, g_argNoColor))
return false;
}
static vector<string> const conflictingWithStopAfter{
g_argBinary,
g_argIR,
g_argIROptimized,
g_argEwasm,
g_argGas,
g_argAsm,
g_argAsmJson,
g_argOpcodes
};
for (auto& option: conflictingWithStopAfter)
if (!checkMutuallyExclusive(m_args, g_strStopAfter, option))
return false;
m_coloredOutput = !m_args.count(g_argNoColor) && (isatty(STDERR_FILENO) || m_args.count(g_argColor));
@ -1138,6 +1168,17 @@ bool CommandLineInterface::processInput()
}
}
if (m_args.count(g_strStopAfter))
{
if (m_args[g_strStopAfter].as<string>() != "parsing")
{
serr() << "Valid options for --" << g_strStopAfter << " are: \"parsing\".\n";
return false;
}
else
m_stopAfter = CompilerStack::State::Parsed;
}
vector<string> const exclusiveModes = {
g_argStandardJSON,
g_argLink,
@ -1417,7 +1458,7 @@ bool CommandLineInterface::processInput()
m_compiler->setParserErrorRecovery(true);
}
bool successful = m_compiler->compile();
bool successful = m_compiler->compile(m_stopAfter);
for (auto const& error: m_compiler->errors())
{
@ -1565,7 +1606,7 @@ void CommandLineInterface::handleCombinedJSON()
output[g_strSources] = Json::Value(Json::objectValue);
for (auto const& sourceCode: m_sourceCodes)
{
ASTJsonConverter converter(legacyFormat, m_compiler->sourceIndices());
ASTJsonConverter converter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices());
output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue);
output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first));
}
@ -1617,7 +1658,7 @@ void CommandLineInterface::handleAst(string const& _argStr)
{
stringstream data;
string postfix = "";
ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first));
ASTJsonConverter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first));
postfix += "_json";
boost::filesystem::path path(sourceCode.first);
createFile(path.filename().string() + postfix + ".ast", data.str());
@ -1629,7 +1670,7 @@ void CommandLineInterface::handleAst(string const& _argStr)
for (auto const& sourceCode: m_sourceCodes)
{
sout() << endl << "======= " << sourceCode.first << " =======" << endl;
ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first));
ASTJsonConverter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first));
}
}
}
@ -1871,7 +1912,10 @@ void CommandLineInterface::outputCompilationResults()
handleAst(g_argAstJson);
handleAst(g_argAstCompactJson);
if (!m_compiler->compilationSuccessful())
if (
!m_compiler->compilationSuccessful() &&
m_stopAfter == CompilerStack::State::CompilationSuccessful
)
{
serr() << endl << "Compilation halted after AST generation due to errors." << endl;
return;

View File

@ -127,6 +127,7 @@ private:
std::map<std::string, util::h160> m_libraries;
/// Solidity compiler stack
std::unique_ptr<frontend::CompilerStack> m_compiler;
CompilerStack::State m_stopAfter = CompilerStack::State::CompilationSuccessful;
/// EVM version to use
langutil::EVMVersion m_evmVersion;
/// How to handle revert strings

View File

@ -439,6 +439,9 @@ SOLTMPDIR=$(mktemp -d)
)
rm -rf "$SOLTMPDIR"
printTask "Testing AST export with stop-after=parsing..."
"$REPO_ROOT/test/stopAfterParseTests.sh"
printTask "Testing soljson via the fuzzer..."
SOLTMPDIR=$(mktemp -d)
(

View File

@ -1,4 +1,4 @@
{"errors":[{"component":"general","errorCode":"2904","formattedMessage":":2:24: DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\").
pragma solidity >=0.0; import {A} from \".\";
^------------------^
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{}}
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{"":{"id":0}}}

View File

@ -0,0 +1,16 @@
from rule import Rule
from opcodes import *
from util import *
"""
Checking conversion of exp(-1, X) to sub(isZero(and(X, 1)), and(X, 1))
"""
rule = Rule()
n_bits = 256
X = BitVec('X', n_bits)
exp_neg_one = If(MOD(X, 2) == 0, BitVecVal(1, n_bits), BVUnsignedMax(n_bits, n_bits))
rule.check(SUB(ISZERO(AND(X, 1)), AND(X, 1)), exp_neg_one)

View File

@ -0,0 +1,54 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": true,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "37:4:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "34:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "37:0:1"
},
"src": "23:18:1",
"stateMutability": "nonpayable",
"virtual": false
}
],
"src": "0:43:1"
}
],
"src": "0:44:1"
}

View File

@ -0,0 +1,370 @@
{
"absolutePath": "a",
"id": 40,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 39,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "m",
"nodeType": "VariableDeclaration",
"src": "17:44:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"keyType":
{
"id": 1,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "25:7:1",
"typeDescriptions": {}
},
"nodeType": "Mapping",
"src": "17:35:1",
"typeDescriptions": {},
"valueType":
{
"id": 2,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "36:15:1",
"stateMutability": "payable",
"typeDescriptions": {}
}
},
"visibility": "public"
},
{
"body":
{
"id": 37,
"nodeType": "Block",
"src": "134:122:1",
"statements":
[
{
"assignments":
[
12
],
"declarations":
[
{
"constant": false,
"id": 12,
"mutability": "mutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "144:17:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 11,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "144:15:1",
"stateMutability": "payable",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 16,
"initialValue":
{
"baseExpression":
{
"id": 13,
"name": "m",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "164:1:1",
"typeDescriptions": {}
},
"id": 15,
"indexExpression":
{
"id": 14,
"name": "arg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "166:3:1",
"typeDescriptions": {}
},
"nodeType": "IndexAccess",
"src": "164:6:1",
"typeDescriptions": {}
},
"nodeType": "VariableDeclarationStatement",
"src": "144:26:1"
},
{
"expression":
{
"id": 19,
"leftHandSide":
{
"id": 17,
"name": "r",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "180:1:1",
"typeDescriptions": {}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide":
{
"id": 18,
"name": "arg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "184:3:1",
"typeDescriptions": {}
},
"src": "180:7:1",
"typeDescriptions": {}
},
"id": 20,
"nodeType": "ExpressionStatement",
"src": "180:7:1"
},
{
"assignments":
[
22
],
"declarations":
[
{
"constant": false,
"id": 22,
"mutability": "mutable",
"name": "c",
"nodeType": "VariableDeclaration",
"src": "197:9:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 21,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "197:7:1",
"stateMutability": "nonpayable",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 27,
"initialValue":
{
"arguments":
[
{
"id": 25,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "217:4:1",
"typeDescriptions": {}
}
],
"expression":
{
"id": 24,
"nodeType": "ElementaryTypeNameExpression",
"src": "209:7:1",
"typeDescriptions": {},
"typeName":
{
"id": 23,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "209:7:1",
"typeDescriptions": {}
}
},
"id": 26,
"names": [],
"nodeType": "FunctionCall",
"src": "209:13:1",
"tryCall": false,
"typeDescriptions": {}
},
"nodeType": "VariableDeclarationStatement",
"src": "197:25:1"
},
{
"expression":
{
"id": 35,
"leftHandSide":
{
"baseExpression":
{
"id": 28,
"name": "m",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "232:1:1",
"typeDescriptions": {}
},
"id": 30,
"indexExpression":
{
"id": 29,
"name": "c",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "234:1:1",
"typeDescriptions": {}
},
"nodeType": "IndexAccess",
"src": "232:4:1",
"typeDescriptions": {}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide":
{
"arguments":
[
{
"hexValue": "30",
"id": 33,
"kind": "number",
"nodeType": "Literal",
"src": "247:1:1",
"typeDescriptions": {},
"value": "0"
}
],
"expression":
{
"id": 32,
"nodeType": "ElementaryTypeNameExpression",
"src": "239:7:1",
"typeDescriptions": {},
"typeName":
{
"id": 31,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "239:7:1",
"typeDescriptions": {}
}
},
"id": 34,
"names": [],
"nodeType": "FunctionCall",
"src": "239:10:1",
"tryCall": false,
"typeDescriptions": {}
},
"src": "232:17:1",
"typeDescriptions": {}
},
"id": 36,
"nodeType": "ExpressionStatement",
"src": "232:17:1"
}
]
},
"id": 38,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 6,
"mutability": "mutable",
"name": "arg",
"nodeType": "VariableDeclaration",
"src": "78:19:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 5,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "78:15:1",
"stateMutability": "payable",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "77:21:1"
},
"returnParameters":
{
"id": 10,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 9,
"mutability": "mutable",
"name": "r",
"nodeType": "VariableDeclaration",
"src": "115:17:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 8,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "115:15:1",
"stateMutability": "payable",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "114:19:1"
},
"src": "67:189:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:258:1"
}
],
"src": "0:259:1"
}

View File

@ -0,0 +1,49 @@
{
"absolutePath": "a",
"id": 5,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 4,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 3,
"mutability": "mutable",
"name": "i",
"nodeType": "VariableDeclaration",
"src": "13:8:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"baseType":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "13:4:1",
"typeDescriptions": {}
},
"id": 2,
"nodeType": "ArrayTypeName",
"src": "13:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "0:24:1"
}
],
"src": "0:25:1"
}

View File

@ -0,0 +1,152 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "37:59:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "56:34:1",
"statements":
[
{
"expression":
{
"arguments":
[
{
"arguments":
[
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "67:1:1",
"type": "",
"value": "0"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "70:1:1",
"type": "",
"value": "1"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "73:1:1",
"type": "",
"value": "2"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "76:1:1",
"type": "",
"value": "3"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "79:1:1",
"type": "",
"value": "4"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "82:1:1",
"type": "",
"value": "5"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "85:1:1",
"type": "",
"value": "6"
}
],
"functionName":
{
"name": "call",
"nodeType": "YulIdentifier",
"src": "62:4:1"
},
"nodeType": "YulFunctionCall",
"src": "62:25:1"
}
],
"functionName":
{
"name": "pop",
"nodeType": "YulIdentifier",
"src": "58:3:1"
},
"nodeType": "YulFunctionCall",
"src": "58:30:1"
},
"nodeType": "YulExpressionStatement",
"src": "58:30:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "47:43:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "j",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "37:0:1"
},
"src": "17:79:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:98:1"
}
],
"src": "0:99:1"
}

View File

@ -0,0 +1,77 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:31:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:6:1",
"statements":
[
{
"nodeType": "YulBlock",
"src": "63:2:1",
"statements": []
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:15:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "g",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:56:1",
"stateMutability": "view",
"virtual": false,
"visibility": "public"
}
],
"src": "0:75:1"
}
],
"src": "0:76:1"
}

View File

@ -0,0 +1,139 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:68:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:43:1",
"statements":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "76:22:1",
"statements":
[
{
"expression":
{
"arguments":
[
{
"arguments":
[
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "92:2:1",
"type": "",
"value": "20"
}
],
"functionName":
{
"name": "blockhash",
"nodeType": "YulIdentifier",
"src": "82:9:1"
},
"nodeType": "YulFunctionCall",
"src": "82:13:1"
}
],
"functionName":
{
"name": "pop",
"nodeType": "YulIdentifier",
"src": "78:3:1"
},
"nodeType": "YulFunctionCall",
"src": "78:18:1"
},
"nodeType": "YulExpressionStatement",
"src": "78:18:1"
}
]
},
"name": "g",
"nodeType": "YulFunctionDefinition",
"src": "63:35:1"
},
{
"expression":
{
"arguments": [],
"functionName":
{
"name": "g",
"nodeType": "YulIdentifier",
"src": "99:1:1"
},
"nodeType": "YulFunctionCall",
"src": "99:3:1"
},
"nodeType": "YulExpressionStatement",
"src": "99:3:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:52:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "h",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:93:1",
"stateMutability": "view",
"virtual": false,
"visibility": "public"
}
],
"src": "0:112:1"
}
],
"src": "0:113:1"
}

View File

@ -0,0 +1,89 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "37:51:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "56:26:1",
"statements":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "71:9:1",
"statements":
[
{
"nodeType": "YulLeave",
"src": "73:5:1"
}
]
},
"name": "f",
"nodeType": "YulFunctionDefinition",
"src": "58:22:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "47:35:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "l",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "37:0:1"
},
"src": "17:71:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:90:1"
}
],
"src": "0:91:1"
}

View File

@ -0,0 +1,152 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:74:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:49:1",
"statements":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "90:18:1",
"statements":
[
{
"nodeType": "YulBreak",
"src": "92:5:1"
},
{
"nodeType": "YulContinue",
"src": "98:8:1"
}
]
},
"condition":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "70:1:1",
"type": "",
"value": "1"
},
"nodeType": "YulForLoop",
"post":
{
"nodeType": "YulBlock",
"src": "72:17:1",
"statements":
[
{
"expression":
{
"arguments":
[
{
"arguments":
[
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "84:1:1",
"type": "",
"value": "0"
}
],
"functionName":
{
"name": "sload",
"nodeType": "YulIdentifier",
"src": "78:5:1"
},
"nodeType": "YulFunctionCall",
"src": "78:8:1"
}
],
"functionName":
{
"name": "pop",
"nodeType": "YulIdentifier",
"src": "74:3:1"
},
"nodeType": "YulFunctionCall",
"src": "74:13:1"
},
"nodeType": "YulExpressionStatement",
"src": "74:13:1"
}
]
},
"pre":
{
"nodeType": "YulBlock",
"src": "67:2:1",
"statements": []
},
"src": "63:45:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:58:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "g",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:99:1",
"stateMutability": "view",
"virtual": false,
"visibility": "public"
}
],
"src": "0:118:1"
}
],
"src": "0:119:1"
}

View File

@ -94,7 +94,6 @@
}
]
},
"functionSelector": "26121ff0",
"id": 7,
"implemented": true,
"kind": "function",

View File

@ -37,7 +37,6 @@
{
"attributes":
{
"functionSelector": "26121ff0",
"implemented": true,
"isConstructor": false,
"kind": "function",

View File

@ -0,0 +1,138 @@
{
"absolutePath": "a",
"id": 9,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 8,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 6,
"nodeType": "Block",
"src": "57:97:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "72:78:1",
"statements":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "94:50:1",
"statements":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "118:3:1",
"statements": []
},
"name": "f2",
"nodeType": "YulFunctionDefinition",
"src": "104:17:1"
},
{
"nodeType": "YulAssignment",
"src": "130:6:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "135:1:1",
"type": "",
"value": "2"
},
"variableNames":
[
{
"name": "x",
"nodeType": "YulIdentifier",
"src": "130:1:1"
}
]
}
]
},
"name": "f1",
"nodeType": "YulFunctionDefinition",
"src": "80:64:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 5,
"nodeType": "InlineAssembly",
"src": "63:87:1"
}
]
},
"id": 7,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "25:2:1"
},
"returnParameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 3,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "49:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "49:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "48:8:1"
},
"src": "15:139:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "public"
}
],
"src": "0:156:1"
}
],
"src": "0:157:1"
}

View File

@ -0,0 +1,180 @@
{
"absolutePath": "a",
"id": 12,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 11,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"id": 3,
"members":
[
{
"constant": false,
"id": 2,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "28:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "28:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"name": "S",
"nodeType": "StructDefinition",
"src": "17:20:1",
"visibility": "public"
},
{
"constant": false,
"id": 5,
"mutability": "mutable",
"name": "s",
"nodeType": "VariableDeclaration",
"src": "42:3:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 4,
"name": "S",
"nodeType": "UserDefinedTypeName",
"src": "42:1:1",
"typeDescriptions": {}
},
"visibility": "internal"
},
{
"body":
{
"id": 9,
"nodeType": "Block",
"src": "76:70:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "95:45:1",
"statements":
[
{
"nodeType": "YulVariableDeclaration",
"src": "97:17:1",
"value":
{
"name": "s.offset",
"nodeType": "YulIdentifier",
"src": "106:8:1"
},
"variables":
[
{
"name": "x",
"nodeType": "YulTypedName",
"src": "101:1:1",
"type": ""
}
]
},
{
"nodeType": "YulVariableDeclaration",
"src": "115:23:1",
"value":
{
"arguments":
[
{
"name": "s.slot",
"nodeType": "YulIdentifier",
"src": "128:6:1"
},
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "136:1:1",
"type": "",
"value": "2"
}
],
"functionName":
{
"name": "mul",
"nodeType": "YulIdentifier",
"src": "124:3:1"
},
"nodeType": "YulFunctionCall",
"src": "124:14:1"
},
"variables":
[
{
"name": "y",
"nodeType": "YulTypedName",
"src": "119:1:1",
"type": ""
}
]
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 8,
"nodeType": "InlineAssembly",
"src": "86:54:1"
}
]
},
"id": 10,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "e",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 6,
"nodeType": "ParameterList",
"parameters": [],
"src": "61:2:1"
},
"returnParameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters": [],
"src": "76:0:1"
},
"src": "51:95:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "public"
}
],
"src": "0:148:1"
}
],
"src": "0:149:1"
}

View File

@ -0,0 +1,93 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "37:43:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "56:18:1",
"statements":
[
{
"nodeType": "YulVariableDeclaration",
"src": "58:14:1",
"value":
{
"kind": "string",
"nodeType": "YulLiteral",
"src": "67:5:1",
"type": "",
"value": "abc"
},
"variables":
[
{
"name": "x",
"nodeType": "YulTypedName",
"src": "62:1:1",
"type": ""
}
]
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "47:27:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "m",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "37:0:1"
},
"src": "17:63:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:82:1"
}
],
"src": "0:83:1"
}

View File

@ -179,7 +179,6 @@
}
]
},
"functionSelector": "26121ff0",
"id": 5,
"implemented": true,
"kind": "function",

View File

@ -0,0 +1,116 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:58:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:33:1",
"statements":
[
{
"cases":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "79:2:1",
"statements": []
},
"nodeType": "YulCase",
"src": "72:9:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "77:1:1",
"type": "",
"value": "0"
}
},
{
"body":
{
"nodeType": "YulBlock",
"src": "90:2:1",
"statements": []
},
"nodeType": "YulCase",
"src": "82:10:1",
"value": "default"
}
],
"expression":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "70:1:1",
"type": "",
"value": "0"
},
"nodeType": "YulSwitch",
"src": "63:29:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:42:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "g",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:83:1",
"stateMutability": "view",
"virtual": false,
"visibility": "public"
}
],
"src": "0:102:1"
}
],
"src": "0:103:1"
}

View File

@ -37,7 +37,6 @@
{
"attributes":
{
"functionSelector": "26121ff0",
"implemented": true,
"isConstructor": false,
"kind": "function",

View File

@ -0,0 +1,185 @@
{
"absolutePath": "a",
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 6,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:154:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:129:1",
"statements":
[
{
"nodeType": "YulVariableDeclaration",
"src": "75:10:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "84:1:1",
"type": "",
"value": "0"
},
"variables":
[
{
"name": "f",
"nodeType": "YulTypedName",
"src": "79:1:1",
"type": ""
}
]
},
{
"cases":
[
{
"body":
{
"nodeType": "YulBlock",
"src": "139:10:1",
"statements":
[
{
"nodeType": "YulAssignment",
"src": "141:6:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "146:1:1",
"type": "",
"value": "1"
},
"variableNames":
[
{
"name": "f",
"nodeType": "YulIdentifier",
"src": "141:1:1"
}
]
}
]
},
"nodeType": "YulCase",
"src": "132:17:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "137:1:1",
"type": "",
"value": "0"
}
},
{
"body":
{
"nodeType": "YulBlock",
"src": "170:10:1",
"statements":
[
{
"nodeType": "YulAssignment",
"src": "172:6:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "177:1:1",
"type": "",
"value": "2"
},
"variableNames":
[
{
"name": "f",
"nodeType": "YulIdentifier",
"src": "172:1:1"
}
]
}
]
},
"nodeType": "YulCase",
"src": "162:18:1",
"value": "default"
}
],
"expression":
{
"arguments": [],
"functionName":
{
"name": "calldatasize",
"nodeType": "YulIdentifier",
"src": "105:12:1"
},
"nodeType": "YulFunctionCall",
"src": "105:14:1"
},
"nodeType": "YulSwitch",
"src": "98:82:1"
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:138:1"
}
]
},
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:179:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "public"
}
],
"src": "0:198:1"
}
],
"src": "0:199:1"
}

View File

@ -0,0 +1,124 @@
{
"absolutePath": "a",
"id": 10,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 9,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 7,
"nodeType": "Block",
"src": "42:51:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "52:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "52:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 5,
"nodeType": "VariableDeclarationStatement",
"src": "52:6:1"
},
{
"AST":
{
"nodeType": "YulBlock",
"src": "77:10:1",
"statements":
[
{
"nodeType": "YulAssignment",
"src": "79:6:1",
"value":
{
"kind": "number",
"nodeType": "YulLiteral",
"src": "84:1:1",
"type": "",
"value": "7"
},
"variableNames":
[
{
"name": "x",
"nodeType": "YulIdentifier",
"src": "79:1:1"
}
]
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 6,
"nodeType": "InlineAssembly",
"src": "68:19:1"
}
]
},
"id": 8,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "17:76:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "public"
}
],
"src": "0:95:1"
}
],
"src": "0:96:1"
}

View File

@ -0,0 +1,54 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "28:4:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "25:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "28:0:1"
},
"src": "14:18:1",
"stateMutability": "nonpayable",
"virtual": false
}
],
"src": "0:34:1"
}
],
"src": "0:35:1"
}

View File

@ -0,0 +1,124 @@
{
"absolutePath": "a",
"id": 14,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 1,
"name": "A",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "0:14:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 2,
"name": "A",
"nodeType": "UserDefinedTypeName",
"src": "29:1:1",
"typeDescriptions": {}
},
"id": 3,
"nodeType": "InheritanceSpecifier",
"src": "29:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 4,
"name": "B",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "15:19:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 5,
"name": "B",
"nodeType": "UserDefinedTypeName",
"src": "49:1:1",
"typeDescriptions": {}
},
"id": 6,
"nodeType": "InheritanceSpecifier",
"src": "49:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 7,
"name": "C",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "35:19:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 8,
"name": "C",
"nodeType": "UserDefinedTypeName",
"src": "69:1:1",
"typeDescriptions": {}
},
"id": 9,
"nodeType": "InheritanceSpecifier",
"src": "69:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 10,
"name": "D",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "55:19:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 11,
"name": "D",
"nodeType": "UserDefinedTypeName",
"src": "89:1:1",
"typeDescriptions": {}
},
"id": 12,
"nodeType": "InheritanceSpecifier",
"src": "89:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 13,
"name": "E",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "75:19:1"
}
],
"src": "0:95:1"
}

View File

@ -0,0 +1,195 @@
[
{
"absolutePath": "a",
"id": 3,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation":
{
"id": 1,
"nodeType": "StructuredDocumentation",
"src": "0:27:1",
"text": "This contract is empty"
},
"id": 2,
"name": "C",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "28:13:1"
}
],
"src": "28:14:1"
},
{
"absolutePath": "b",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation":
{
"id": 4,
"nodeType": "StructuredDocumentation",
"src": "0:61:2",
"text": "This contract is empty\nand has a line-breaking comment."
},
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "62:13:2"
}
],
"src": "62:14:2"
},
{
"absolutePath": "c",
"id": 24,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 23,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 9,
"mutability": "mutable",
"name": "state",
"nodeType": "VariableDeclaration",
"src": "48:17:3",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 8,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "48:4:3",
"typeDescriptions": {}
},
"visibility": "public"
},
{
"anonymous": false,
"documentation":
{
"id": 10,
"nodeType": "StructuredDocumentation",
"src": "69:26:3",
"text": "Some comment on Evt."
},
"id": 12,
"name": "Evt",
"nodeType": "EventDefinition",
"parameters":
{
"id": 11,
"nodeType": "ParameterList",
"parameters": [],
"src": "105:2:3"
},
"src": "96:12:3"
},
{
"body":
{
"id": 16,
"nodeType": "Block",
"src": "153:6:3",
"statements":
[
{
"id": 15,
"nodeType": "PlaceholderStatement",
"src": "155:1:3"
}
]
},
"documentation":
{
"id": 13,
"nodeType": "StructuredDocumentation",
"src": "111:26:3",
"text": "Some comment on mod."
},
"id": 17,
"name": "mod",
"nodeType": "ModifierDefinition",
"parameters":
{
"id": 14,
"nodeType": "ParameterList",
"parameters": [],
"src": "150:2:3"
},
"src": "138:21:3",
"virtual": false,
"visibility": "internal"
},
{
"body":
{
"id": 21,
"nodeType": "Block",
"src": "209:2:3",
"statements": []
},
"documentation":
{
"id": 18,
"nodeType": "StructuredDocumentation",
"src": "162:25:3",
"text": "Some comment on fn."
},
"id": 22,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "fn",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 19,
"nodeType": "ParameterList",
"parameters": [],
"src": "199:2:3"
},
"returnParameters":
{
"id": 20,
"nodeType": "ParameterList",
"parameters": [],
"src": "209:0:3"
},
"src": "188:23:3",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:213:3"
}
],
"src": "0:214:3"
}
]

View File

@ -0,0 +1,43 @@
{
"absolutePath": "a",
"id": 5,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 4,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"id": 3,
"members":
[
{
"id": 1,
"name": "A",
"nodeType": "EnumValue",
"src": "22:1:1"
},
{
"id": 2,
"name": "B",
"nodeType": "EnumValue",
"src": "25:1:1"
}
],
"name": "E",
"nodeType": "EnumDefinition",
"src": "13:15:1"
}
],
"src": "0:30:1"
}
],
"src": "0:31:1"
}

View File

@ -0,0 +1,36 @@
{
"absolutePath": "a",
"id": 4,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 3,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"anonymous": false,
"id": 2,
"name": "E",
"nodeType": "EventDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "20:2:1"
},
"src": "13:10:1"
}
],
"src": "0:25:1"
}
],
"src": "0:26:1"
}

View File

@ -0,0 +1,88 @@
{
"absolutePath": "a",
"id": 10,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 9,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "42:5:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "receive",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "22:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "15:32:1",
"stateMutability": "payable",
"virtual": false,
"visibility": "external"
},
{
"body":
{
"id": 7,
"nodeType": "Block",
"src": "78:5:1",
"statements": []
},
"id": 8,
"implemented": true,
"kind": "fallback",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 5,
"nodeType": "ParameterList",
"parameters": [],
"src": "58:2:1"
},
"returnParameters":
{
"id": 6,
"nodeType": "ParameterList",
"parameters": [],
"src": "78:0:1"
},
"src": "50:33:1",
"stateMutability": "payable",
"virtual": false,
"visibility": "external"
}
],
"src": "0:85:1"
}
],
"src": "0:86:1"
}

View File

@ -0,0 +1,55 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "43:5:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "fallback",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "43:0:1"
},
"src": "15:33:1",
"stateMutability": "payable",
"virtual": false,
"visibility": "external"
}
],
"src": "0:50:1"
}
],
"src": "0:51:1"
}

View File

@ -0,0 +1,55 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "34:2:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "fallback",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "22:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "34:0:1"
},
"src": "14:22:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "external"
}
],
"src": "0:38:1"
}
],
"src": "0:39:1"
}

View File

@ -0,0 +1,173 @@
{
"absolutePath": "a",
"id": 18,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 17,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 15,
"nodeType": "Block",
"src": "120:2:1",
"statements": []
},
"id": 16,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 6,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "24:44:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 5,
"nodeType": "FunctionTypeName",
"parameterTypes":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "32:2:1"
},
"returnParameterTypes":
{
"id": 4,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 3,
"mutability": "mutable",
"name": "",
"nodeType": "VariableDeclaration",
"src": "61:4:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "61:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "60:6:1"
},
"src": "24:44:1",
"stateMutability": "payable",
"typeDescriptions": {},
"visibility": "external"
},
"visibility": "internal"
}
],
"src": "23:46:1"
},
"returnParameters":
{
"id": 14,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 13,
"mutability": "mutable",
"name": "",
"nodeType": "VariableDeclaration",
"src": "79:40:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 12,
"nodeType": "FunctionTypeName",
"parameterTypes":
{
"id": 8,
"nodeType": "ParameterList",
"parameters": [],
"src": "87:2:1"
},
"returnParameterTypes":
{
"id": 11,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 10,
"mutability": "mutable",
"name": "",
"nodeType": "VariableDeclaration",
"src": "113:4:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 9,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "113:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "112:6:1"
},
"src": "79:40:1",
"stateMutability": "view",
"typeDescriptions": {},
"visibility": "external"
},
"visibility": "internal"
}
],
"src": "78:41:1"
},
"src": "13:109:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:124:1"
}
],
"src": "0:125:1"
}

View File

@ -0,0 +1,24 @@
{
"absolutePath": "a",
"id": 3,
"nodeType": "SourceUnit",
"nodes":
[
{
"id": 2,
"members":
[
{
"id": 1,
"name": "A",
"nodeType": "EnumValue",
"src": "9:1:1"
}
],
"name": "E",
"nodeType": "EnumDefinition",
"src": "0:12:1"
}
],
"src": "0:13:1"
}

View File

@ -0,0 +1,39 @@
{
"absolutePath": "a",
"id": 4,
"nodeType": "SourceUnit",
"nodes":
[
{
"id": 3,
"members":
[
{
"constant": false,
"id": 2,
"mutability": "mutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "11:9:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 1,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "11:7:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"name": "S",
"nodeType": "StructDefinition",
"src": "0:23:1",
"visibility": "public"
}
],
"src": "0:24:1"
}

View File

@ -0,0 +1,46 @@
{
"absolutePath": "a",
"id": 5,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 1,
"name": "C1",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "0:14:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 2,
"name": "C1",
"nodeType": "UserDefinedTypeName",
"src": "30:2:1",
"typeDescriptions": {}
},
"id": 3,
"nodeType": "InheritanceSpecifier",
"src": "30:2:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 4,
"name": "C2",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "15:20:1"
}
],
"src": "0:36:1"
}

View File

@ -0,0 +1,21 @@
{
"absolutePath": "a",
"id": 2,
"license": "GPL-3.0",
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 1,
"name": "C",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "36:13:1"
}
],
"src": "36:14:1"
}

View File

@ -0,0 +1,118 @@
{
"absolutePath": "a",
"id": 12,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 11,
"name": "c",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 9,
"nodeType": "Block",
"src": "33:19:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "35:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "35:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 8,
"initialValue":
{
"commonType": {},
"id": 7,
"leftExpression":
{
"hexValue": "32",
"id": 5,
"kind": "number",
"nodeType": "Literal",
"src": "44:1:1",
"typeDescriptions": {},
"value": "2"
},
"nodeType": "BinaryOperation",
"operator": "+",
"rightExpression":
{
"hexValue": "33",
"id": 6,
"kind": "number",
"nodeType": "Literal",
"src": "48:1:1",
"typeDescriptions": {},
"value": "3"
},
"src": "44:5:1",
"typeDescriptions": {}
},
"nodeType": "VariableDeclarationStatement",
"src": "35:14:1"
}
]
},
"id": 10,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:39:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:54:1"
}
],
"src": "0:55:1"
}

View File

@ -0,0 +1,132 @@
{
"absolutePath": "a",
"id": 16,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 15,
"name": "c",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 3,
"mutability": "mutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "13:8:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"baseType":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "13:4:1",
"typeDescriptions": {}
},
"id": 2,
"nodeType": "ArrayTypeName",
"src": "13:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
},
{
"body":
{
"id": 13,
"nodeType": "Block",
"src": "43:25:1",
"statements":
[
{
"assignments":
[
10
],
"declarations":
[
{
"constant": false,
"id": 10,
"mutability": "mutable",
"name": "b",
"nodeType": "VariableDeclaration",
"src": "45:16:1",
"stateVariable": false,
"storageLocation": "storage",
"typeDescriptions": {},
"typeName":
{
"baseType":
{
"id": 8,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "45:4:1",
"typeDescriptions": {}
},
"id": 9,
"nodeType": "ArrayTypeName",
"src": "45:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 12,
"initialValue":
{
"id": 11,
"name": "a",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "64:1:1",
"typeDescriptions": {}
},
"nodeType": "VariableDeclarationStatement",
"src": "45:20:1"
}
]
},
"id": 14,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:2:1"
},
"returnParameters":
{
"id": 5,
"nodeType": "ParameterList",
"parameters": [],
"src": "43:0:1"
},
"src": "23:45:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:70:1"
}
],
"src": "0:71:1"
}

View File

@ -0,0 +1,154 @@
{
"absolutePath": "a",
"id": 18,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 17,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"id": 4,
"members":
[
{
"id": 1,
"name": "A",
"nodeType": "EnumValue",
"src": "26:1:1"
},
{
"id": 2,
"name": "B",
"nodeType": "EnumValue",
"src": "29:1:1"
},
{
"id": 3,
"name": "C",
"nodeType": "EnumValue",
"src": "32:1:1"
}
],
"name": "E",
"nodeType": "EnumDefinition",
"src": "17:18:1"
},
{
"constant": false,
"id": 8,
"mutability": "mutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "40:20:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 7,
"keyType":
{
"id": 5,
"name": "C",
"nodeType": "UserDefinedTypeName",
"src": "48:1:1",
"typeDescriptions": {}
},
"nodeType": "Mapping",
"src": "40:18:1",
"typeDescriptions": {},
"valueType":
{
"id": 6,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "53:4:1",
"typeDescriptions": {}
}
},
"visibility": "internal"
},
{
"constant": false,
"id": 12,
"mutability": "mutable",
"name": "b",
"nodeType": "VariableDeclaration",
"src": "66:26:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 11,
"keyType":
{
"id": 9,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "74:7:1",
"typeDescriptions": {}
},
"nodeType": "Mapping",
"src": "66:24:1",
"typeDescriptions": {},
"valueType":
{
"id": 10,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "85:4:1",
"typeDescriptions": {}
}
},
"visibility": "internal"
},
{
"constant": false,
"id": 16,
"mutability": "mutable",
"name": "c",
"nodeType": "VariableDeclaration",
"src": "98:20:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 15,
"keyType":
{
"id": 13,
"name": "E",
"nodeType": "UserDefinedTypeName",
"src": "106:1:1",
"typeDescriptions": {}
},
"nodeType": "Mapping",
"src": "98:18:1",
"typeDescriptions": {},
"valueType":
{
"id": 14,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "111:4:1",
"typeDescriptions": {}
}
},
"visibility": "internal"
}
],
"src": "0:121:1"
}
],
"src": "0:122:1"
}

View File

@ -0,0 +1,134 @@
{
"absolutePath": "a",
"id": 15,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 14,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 5,
"nodeType": "Block",
"src": "32:6:1",
"statements":
[
{
"id": 4,
"nodeType": "PlaceholderStatement",
"src": "34:1:1"
}
]
},
"id": 6,
"name": "M",
"nodeType": "ModifierDefinition",
"parameters":
{
"id": 3,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 2,
"mutability": "mutable",
"name": "i",
"nodeType": "VariableDeclaration",
"src": "24:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "24:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "23:8:1"
},
"src": "13:25:1",
"virtual": false,
"visibility": "internal"
},
{
"body":
{
"id": 12,
"nodeType": "Block",
"src": "64:2:1",
"statements": []
},
"id": 13,
"implemented": true,
"kind": "function",
"modifiers":
[
{
"arguments":
[
{
"hexValue": "31",
"id": 9,
"kind": "number",
"nodeType": "Literal",
"src": "54:1:1",
"typeDescriptions": {},
"value": "1"
}
],
"id": 10,
"modifierName":
{
"id": 8,
"name": "M",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "52:1:1",
"typeDescriptions": {}
},
"nodeType": "ModifierInvocation",
"src": "52:4:1"
}
],
"name": "F",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters": [],
"src": "49:2:1"
},
"returnParameters":
{
"id": 11,
"nodeType": "ParameterList",
"parameters": [],
"src": "64:0:1"
},
"src": "39:27:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:68:1"
}
],
"src": "0:69:1"
}

View File

@ -0,0 +1,134 @@
{
"absolutePath": "a",
"id": 15,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 14,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 5,
"nodeType": "Block",
"src": "32:6:1",
"statements":
[
{
"id": 4,
"nodeType": "PlaceholderStatement",
"src": "34:1:1"
}
]
},
"id": 6,
"name": "M",
"nodeType": "ModifierDefinition",
"parameters":
{
"id": 3,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 2,
"mutability": "mutable",
"name": "i",
"nodeType": "VariableDeclaration",
"src": "24:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "24:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "23:8:1"
},
"src": "13:25:1",
"virtual": false,
"visibility": "internal"
},
{
"body":
{
"id": 12,
"nodeType": "Block",
"src": "64:2:1",
"statements": []
},
"id": 13,
"implemented": true,
"kind": "function",
"modifiers":
[
{
"arguments":
[
{
"hexValue": "31",
"id": 9,
"kind": "number",
"nodeType": "Literal",
"src": "54:1:1",
"typeDescriptions": {},
"value": "1"
}
],
"id": 10,
"modifierName":
{
"id": 8,
"name": "M",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "52:1:1",
"typeDescriptions": {}
},
"nodeType": "ModifierInvocation",
"src": "52:4:1"
}
],
"name": "F",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters": [],
"src": "49:2:1"
},
"returnParameters":
{
"id": 11,
"nodeType": "ParameterList",
"parameters": [],
"src": "64:0:1"
},
"src": "39:27:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:68:1"
}
],
"src": "0:69:1"
}

View File

@ -0,0 +1,112 @@
{
"absolutePath": "a",
"id": 11,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 10,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 3,
"mutability": "immutable",
"name": "a",
"nodeType": "VariableDeclaration",
"src": "17:27:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 1,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "17:4:1",
"typeDescriptions": {}
},
"value":
{
"hexValue": "34",
"id": 2,
"kind": "number",
"nodeType": "Literal",
"src": "43:1:1",
"typeDescriptions": {},
"value": "4"
},
"visibility": "public"
},
{
"constant": true,
"id": 6,
"mutability": "constant",
"name": "b",
"nodeType": "VariableDeclaration",
"src": "50:26:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 4,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "50:4:1",
"typeDescriptions": {}
},
"value":
{
"hexValue": "32",
"id": 5,
"kind": "number",
"nodeType": "Literal",
"src": "75:1:1",
"typeDescriptions": {},
"value": "2"
},
"visibility": "public"
},
{
"constant": false,
"id": 9,
"mutability": "mutable",
"name": "c",
"nodeType": "VariableDeclaration",
"src": "82:17:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 7,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "82:4:1",
"typeDescriptions": {}
},
"value":
{
"hexValue": "33",
"id": 8,
"kind": "number",
"nodeType": "Literal",
"src": "98:1:1",
"typeDescriptions": {},
"value": "3"
},
"visibility": "public"
}
],
"src": "0:102:1"
}
],
"src": "0:103:1"
}

View File

@ -0,0 +1,98 @@
{
"absolutePath": "a",
"id": 10,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 9,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 7,
"nodeType": "Block",
"src": "33:30:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "35:15:1",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "string",
"nodeType": "ElementaryTypeName",
"src": "35:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 6,
"initialValue":
{
"hexValue": "ff",
"id": 5,
"kind": "hexString",
"nodeType": "Literal",
"src": "53:7:1",
"typeDescriptions": {}
},
"nodeType": "VariableDeclarationStatement",
"src": "35:25:1"
}
]
},
"id": 8,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:50:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:65:1"
}
],
"src": "0:66:1"
}

View File

@ -0,0 +1,8 @@
import "notexisting.sol" as NotExisting;
contract C is NotExisting.X
{
NotExisting.SomeStruct public myStruct;
constructor() {}
}
// ----

View File

@ -0,0 +1,97 @@
{
"absolutePath": "a",
"id": 11,
"nodeType": "SourceUnit",
"nodes":
[
{
"file": "notexisting.sol",
"id": 1,
"nodeType": "ImportDirective",
"src": "0:40:1",
"symbolAliases": [],
"unitAlias": "NotExisting"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 2,
"name": "NotExisting.X",
"nodeType": "UserDefinedTypeName",
"src": "55:13:1",
"typeDescriptions": {}
},
"id": 3,
"nodeType": "InheritanceSpecifier",
"src": "55:13:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 10,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"constant": false,
"id": 5,
"mutability": "mutable",
"name": "myStruct",
"nodeType": "VariableDeclaration",
"src": "72:38:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 4,
"name": "NotExisting.SomeStruct",
"nodeType": "UserDefinedTypeName",
"src": "72:22:1",
"typeDescriptions": {}
},
"visibility": "public"
},
{
"body":
{
"id": 8,
"nodeType": "Block",
"src": "127:2:1",
"statements": []
},
"id": 9,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 6,
"nodeType": "ParameterList",
"parameters": [],
"src": "124:2:1"
},
"returnParameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters": [],
"src": "127:0:1"
},
"src": "113:16:1",
"stateMutability": "nonpayable",
"virtual": false
}
],
"src": "41:90:1"
}
],
"src": "0:132:1"
}

View File

@ -0,0 +1,273 @@
{
"absolutePath": "a",
"id": 32,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "A",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "36:2:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "faa",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "26:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "36:0:1"
},
"src": "14:24:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:40:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 6,
"name": "A",
"nodeType": "UserDefinedTypeName",
"src": "55:1:1",
"typeDescriptions": {}
},
"id": 7,
"nodeType": "InheritanceSpecifier",
"src": "55:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 16,
"name": "B",
"nodeType": "ContractDefinition",
"nodes":
[
{
"id": 10,
"implemented": false,
"kind": "function",
"modifiers": [],
"name": "foo",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 8,
"nodeType": "ParameterList",
"parameters": [],
"src": "72:2:1"
},
"returnParameters":
{
"id": 9,
"nodeType": "ParameterList",
"parameters": [],
"src": "81:0:1"
},
"src": "60:22:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"body":
{
"id": 14,
"nodeType": "Block",
"src": "115:2:1",
"statements": []
},
"id": 15,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "faa",
"nodeType": "FunctionDefinition",
"overrides":
{
"id": 12,
"nodeType": "OverrideSpecifier",
"overrides": [],
"src": "106:8:1"
},
"parameters":
{
"id": 11,
"nodeType": "ParameterList",
"parameters": [],
"src": "96:2:1"
},
"returnParameters":
{
"id": 13,
"nodeType": "ParameterList",
"parameters": [],
"src": "115:0:1"
},
"src": "84:33:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "41:78:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 17,
"name": "B",
"nodeType": "UserDefinedTypeName",
"src": "134:1:1",
"typeDescriptions": {}
},
"id": 18,
"nodeType": "InheritanceSpecifier",
"src": "134:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 31,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 22,
"nodeType": "Block",
"src": "170:3:1",
"statements": []
},
"id": 23,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "foo",
"nodeType": "FunctionDefinition",
"overrides":
{
"id": 20,
"nodeType": "OverrideSpecifier",
"overrides": [],
"src": "161:8:1"
},
"parameters":
{
"id": 19,
"nodeType": "ParameterList",
"parameters": [],
"src": "151:2:1"
},
"returnParameters":
{
"id": 21,
"nodeType": "ParameterList",
"parameters": [],
"src": "170:0:1"
},
"src": "139:34:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"body":
{
"id": 29,
"nodeType": "Block",
"src": "212:2:1",
"statements": []
},
"id": 30,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "faa",
"nodeType": "FunctionDefinition",
"overrides":
{
"id": 27,
"nodeType": "OverrideSpecifier",
"overrides":
[
{
"id": 25,
"name": "A",
"nodeType": "UserDefinedTypeName",
"src": "206:1:1",
"typeDescriptions": {}
},
{
"id": 26,
"name": "B",
"nodeType": "UserDefinedTypeName",
"src": "209:1:1",
"typeDescriptions": {}
}
],
"src": "197:14:1"
},
"parameters":
{
"id": 24,
"nodeType": "ParameterList",
"parameters": [],
"src": "187:2:1"
},
"returnParameters":
{
"id": 28,
"nodeType": "ParameterList",
"parameters": [],
"src": "212:0:1"
},
"src": "175:39:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "120:96:1"
}
],
"src": "0:217:1"
}

View File

@ -0,0 +1,51 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "24:6:1",
"statements":
[
{
"id": 2,
"nodeType": "PlaceholderStatement",
"src": "26:1:1"
}
]
},
"id": 4,
"name": "M",
"nodeType": "ModifierDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "24:0:1"
},
"src": "13:17:1",
"virtual": false,
"visibility": "internal"
}
],
"src": "0:32:1"
}
],
"src": "0:33:1"
}

View File

@ -0,0 +1,55 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "42:5:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "receive",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "22:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"src": "15:32:1",
"stateMutability": "payable",
"virtual": false,
"visibility": "external"
}
],
"src": "0:49:1"
}
],
"src": "0:50:1"
}

View File

@ -0,0 +1,96 @@
{
"absolutePath": "a",
"id": 12,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 11,
"name": "c",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 9,
"nodeType": "Block",
"src": "33:20:1",
"statements":
[
{
"assignments":
[
7
],
"declarations":
[
{
"constant": false,
"id": 7,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "35:15:1",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {},
"typeName":
{
"baseType":
{
"id": 5,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "35:4:1",
"typeDescriptions": {}
},
"id": 6,
"nodeType": "ArrayTypeName",
"src": "35:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 8,
"nodeType": "VariableDeclarationStatement",
"src": "35:15:1"
}
]
},
"id": 10,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:40:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:55:1"
}
],
"src": "0:56:1"
}

View File

@ -0,0 +1,103 @@
{
"absolutePath": "a",
"id": 13,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 12,
"name": "c",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 10,
"nodeType": "Block",
"src": "33:25:1",
"statements":
[
{
"assignments":
[
8
],
"declarations":
[
{
"constant": false,
"id": 8,
"mutability": "mutable",
"name": "rows",
"nodeType": "VariableDeclaration",
"src": "35:20:1",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {},
"typeName":
{
"baseType":
{
"baseType":
{
"id": 5,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "35:4:1",
"typeDescriptions": {}
},
"id": 6,
"nodeType": "ArrayTypeName",
"src": "35:6:1",
"typeDescriptions": {}
},
"id": 7,
"nodeType": "ArrayTypeName",
"src": "35:8:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 9,
"nodeType": "VariableDeclarationStatement",
"src": "35:20:1"
}
]
},
"id": 11,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:45:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:60:1"
}
],
"src": "0:61:1"
}

View File

@ -0,0 +1,20 @@
{
"absolutePath": "a",
"id": 2,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 1,
"name": "C",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "0:13:1"
}
],
"src": "0:14:1"
}

View File

@ -0,0 +1,122 @@
{
"absolutePath": "a",
"id": 13,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 12,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 10,
"nodeType": "Block",
"src": "26:20:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "28:6:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "28:4:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 6,
"initialValue":
{
"hexValue": "32",
"id": 5,
"kind": "number",
"nodeType": "Literal",
"src": "37:1:1",
"typeDescriptions": {},
"value": "2"
},
"nodeType": "VariableDeclarationStatement",
"src": "28:10:1"
},
{
"expression":
{
"id": 8,
"nodeType": "UnaryOperation",
"operator": "++",
"prefix": false,
"src": "40:3:1",
"subExpression":
{
"id": 7,
"name": "x",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "40:1:1",
"typeDescriptions": {}
},
"typeDescriptions": {}
},
"id": 9,
"nodeType": "ExpressionStatement",
"src": "40:3:1"
}
]
},
"id": 11,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "26:0:1"
},
"src": "13:33:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:48:1"
}
],
"src": "0:49:1"
}

View File

@ -0,0 +1,99 @@
{
"absolutePath": "a",
"id": 10,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 9,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 7,
"nodeType": "Block",
"src": "33:36:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "35:15:1",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "string",
"nodeType": "ElementaryTypeName",
"src": "35:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 6,
"initialValue":
{
"hexValue": "48656c6c6f20576f726c64",
"id": 5,
"kind": "string",
"nodeType": "Literal",
"src": "53:13:1",
"typeDescriptions": {},
"value": "Hello World"
},
"nodeType": "VariableDeclarationStatement",
"src": "35:31:1"
}
]
},
"id": 8,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:56:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:71:1"
}
],
"src": "0:72:1"
}

View File

@ -0,0 +1,198 @@
{
"absolutePath": "a",
"id": 23,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "A",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "45:2:1",
"statements": []
},
"id": 4,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "45:0:1"
},
"src": "17:30:1",
"stateMutability": "nonpayable",
"virtual": true,
"visibility": "public"
}
],
"src": "0:49:1"
},
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 10,
"name": "B",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 8,
"nodeType": "Block",
"src": "95:2:1",
"statements": []
},
"id": 9,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 6,
"nodeType": "ParameterList",
"parameters": [],
"src": "77:2:1"
},
"returnParameters":
{
"id": 7,
"nodeType": "ParameterList",
"parameters": [],
"src": "95:0:1"
},
"src": "67:30:1",
"stateMutability": "nonpayable",
"virtual": true,
"visibility": "public"
}
],
"src": "50:49:1"
},
{
"abstract": false,
"baseContracts":
[
{
"baseName":
{
"id": 11,
"name": "A",
"nodeType": "UserDefinedTypeName",
"src": "114:1:1",
"typeDescriptions": {}
},
"id": 12,
"nodeType": "InheritanceSpecifier",
"src": "114:1:1"
},
{
"baseName":
{
"id": 13,
"name": "B",
"nodeType": "UserDefinedTypeName",
"src": "117:1:1",
"typeDescriptions": {}
},
"id": 14,
"nodeType": "InheritanceSpecifier",
"src": "117:1:1"
}
],
"contractDependencies": [],
"contractKind": "contract",
"id": 22,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 20,
"nodeType": "Block",
"src": "160:2:1",
"statements": []
},
"id": 21,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"overrides":
{
"id": 18,
"nodeType": "OverrideSpecifier",
"overrides":
[
{
"id": 16,
"name": "A",
"nodeType": "UserDefinedTypeName",
"src": "154:1:1",
"typeDescriptions": {}
},
{
"id": 17,
"name": "B",
"nodeType": "UserDefinedTypeName",
"src": "157:1:1",
"typeDescriptions": {}
}
],
"src": "145:14:1"
},
"parameters":
{
"id": 15,
"nodeType": "ParameterList",
"parameters": [],
"src": "135:2:1"
},
"returnParameters":
{
"id": 19,
"nodeType": "ParameterList",
"parameters": [],
"src": "160:0:1"
},
"src": "125:37:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "100:64:1"
}
],
"src": "0:165:1"
}

View File

@ -0,0 +1,99 @@
{
"absolutePath": "a",
"id": 10,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 9,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 7,
"nodeType": "Block",
"src": "33:42:1",
"statements":
[
{
"assignments":
[
4
],
"declarations":
[
{
"constant": false,
"id": 4,
"mutability": "mutable",
"name": "x",
"nodeType": "VariableDeclaration",
"src": "35:15:1",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions": {},
"typeName":
{
"id": 3,
"name": "string",
"nodeType": "ElementaryTypeName",
"src": "35:6:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"id": 6,
"initialValue":
{
"hexValue": "48656c6c6f20f09f9883",
"id": 5,
"kind": "unicodeString",
"nodeType": "Literal",
"src": "53:19:1",
"typeDescriptions": {},
"value": "Hello \ud83d\ude03"
},
"nodeType": "VariableDeclarationStatement",
"src": "35:37:1"
}
]
},
"id": 8,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "23:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "33:0:1"
},
"src": "13:62:1",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"src": "0:77:1"
}
],
"src": "0:78:1"
}

View File

@ -0,0 +1,54 @@
{
"absolutePath": "a",
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "library",
"id": 1,
"name": "L",
"nodeType": "ContractDefinition",
"nodes": [],
"src": "0:12:1"
},
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"id": 5,
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"id": 4,
"libraryName":
{
"id": 2,
"name": "L",
"nodeType": "UserDefinedTypeName",
"src": "32:1:1",
"typeDescriptions": {}
},
"nodeType": "UsingForDirective",
"src": "26:17:1",
"typeName":
{
"id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "38:4:1",
"typeDescriptions": {}
}
}
],
"src": "13:32:1"
}
],
"src": "0:46:1"
}

View File

@ -73,6 +73,7 @@ ASTJSONTest::ASTJSONTest(string const& _filename)
BOOST_THROW_EXCEPTION(runtime_error("Invalid test contract file name: \"" + _filename + "\"."));
m_astFilename = _filename.substr(0, _filename.size() - 4) + ".json";
m_astParseOnlyFilename = _filename.substr(0, _filename.size() - 4) + "_parseOnly.json";
m_legacyAstFilename = _filename.substr(0, _filename.size() - 4) + "_legacy.json";
ifstream file(_filename);
@ -112,6 +113,15 @@ ASTJSONTest::ASTJSONTest(string const& _filename)
m_expectation += line + "\n";
}
file.close();
file.open(m_astParseOnlyFilename);
if (file)
{
string line;
while (getline(file, line))
m_expectationParseOnly += line + "\n";
}
file.close();
file.open(m_legacyAstFilename);
if (file)
@ -120,6 +130,7 @@ ASTJSONTest::ASTJSONTest(string const& _filename)
while (getline(file, line))
m_expectationLegacy += line + "\n";
}
file.close();
}
TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted)
@ -136,8 +147,36 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
c.setSources(sources);
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
if (!c.compile(CompilerStack::State::Parsed))
{
SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
for (auto const& error: c.errors())
formatter.printErrorInformation(*error);
return TestResult::FatalError;
}
bool resultsMatch = runTest(
m_expectationParseOnly,
m_resultParseOnly,
sourceIndices,
c,
false,
"parseOnly",
_stream,
_linePrefix,
_formatted
);
c.reset();
c.setSources(sources);
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
if (!c.parse())
{
// Empty Expectations means we expect failure
if (m_expectation.empty() && m_expectationLegacy.empty())
return resultsMatch ? TestResult::Success : TestResult::Failure;
SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
for (auto const& error: c.errors())
formatter.printErrorInformation(*error);
@ -146,7 +185,7 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
c.analyze();
bool resultsMatch = runTest(
resultsMatch = runTest(
m_expectation,
m_result,
sourceIndices,
@ -156,7 +195,7 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
_stream,
_linePrefix,
_formatted
);
) && resultsMatch;
resultsMatch = runTest(
m_expectationLegacy,
@ -191,7 +230,7 @@ bool ASTJSONTest::runTest(
for (size_t i = 0; i < m_sources.size(); i++)
{
ostringstream result;
ASTJsonConverter(_legacy, _sourceIndices).print(result, _compiler.ast(m_sources[i].first));
ASTJsonConverter(_legacy, _compiler.state(), _sourceIndices).print(result, _compiler.ast(m_sources[i].first));
_result += result.str();
if (i != m_sources.size() - 1)
_result += ",";
@ -234,7 +273,7 @@ bool ASTJSONTest::runTest(
return false;
}
return true;;
return true;
}
void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
@ -255,6 +294,7 @@ void ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) co
{
updateExpectation(m_astFilename, m_result, "");
updateExpectation(m_legacyAstFilename, m_resultLegacy, "legacy ");
updateExpectation(m_astParseOnlyFilename, m_resultParseOnly, "parseOnly ");
}
void ASTJSONTest::updateExpectation(string const& _filename, string const& _expectation, string const& _variation) const

View File

@ -34,7 +34,6 @@ class CompilerStack;
namespace solidity::frontend::test
{
class ASTJSONTest: public TestCase
{
public:
@ -50,9 +49,9 @@ private:
bool runTest(
std::string& _expectation,
std::string& _result,
std::map<std::string, unsigned> const& _sourceIndicies,
std::map<std::string, unsigned> const& _sourceIndices,
CompilerStack& _compiler,
bool _legacy,
bool _parseOnly,
std::string const& _variation,
std::ostream& _stream,
std::string const& _linePrefix = "",
@ -66,10 +65,13 @@ private:
std::vector<std::pair<std::string, std::string>> m_sources;
std::string m_expectationLegacy;
std::string m_expectationParseOnly;
std::string m_astFilename;
std::string m_astParseOnlyFilename;
std::string m_legacyAstFilename;
std::string m_result;
std::string m_resultLegacy;
std::string m_resultParseOnly;
};
}

View File

@ -94,7 +94,22 @@ ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _inc
continue;
}
errors.emplace_back(currentError);
std::shared_ptr<Error const> newError = currentError;
for (auto const& messagePrefix: m_messagesToCut)
if (currentError->comment()->find(messagePrefix) == 0)
{
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(*currentError);
// sufficient for now, but in future we might clone the error completely, including the secondary location
newError = make_shared<Error>(
currentError->errorId(),
currentError->type(),
location ? *location : SourceLocation(),
messagePrefix + " ...."
);
break;
}
errors.emplace_back(newError);
}
return errors;

View File

@ -71,6 +71,7 @@ protected:
langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarnings) const;
std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
std::vector<std::string> m_messagesToCut = {"Source file requires different compiler version (current compiler is"};
/// @returns reference to lazy-instanciated CompilerStack.
solidity::frontend::CompilerStack& compiler()

View File

@ -2453,6 +2453,38 @@ BOOST_AUTO_TEST_CASE(event_indexed_string)
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("E(string,uint256[4])")));
}
BOOST_AUTO_TEST_CASE(event_indexed_function)
{
char const* sourceCode = R"(
contract C {
event Test(function() external indexed);
function f() public {
emit Test(this.f);
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
callContractFunction("f()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK(logData(0) == bytes());
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
bytes functionHash = util::keccak256("f()").asBytes();
bytes address = m_contractAddress.asBytes();
bytes selector = bytes(functionHash.cbegin(), functionHash.cbegin() + 4);
bytes padding = bytes(8, 0);
bytes functionABI = address + selector + padding;
BOOST_CHECK_EQUAL(logTopic(0, 1).hex(), util::toHex(functionABI));
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Test(function)")));
)
}
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
{
char const* sourceCode = R"(

View File

@ -121,38 +121,10 @@ BOOST_AUTO_TEST_CASE(reserved_keywords)
BOOST_CHECK(!TokenTraits::isReservedKeyword(Token::Identifier));
BOOST_CHECK(TokenTraits::isReservedKeyword(Token::After));
BOOST_CHECK(TokenTraits::isReservedKeyword(Token::Unchecked));
BOOST_CHECK(TokenTraits::isReservedKeyword(Token::Var));
BOOST_CHECK(!TokenTraits::isReservedKeyword(Token::Illegal));
}
BOOST_AUTO_TEST_CASE(unsatisfied_version)
{
char const* text = R"(
pragma solidity ^99.99.0;
)";
CHECK_PARSE_ERROR(text, "Source file requires different compiler version");
}
BOOST_AUTO_TEST_CASE(unsatisfied_version_followed_by_invalid_syntax)
{
char const* text = R"(
pragma solidity ^99.99.0;
this is surely invalid
)";
CHECK_PARSE_ERROR(text, "Source file requires different compiler version");
}
BOOST_AUTO_TEST_CASE(unsatisfied_version_with_recovery)
{
char const* text = R"(
pragma solidity ^99.99.0;
contract test {
uint ;
}
)";
Error err = getError(text, true);
BOOST_CHECK(searchErrorMessage(err, "Expected identifier but got ';'"));
}
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
{
char const* text = R"(
@ -543,10 +515,11 @@ BOOST_AUTO_TEST_CASE(keyword_is_reserved)
"switch",
"typedef",
"typeof",
"unchecked"
"unchecked",
"var"
};
BOOST_CHECK_EQUAL(std::size(keywords), static_cast<int>(Token::Unchecked) - static_cast<int>(Token::After) + 1);
BOOST_CHECK_EQUAL(std::size(keywords), static_cast<int>(Token::Var) - static_cast<int>(Token::After) + 1);
for (auto const& keyword: keywords)
{

View File

@ -1420,6 +1420,91 @@ BOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_multiple_sources)
BOOST_REQUIRE(result["sources"]["B"].isObject());
}
BOOST_AUTO_TEST_CASE(stopAfter_invalid_value)
{
char const* input = R"(
{
"language": "Solidity",
"sources":
{ "": { "content": "pragma solidity >=0.0; contract C { function f() public pure {} }" } },
"settings":
{
"stopAfter": "rrr",
"outputSelection":
{
"*": { "C": ["evm.bytecode"] }
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsError(result, "JSONError", "Invalid value for \"settings.stopAfter\". Only valid value is \"parsing\"."));
}
BOOST_AUTO_TEST_CASE(stopAfter_invalid_type)
{
char const* input = R"(
{
"language": "Solidity",
"sources":
{ "": { "content": "pragma solidity >=0.0; contract C { function f() public pure {} }" } },
"settings":
{
"stopAfter": 3,
"outputSelection":
{
"*": { "C": ["evm.bytecode"] }
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsError(result, "JSONError", "\"settings.stopAfter\" must be a string."));
}
BOOST_AUTO_TEST_CASE(stopAfter_bin_conflict)
{
char const* input = R"(
{
"language": "Solidity",
"sources":
{ "": { "content": "pragma solidity >=0.0; contract C { function f() public pure {} }" } },
"settings":
{
"stopAfter": "parsing",
"outputSelection":
{
"*": { "C": ["evm.bytecode"] }
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsError(result, "JSONError", "Requested output selection conflicts with \"settings.stopAfter\"."));
}
BOOST_AUTO_TEST_CASE(stopAfter_ast_output)
{
char const* input = R"(
{
"language": "Solidity",
"sources": {
"a.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\nimport \"tes32.sol\";\n contract C is X { constructor() {} }"
}
},
"settings": {
"stopAfter": "parsing",
"outputSelection": { "*": { "": [ "ast" ] } }
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(result["sources"].isObject());
BOOST_CHECK(result["sources"]["a.sol"].isObject());
BOOST_CHECK(result["sources"]["a.sol"]["ast"].isObject());
}
BOOST_AUTO_TEST_SUITE_END()
} // end namespaces

View File

@ -0,0 +1,3 @@
pragma solidity ^99.99.0;
// ----
// SyntaxError 3997: (0-25): Source file requires different compiler version (current compiler is ....

View File

@ -0,0 +1,4 @@
pragma solidity ^99.99.0;
this is surely invalid
// ----
// ParserError 7858: (26-30): Expected pragma, import directive or contract/interface/library/struct/enum/function definition.

View File

@ -0,0 +1,7 @@
pragma solidity ^99.99.0;
contract C {
uint ;
}
// ----
// ParserError 6635: (48-49): Expected identifier but got ';'
// ParserError 6635: (50-51): Expected ';' but got '}'

Some files were not shown because too many files have changed in this diff Show More