mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2532 from ethereum/develop
Merge develop to release for 0.4.13.
This commit is contained in:
commit
0fb4cb1ab9
@ -221,6 +221,7 @@ deploy:
|
|||||||
branch:
|
branch:
|
||||||
- develop
|
- develop
|
||||||
- release
|
- release
|
||||||
|
- /^v[0-9]/
|
||||||
# This is the deploy target for the native build (Linux and macOS)
|
# This is the deploy target for the native build (Linux and macOS)
|
||||||
# which generates ZIPs per commit and the source tarball.
|
# which generates ZIPs per commit and the source tarball.
|
||||||
#
|
#
|
||||||
|
@ -8,7 +8,7 @@ include(EthPolicy)
|
|||||||
eth_policy()
|
eth_policy()
|
||||||
|
|
||||||
# project name and version should be set after cmake_policy CMP0048
|
# project name and version should be set after cmake_policy CMP0048
|
||||||
set(PROJECT_VERSION "0.4.12")
|
set(PROJECT_VERSION "0.4.13")
|
||||||
project(solidity VERSION ${PROJECT_VERSION})
|
project(solidity VERSION ${PROJECT_VERSION})
|
||||||
|
|
||||||
# Let's find our dependencies
|
# Let's find our dependencies
|
||||||
|
11
Changelog.md
11
Changelog.md
@ -1,3 +1,14 @@
|
|||||||
|
### 0.4.13 (2017-07-06)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Syntax Checker: Deprecated "throw" in favour of require(), assert() and revert().
|
||||||
|
* Type Checker: Warn if a local storage reference variable does not explicitly use the keyword ``storage``.
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Code Generator: Correctly unregister modifier variables.
|
||||||
|
* Compiler Interface: Only output AST if analysis was successful.
|
||||||
|
* Error Output: Do not omit the error type.
|
||||||
|
|
||||||
### 0.4.12 (2017-07-03)
|
### 0.4.12 (2017-07-03)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
@ -301,6 +301,10 @@
|
|||||||
"bugs": [],
|
"bugs": [],
|
||||||
"released": "2017-07-03"
|
"released": "2017-07-03"
|
||||||
},
|
},
|
||||||
|
"0.4.13": {
|
||||||
|
"bugs": [],
|
||||||
|
"released": "2017-07-06"
|
||||||
|
},
|
||||||
"0.4.2": {
|
"0.4.2": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
"SkipEmptyStringLiteral",
|
"SkipEmptyStringLiteral",
|
||||||
|
@ -78,10 +78,10 @@ Alternatively, there is a testing script at ``scripts/test.sh`` which executes a
|
|||||||
Whiskers
|
Whiskers
|
||||||
========
|
========
|
||||||
|
|
||||||
*Whiskers* is a templating system similar to `Moustache <https://mustache.github.io>`_. It is used by the
|
*Whiskers* is a templating system similar to `Mustache <https://mustache.github.io>`_. It is used by the
|
||||||
compiler in various places to aid readability, and thus maintainability and verifiability, of the code.
|
compiler in various places to aid readability, and thus maintainability and verifiability, of the code.
|
||||||
|
|
||||||
The syntax comes with a substantial difference to Moustache: the template markers ``{{`` and ``}}`` are
|
The syntax comes with a substantial difference to Mustache: the template markers ``{{`` and ``}}`` are
|
||||||
replaced by ``<`` and ``>`` in order to aid parsing and avoid conflicts with :ref:`inline-assembly`
|
replaced by ``<`` and ``>`` in order to aid parsing and avoid conflicts with :ref:`inline-assembly`
|
||||||
(The symbols ``<`` and ``>`` are invalid in inline assembly, while ``{`` and ``}`` are used to delimit blocks).
|
(The symbols ``<`` and ``>`` are invalid in inline assembly, while ``{`` and ``}`` are used to delimit blocks).
|
||||||
Another limitation is that lists are only resolved one depth and they will not recurse. This may change in the future.
|
Another limitation is that lists are only resolved one depth and they will not recurse. This may change in the future.
|
||||||
@ -91,5 +91,5 @@ A rough specification is the following:
|
|||||||
Any occurrence of ``<name>`` is replaced by the string-value of the supplied variable ``name`` without any
|
Any occurrence of ``<name>`` is replaced by the string-value of the supplied variable ``name`` without any
|
||||||
escaping and without iterated replacements. An area can be delimited by ``<#name>...</name>``. It is replaced
|
escaping and without iterated replacements. An area can be delimited by ``<#name>...</name>``. It is replaced
|
||||||
by as many concatenations of its contents as there were sets of variables supplied to the template system,
|
by as many concatenations of its contents as there were sets of variables supplied to the template system,
|
||||||
each time replacing any ``<inner>`` items by their respective value. Top-level variales can also be used
|
each time replacing any ``<inner>`` items by their respective value. Top-level variables can also be used
|
||||||
inside such areas.
|
inside such areas.
|
@ -289,7 +289,20 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
|
|||||||
typeLoc = DataLocation::Memory;
|
typeLoc = DataLocation::Memory;
|
||||||
}
|
}
|
||||||
else if (varLoc == Location::Default)
|
else if (varLoc == Location::Default)
|
||||||
typeLoc = _variable.isCallableParameter() ? DataLocation::Memory : DataLocation::Storage;
|
{
|
||||||
|
if (_variable.isCallableParameter())
|
||||||
|
typeLoc = DataLocation::Memory;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typeLoc = DataLocation::Storage;
|
||||||
|
if (!_variable.isStateVariable())
|
||||||
|
m_errorReporter.warning(
|
||||||
|
_variable.location(),
|
||||||
|
"Variable is declared as a storage pointer. "
|
||||||
|
"Use an explicit \"storage\" keyword to silence this warning."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
|
typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
|
||||||
isPointer = !_variable.isStateVariable();
|
isPointer = !_variable.isStateVariable();
|
||||||
|
@ -135,6 +135,16 @@ bool SyntaxChecker::visit(Break const& _breakStatement)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SyntaxChecker::visit(Throw const& _throwStatement)
|
||||||
|
{
|
||||||
|
m_errorReporter.warning(
|
||||||
|
_throwStatement.location(),
|
||||||
|
"\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"."
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SyntaxChecker::visit(UnaryOperation const& _operation)
|
bool SyntaxChecker::visit(UnaryOperation const& _operation)
|
||||||
{
|
{
|
||||||
if (_operation.getOperator() == Token::Add)
|
if (_operation.getOperator() == Token::Add)
|
||||||
|
@ -33,6 +33,7 @@ namespace solidity
|
|||||||
* - whether continue/break is in a for/while loop.
|
* - whether continue/break is in a for/while loop.
|
||||||
* - whether a modifier contains at least one '_'
|
* - whether a modifier contains at least one '_'
|
||||||
* - issues deprecation warnings for unary '+'
|
* - issues deprecation warnings for unary '+'
|
||||||
|
* - issues deprecation warning for throw
|
||||||
*/
|
*/
|
||||||
class SyntaxChecker: private ASTConstVisitor
|
class SyntaxChecker: private ASTConstVisitor
|
||||||
{
|
{
|
||||||
@ -59,6 +60,8 @@ private:
|
|||||||
virtual bool visit(Continue const& _continueStatement) override;
|
virtual bool visit(Continue const& _continueStatement) override;
|
||||||
virtual bool visit(Break const& _breakStatement) override;
|
virtual bool visit(Break const& _breakStatement) override;
|
||||||
|
|
||||||
|
virtual bool visit(Throw const& _throwStatement) override;
|
||||||
|
|
||||||
virtual bool visit(UnaryOperation const& _operation) override;
|
virtual bool visit(UnaryOperation const& _operation) override;
|
||||||
|
|
||||||
virtual bool visit(PlaceholderStatement const& _placeholderStatement) override;
|
virtual bool visit(PlaceholderStatement const& _placeholderStatement) override;
|
||||||
|
@ -854,10 +854,12 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
if (auto ref = dynamic_cast<ReferenceType const*>(type(varDecl).get()))
|
if (auto ref = dynamic_cast<ReferenceType const*>(type(varDecl).get()))
|
||||||
{
|
{
|
||||||
if (ref->dataStoredIn(DataLocation::Storage))
|
if (ref->dataStoredIn(DataLocation::Storage))
|
||||||
m_errorReporter.warning(
|
{
|
||||||
varDecl.location(),
|
string errorText{"Uninitialized storage pointer."};
|
||||||
"Uninitialized storage pointer. Did you mean '<type> memory " + varDecl.name() + "'?"
|
if (varDecl.referenceLocation() == VariableDeclaration::Location::Default)
|
||||||
);
|
errorText += " Did you mean '<type> memory " + varDecl.name() + "'?";
|
||||||
|
m_errorReporter.warning(varDecl.location(), errorText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<MappingType const*>(type(varDecl).get()))
|
else if (dynamic_cast<MappingType const*>(type(varDecl).get()))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
|
@ -928,7 +928,10 @@ void ContractCompiler::appendModifierOrFunctionCode()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (VariableDeclaration const* localVariable: modifier.localVariables())
|
for (VariableDeclaration const* localVariable: modifier.localVariables())
|
||||||
|
{
|
||||||
|
addedVariables.push_back(localVariable);
|
||||||
appendStackVariableInitialisation(*localVariable);
|
appendStackVariableInitialisation(*localVariable);
|
||||||
|
}
|
||||||
|
|
||||||
stackSurplus =
|
stackSurplus =
|
||||||
CompilerUtils::sizeOnStack(modifier.parameters()) +
|
CompilerUtils::sizeOnStack(modifier.parameters()) +
|
||||||
|
@ -71,7 +71,7 @@ Json::Value formatErrorWithException(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
string message;
|
string message;
|
||||||
string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(_exception, _message, _scannerFromSourceName);
|
string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(_exception, _type, _scannerFromSourceName);
|
||||||
|
|
||||||
// NOTE: the below is partially a copy from SourceReferenceFormatter
|
// NOTE: the below is partially a copy from SourceReferenceFormatter
|
||||||
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
|
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
|
||||||
@ -271,12 +271,12 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
|||||||
|
|
||||||
for (auto const& error: m_compilerStack.errors())
|
for (auto const& error: m_compilerStack.errors())
|
||||||
{
|
{
|
||||||
auto err = dynamic_pointer_cast<Error const>(error);
|
Error const& err = dynamic_cast<Error const&>(*error);
|
||||||
|
|
||||||
errors.append(formatErrorWithException(
|
errors.append(formatErrorWithException(
|
||||||
*error,
|
*error,
|
||||||
err->type() == Error::Type::Warning,
|
err.type() == Error::Type::Warning,
|
||||||
err->typeName(),
|
err.typeName(),
|
||||||
"general",
|
"general",
|
||||||
"",
|
"",
|
||||||
scannerFromSourceName
|
scannerFromSourceName
|
||||||
@ -357,7 +357,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
|||||||
if (errors.size() > 0)
|
if (errors.size() > 0)
|
||||||
output["errors"] = errors;
|
output["errors"] = errors;
|
||||||
|
|
||||||
bool parsingSuccess = m_compilerStack.state() >= CompilerStack::State::ParsingSuccessful;
|
bool analysisSuccess = m_compilerStack.state() >= CompilerStack::State::AnalysisSuccessful;
|
||||||
bool compilationSuccess = m_compilerStack.state() == CompilerStack::State::CompilationSuccessful;
|
bool compilationSuccess = m_compilerStack.state() == CompilerStack::State::CompilationSuccessful;
|
||||||
|
|
||||||
/// Inconsistent state - stop here to receive error reports from users
|
/// Inconsistent state - stop here to receive error reports from users
|
||||||
@ -366,7 +366,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
|||||||
|
|
||||||
output["sources"] = Json::objectValue;
|
output["sources"] = Json::objectValue;
|
||||||
unsigned sourceIndex = 0;
|
unsigned sourceIndex = 0;
|
||||||
for (auto const& source: parsingSuccess ? m_compilerStack.sourceNames() : vector<string>())
|
for (auto const& source: analysisSuccess ? m_compilerStack.sourceNames() : vector<string>())
|
||||||
{
|
{
|
||||||
Json::Value sourceResult = Json::objectValue;
|
Json::Value sourceResult = Json::objectValue;
|
||||||
sourceResult["id"] = sourceIndex++;
|
sourceResult["id"] = sourceIndex++;
|
||||||
|
@ -14,6 +14,21 @@
|
|||||||
##
|
##
|
||||||
## It will clone the Solidity git from github, determine the version,
|
## It will clone the Solidity git from github, determine the version,
|
||||||
## create a source archive and push it to the ubuntu ppa servers.
|
## create a source archive and push it to the ubuntu ppa servers.
|
||||||
|
##
|
||||||
|
## This requires the following entries in /etc/dput.cf:
|
||||||
|
##
|
||||||
|
## [ethereum-dev]
|
||||||
|
## fqdn = ppa.launchpad.net
|
||||||
|
## method = ftp
|
||||||
|
## incoming = ~ethereum/ethereum-dev
|
||||||
|
## login = anonymous
|
||||||
|
##
|
||||||
|
## [ethereum]
|
||||||
|
## fqdn = ppa.launchpad.net
|
||||||
|
## method = ftp
|
||||||
|
## incoming = ~ethereum/ethereum
|
||||||
|
## login = anonymous
|
||||||
|
|
||||||
##
|
##
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -28,10 +43,10 @@ fi
|
|||||||
|
|
||||||
if [ "$branch" = develop ]
|
if [ "$branch" = develop ]
|
||||||
then
|
then
|
||||||
pparepo=ethereum/ethereum-dev
|
pparepo=ethereum-dev
|
||||||
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-dev/+files
|
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-dev/+files
|
||||||
else
|
else
|
||||||
pparepo=ethereum/ethereum
|
pparepo=ethereum
|
||||||
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum/+files
|
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum/+files
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -192,7 +207,8 @@ EMAIL="$email" dch -v 1:${debversion}-${versionsuffix} "git build of ${commithas
|
|||||||
# build source package
|
# build source package
|
||||||
# If packages is rejected because original source is already present, add
|
# If packages is rejected because original source is already present, add
|
||||||
# -sd to remove it from the .changes file
|
# -sd to remove it from the .changes file
|
||||||
debuild -S -sa -us -uc
|
# -d disables the build dependencies check
|
||||||
|
debuild -S -d -sa -us -uc
|
||||||
|
|
||||||
# prepare .changes file for Launchpad
|
# prepare .changes file for Launchpad
|
||||||
sed -i -e s/UNRELEASED/${distribution}/ -e s/urgency=medium/urgency=low/ ../*.changes
|
sed -i -e s/UNRELEASED/${distribution}/ -e s/urgency=medium/urgency=low/ ../*.changes
|
||||||
@ -223,6 +239,6 @@ fi
|
|||||||
debsign --re-sign -k ${keyid} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
debsign --re-sign -k ${keyid} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
||||||
|
|
||||||
# upload
|
# upload
|
||||||
dput ppa:${pparepo} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
dput ${pparepo} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
||||||
|
|
||||||
done
|
done
|
||||||
|
29
snap/snapcraft.yaml
Normal file
29
snap/snapcraft.yaml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: solc
|
||||||
|
version: master
|
||||||
|
summary: The Solidity Contract-Oriented Programming Language
|
||||||
|
description: |
|
||||||
|
Solidity is a contract-oriented, high-level language whose syntax is similar
|
||||||
|
to that of JavaScript and it is designed to target the Ethereum Virtual
|
||||||
|
Machine (EVM).
|
||||||
|
|
||||||
|
Solidity is statically typed, supports inheritance, libraries and complex
|
||||||
|
user-defined types among other features.
|
||||||
|
|
||||||
|
It is possible to create contracts for voting, crowdfunding, blind auctions,
|
||||||
|
multi-signature wallets and more.
|
||||||
|
|
||||||
|
grade: devel # must be 'stable' to release into candidate/stable channels
|
||||||
|
confinement: strict
|
||||||
|
|
||||||
|
apps:
|
||||||
|
solc:
|
||||||
|
command: solc
|
||||||
|
plugs: [home]
|
||||||
|
|
||||||
|
parts:
|
||||||
|
solidity:
|
||||||
|
source: .
|
||||||
|
source-type: git
|
||||||
|
plugin: cmake
|
||||||
|
build-packages: [build-essential, libboost-all-dev]
|
||||||
|
stage-packages: [libicu55]
|
@ -9696,6 +9696,33 @@ BOOST_AUTO_TEST_CASE(keccak256_assembly)
|
|||||||
BOOST_CHECK(callContractFunction("i()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
|
BOOST_CHECK(callContractFunction("i()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(multi_modifiers)
|
||||||
|
{
|
||||||
|
// This triggered a bug in some version because the variable in the modifier was not
|
||||||
|
// unregistered correctly.
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
uint public x;
|
||||||
|
modifier m1 {
|
||||||
|
address a1 = msg.sender;
|
||||||
|
x++;
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
function f1() m1() {
|
||||||
|
x += 7;
|
||||||
|
}
|
||||||
|
function f2() m1() {
|
||||||
|
x += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "C");
|
||||||
|
BOOST_CHECK(callContractFunction("f1()") == bytes());
|
||||||
|
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(8)));
|
||||||
|
BOOST_CHECK(callContractFunction("f2()") == bytes());
|
||||||
|
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(12)));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2817,7 +2817,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_mapping_array_variable)
|
|||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
mapping(uint => uint)[] x;
|
mapping(uint => uint)[] storage x;
|
||||||
x;
|
x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3103,7 +3103,7 @@ BOOST_AUTO_TEST_CASE(non_initialized_references)
|
|||||||
}
|
}
|
||||||
function f()
|
function f()
|
||||||
{
|
{
|
||||||
s x;
|
s storage x;
|
||||||
x.a = 2;
|
x.a = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5860,6 +5860,18 @@ BOOST_AUTO_TEST_CASE(using_interface_complex)
|
|||||||
success(text);
|
success(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(warn_about_throw)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
function f() {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(text, "\"throw\" is deprecated");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(bare_revert)
|
BOOST_AUTO_TEST_CASE(bare_revert)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
@ -6144,6 +6156,32 @@ BOOST_AUTO_TEST_CASE(shadowing_warning_can_be_removed)
|
|||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(warn_unspecified_storage)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
struct S { uint a; }
|
||||||
|
S x;
|
||||||
|
function f() {
|
||||||
|
S storage y = x;
|
||||||
|
y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||||
|
text = R"(
|
||||||
|
contract C {
|
||||||
|
struct S { uint a; }
|
||||||
|
S x;
|
||||||
|
function f() {
|
||||||
|
S y = x;
|
||||||
|
y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(text, "is declared as a storage pointer. Use an explicit \"storage\" keyword to silence this warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user