aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/control-structures.rst16
-rw-r--r--docs/frequently-asked-questions.rst43
-rw-r--r--docs/miscellaneous.rst4
-rw-r--r--docs/types.rst5
-rw-r--r--libdevcore/CMakeLists.txt16
-rw-r--r--libevmasm/CMakeLists.txt22
-rw-r--r--liblangutil/CMakeLists.txt13
-rw-r--r--liblll/CMakeLists.txt10
-rw-r--r--libsolidity/CMakeLists.txt56
-rw-r--r--libsolidity/codegen/CompilerContext.h5
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp5
-rw-r--r--libsolidity/formal/SMTChecker.cpp4
-rwxr-xr-xscripts/check_style.sh10
-rwxr-xr-xscripts/report_errors.sh49
15 files changed, 192 insertions, 67 deletions
diff --git a/Changelog.md b/Changelog.md
index e6f01553..5408bb8e 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -15,6 +15,7 @@ Compiler Features:
Bugfixes:
* Assembly output: Do not mix in/out jump annotations with arguments.
+ * Code Generator: Annotate jump from calldata decoder to function as "jump in".
Build System:
* Emscripten: Upgrade to Emscripten SDK 1.37.21 and boost 1.67.
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 889fbdb9..720b7084 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -30,6 +30,16 @@ with two integers, you would use something like::
Function parameters can be used as any other local variable and they can also be assigned to.
+.. note::
+
+ An :ref:`external function<external-function-calls>` cannot accept a
+ multi-dimensional array as an input
+ parameter. This functionality is possible if you enable the new
+ experimental ``ABIEncoderV2`` feature by adding ``pragma experimental ABIEncoderV2;`` to your source file.
+
+ An :ref:`internal function<external-function-calls>` can accept a
+ multi-dimensional array without enabling the feature.
+
.. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct
Return Variables
@@ -56,7 +66,7 @@ two integers passed as function parameters, then you use something like::
The names of return variables can be omitted.
Return variables can be used as any other local variable and they
-are zero-initialized. If they are not explicitly
+are initialized with their :ref:`default value <default-value>` and have that value unless explicitly set.
set, they stay zero value.
You can either explicitly assign to return variables and
@@ -122,6 +132,8 @@ the same as the number of return types.
Function Calls
==============
+.. _internal-function-calls:
+
Internal Function Calls
-----------------------
@@ -143,6 +155,8 @@ contract can be called internally.
You should still avoid excessive recursion, as every internal function call
uses up at least one stack slot and there are at most 1024 slots available.
+.. _external-function-calls:
+
External Function Calls
-----------------------
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index b6e5fe78..bcdfdcd8 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -143,44 +143,6 @@ arguments for you.
See `ping.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_ping.sol>`_ and
`pong.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_pong.sol>`_.
-When returning a value of say ``uint`` type, is it possible to return an ``undefined`` or "null"-like value?
-============================================================================================================
-
-This is not possible, because all types use up the full value range.
-
-You have the option to ``throw`` on error, which will also revert the whole
-transaction, which might be a good idea if you ran into an unexpected
-situation.
-
-If you do not want to throw, you can return a pair::
-
- pragma solidity >0.4.23 <0.6.0;
-
- contract C {
- uint[] counters;
-
- function getCounter(uint index)
- public
- view
- returns (uint counter, bool error) {
- if (index >= counters.length)
- return (0, true);
- else
- return (counters[index], false);
- }
-
- function checkCounter(uint index) public view {
- (uint counter, bool error) = getCounter(index);
- if (error) {
- // Handle the error
- } else {
- // Do something with counter.
- require(counter > 7, "Invalid counter value");
- }
- }
- }
-
-
Are comments included with deployed contracts and do they increase deployment gas?
==================================================================================
@@ -307,11 +269,6 @@ to create an independent copy of the storage value in memory.
On the other hand, ``h(x)`` successfully modifies ``x`` because only
a reference and not a copy is passed.
-Is it possible to return an array of strings (``string[]``) from a Solidity function?
-=====================================================================================
-
-Only when ``pragma experimental "ABIEncoderV2";`` is used.
-
What does the following strange check do in the Custom Token contract?
======================================================================
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index cc2ba801..017d5b81 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -15,6 +15,10 @@ Statically-sized variables (everything except mapping and dynamically-sized arra
- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot.
- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules).
+For contracts that use inheritance, the ordering of state variables is determined by the
+C3-linearized order of contracts starting with the most base-ward contract. If allowed
+by the above rules, state variables from different contracts do share the same storage slot.
+
.. warning::
When using elements that are smaller than 32 bytes, your contract's gas usage may be higher.
This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller
diff --git a/docs/types.rst b/docs/types.rst
index 5a578072..69c846a6 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -13,6 +13,11 @@ Solidity provides several elementary types which can be combined to form complex
In addition, types can interact with each other in expressions containing
operators. For a quick reference of the various operators, see :ref:`order`.
+The concept of "undefined" or "null" values does not exist in Solidity, but newly
+declared variables always have a :ref:`default value<default-value>` dependent
+on its type. To handle any unexpected values, you should use the :ref:`revert function<assert-and-require>` to revert the whole transaction, or return a
+tuple with a second `bool` value denoting success.
+
.. index:: ! value type, ! type;value
Value Types
diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt
index fa7e3f48..01a8bcc6 100644
--- a/libdevcore/CMakeLists.txt
+++ b/libdevcore/CMakeLists.txt
@@ -1,7 +1,17 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ CommonData.cpp
+ CommonIO.cpp
+ Exceptions.cpp
+ IndentedWriter.cpp
+ JSON.cpp
+ Keccak256.cpp
+ StringUtils.cpp
+ SwarmHash.cpp
+ UTF8.cpp
+ Whiskers.cpp
+)
-add_library(devcore ${sources} ${headers})
+add_library(devcore ${sources})
target_link_libraries(devcore PRIVATE jsoncpp ${Boost_FILESYSTEM_LIBRARIES} ${Boost_REGEX_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(devcore PUBLIC "${CMAKE_SOURCE_DIR}")
target_include_directories(devcore SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt
index 86192c1b..e0e3389a 100644
--- a/libevmasm/CMakeLists.txt
+++ b/libevmasm/CMakeLists.txt
@@ -1,5 +1,21 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ Assembly.cpp
+ AssemblyItem.cpp
+ BlockDeduplicator.cpp
+ CommonSubexpressionEliminator.cpp
+ ConstantOptimiser.cpp
+ ControlFlowGraph.cpp
+ ExpressionClasses.cpp
+ GasMeter.cpp
+ Instruction.cpp
+ JumpdestRemover.cpp
+ KnownState.cpp
+ LinkerObject.cpp
+ PathGasMeter.cpp
+ PeepholeOptimiser.cpp
+ SemanticInformation.cpp
+ SimplificationRules.cpp
+)
-add_library(evmasm ${sources} ${headers})
+add_library(evmasm ${sources})
target_link_libraries(evmasm PUBLIC devcore)
diff --git a/liblangutil/CMakeLists.txt b/liblangutil/CMakeLists.txt
index 722ca840..dfcccfce 100644
--- a/liblangutil/CMakeLists.txt
+++ b/liblangutil/CMakeLists.txt
@@ -1,6 +1,13 @@
# Solidity Commons Library (Solidity related sharing bits between libsolidity and libyul)
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ CharStream.cpp
+ ErrorReporter.cpp
+ Exceptions.cpp
+ ParserBase.cpp
+ Scanner.cpp
+ SourceReferenceFormatter.cpp
+ Token.cpp
+)
-add_library(langutil ${sources} ${headers})
+add_library(langutil ${sources})
target_link_libraries(langutil PUBLIC devcore)
diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt
index 4cdc073a..9566c62f 100644
--- a/liblll/CMakeLists.txt
+++ b/liblll/CMakeLists.txt
@@ -1,5 +1,9 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ CodeFragment.cpp
+ Compiler.cpp
+ CompilerState.cpp
+ Parser.cpp
+)
-add_library(lll ${sources} ${headers})
+add_library(lll ${sources})
target_link_libraries(lll PUBLIC evmasm devcore)
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index c40087f0..d2e0c854 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -1,14 +1,59 @@
# Until we have a clear separation, libyul has to be included here
-file(GLOB_RECURSE sources "*.cpp")
-file(GLOB_RECURSE headers "*.h")
+set(sources
+ analysis/ConstantEvaluator.cpp
+ analysis/ControlFlowAnalyzer.cpp
+ analysis/ControlFlowBuilder.cpp
+ analysis/ControlFlowGraph.cpp
+ analysis/DeclarationContainer.cpp
+ analysis/DocStringAnalyser.cpp
+ analysis/GlobalContext.cpp
+ analysis/NameAndTypeResolver.cpp
+ analysis/PostTypeChecker.cpp
+ analysis/ReferencesResolver.cpp
+ analysis/SemVerHandler.cpp
+ analysis/StaticAnalyzer.cpp
+ analysis/SyntaxChecker.cpp
+ analysis/TypeChecker.cpp
+ analysis/ViewPureChecker.cpp
+ ast/AST.cpp
+ ast/ASTAnnotations.cpp
+ ast/ASTJsonConverter.cpp
+ ast/ASTPrinter.cpp
+ ast/Types.cpp
+ codegen/ABIFunctions.cpp
+ codegen/ArrayUtils.cpp
+ codegen/Compiler.cpp
+ codegen/CompilerContext.cpp
+ codegen/CompilerUtils.cpp
+ codegen/ContractCompiler.cpp
+ codegen/ExpressionCompiler.cpp
+ codegen/LValue.cpp
+ formal/SMTChecker.cpp
+ formal/SMTLib2Interface.cpp
+ formal/SMTPortfolio.cpp
+ formal/SSAVariable.cpp
+ formal/SymbolicTypes.cpp
+ formal/SymbolicVariables.cpp
+ formal/VariableUsage.cpp
+ interface/ABI.cpp
+ interface/AssemblyStack.cpp
+ interface/CompilerStack.cpp
+ interface/GasEstimator.cpp
+ interface/Natspec.cpp
+ interface/StandardCompiler.cpp
+ interface/Version.cpp
+ parsing/DocStringParser.cpp
+ parsing/Parser.cpp
+)
find_package(Z3 QUIET)
if (${Z3_FOUND})
include_directories(${Z3_INCLUDE_DIR})
add_definitions(-DHAVE_Z3)
message("Z3 SMT solver found. This enables optional SMT checking with Z3.")
+ set(z3_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/formal/Z3Interface.cpp")
else()
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/Z3Interface.cpp")
+ set(z3_SRCS)
endif()
find_package(CVC4 QUIET)
@@ -16,8 +61,9 @@ if (${CVC4_FOUND})
include_directories(${CVC4_INCLUDE_DIR})
add_definitions(-DHAVE_CVC4)
message("CVC4 SMT solver found. This enables optional SMT checking with CVC4.")
+ set(cvc4_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
else()
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
+ set(cvc4_SRCS)
endif()
if (NOT (${Z3_FOUND} OR ${CVC4_FOUND}))
@@ -25,7 +71,7 @@ if (NOT (${Z3_FOUND} OR ${CVC4_FOUND}))
\nPlease install Z3 or CVC4 or remove the option disabling them (USE_Z3, USE_CVC4).")
endif()
-add_library(solidity ${sources} ${headers})
+add_library(solidity ${sources} ${z3_SRCS} ${cvc4_SRCS})
target_link_libraries(solidity PUBLIC yul evmasm langutil devcore ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
if (${Z3_FOUND})
diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h
index 63365175..02369813 100644
--- a/libsolidity/codegen/CompilerContext.h
+++ b/libsolidity/codegen/CompilerContext.h
@@ -167,7 +167,10 @@ public:
/// the data.
CompilerContext& appendConditionalRevert(bool _forwardReturnData = false);
/// Appends a JUMP to a specific tag
- CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm->appendJump(_tag); return *this; }
+ CompilerContext& appendJumpTo(
+ eth::AssemblyItem const& _tag,
+ eth::AssemblyItem::JumpType _jumpType = eth::AssemblyItem::JumpType::Ordinary
+ ) { *m_asm << _tag.pushTag(); return appendJump(_jumpType); }
/// Appends pushing of a new tag and @returns the new tag.
eth::AssemblyItem pushNewTag() { return m_asm->append(m_asm->newPushTag()).tag(); }
/// @returns a new tag without pushing any opcodes or data
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp
index 157d5fa7..aabdbb79 100644
--- a/libsolidity/codegen/ContractCompiler.cpp
+++ b/libsolidity/codegen/ContractCompiler.cpp
@@ -344,7 +344,10 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
m_context << Instruction::DUP1 << Instruction::CALLDATASIZE << Instruction::SUB;
CompilerUtils(m_context).abiDecode(functionType->parameterTypes());
}
- m_context.appendJumpTo(m_context.functionEntryLabel(functionType->declaration()));
+ m_context.appendJumpTo(
+ m_context.functionEntryLabel(functionType->declaration()),
+ eth::AssemblyItem::JumpType::IntoFunction
+ );
m_context << returnTag;
// Return tag and input parameters get consumed.
m_context.adjustStackOffset(
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp
index 5b7807f7..477568a0 100644
--- a/libsolidity/formal/SMTChecker.cpp
+++ b/libsolidity/formal/SMTChecker.cpp
@@ -889,6 +889,10 @@ void SMTChecker::checkBooleanNotConstant(Expression const& _condition, string co
{
// everything fine.
}
+ else if (positiveResult == smt::CheckResult::UNKNOWN || negatedResult == smt::CheckResult::UNKNOWN)
+ {
+ // can't do anything.
+ }
else if (positiveResult == smt::CheckResult::UNSATISFIABLE && negatedResult == smt::CheckResult::UNSATISFIABLE)
m_errorReporter.warning(_condition.location(), "Condition unreachable.");
else
diff --git a/scripts/check_style.sh b/scripts/check_style.sh
index 4f716d66..171867f9 100755
--- a/scripts/check_style.sh
+++ b/scripts/check_style.sh
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
+. scripts/report_errors.sh
+
(
REPO_ROOT="$(dirname "$0")"/..
cd $REPO_ROOT
@@ -8,8 +10,8 @@ WHITESPACE=$(git grep -n -I -E "^.*[[:space:]]+$" | grep -v "test/libsolidity/AS
if [[ "$WHITESPACE" != "" ]]
then
- echo "Error: Trailing whitespace found:" >&2
- echo "$WHITESPACE" >&2
+ echo "Error: Trailing whitespace found:" | tee -a $ERROR_LOG
+ echo "$WHITESPACE" | tee -a $ERROR_LOG
exit 1
fi
@@ -22,8 +24,8 @@ git grep -nIE "\<if\>\s*\(.*\)\s*\{\s*$" -- '*.h' '*.cpp'
if [[ "$FORMATERROR" != "" ]]
then
- echo "Error: Format error for if/for:" >&2
- echo "$FORMATERROR" >&2
+ echo "Error: Format error for if/for:" | tee -a $ERROR_LOG
+ echo "$FORMATERROR" | tee -a $ERROR_LOG
exit 1
fi
)
diff --git a/scripts/report_errors.sh b/scripts/report_errors.sh
new file mode 100755
index 00000000..55fc2e8c
--- /dev/null
+++ b/scripts/report_errors.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+export ERROR_LOG="/tmp/error.log"
+
+function report_error_to_github
+{
+ if [ $? -eq 0 ]
+ then
+ exit 0
+ fi
+
+ if [ -z $CIRCLE_PR_NUMBER ]
+ then
+ CIRCLE_PR_NUMBER="${CIRCLE_PULL_REQUEST//[^0-9]/}"
+ fi
+
+ ERROR_MSG=$(cat $ERROR_LOG)
+
+ echo $ERROR_MSG
+
+ if [ ! -z $CI ]
+ then
+ echo "posting error message to github"
+ post_error_to_github
+ fi
+}
+
+function post_error_to_github
+{
+ if [ -z $CIRCLE_PR_NUMBER ]
+ then
+ CIRCLE_PR_NUMBER="${CIRCLE_PULL_REQUEST//[^0-9]/}"
+ fi
+
+ GITHUB_API_URL="https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/issues/$CIRCLE_PR_NUMBER/comments"
+
+ ESCAPED_ERROR_MSG=$(cat -e $ERROR_LOG | sed 's/\\/\\\\/g' | sed 's/"/\\\"/g')
+
+ FORMATTED_ERROR_MSG=$(echo $ESCAPED_ERROR_MSG | sed 's/\$/\\n/g' | tr -d '\n')
+
+ curl --request POST \
+ --url $GITHUB_API_URL \
+ --header 'accept: application/vnd.github.v3+json' \
+ --header 'content-type: application/json' \
+ -u stackenbotten:$GITHUB_ACCESS_TOKEN \
+ --data "{\"body\": \"There was an error when running \`$CIRCLE_JOB\` for commit \`$CIRCLE_SHA1\`:\n\`\`\`\n$FORMATTED_ERROR_MSG\n\`\`\`\nPlease check that your changes are working as intended.\"}"
+}
+
+trap report_error_to_github EXIT