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:
|
||||
- develop
|
||||
- release
|
||||
- /^v[0-9]/
|
||||
# This is the deploy target for the native build (Linux and macOS)
|
||||
# which generates ZIPs per commit and the source tarball.
|
||||
#
|
||||
|
@ -8,7 +8,7 @@ include(EthPolicy)
|
||||
eth_policy()
|
||||
|
||||
# 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})
|
||||
|
||||
# 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)
|
||||
|
||||
Features:
|
||||
|
@ -301,6 +301,10 @@
|
||||
"bugs": [],
|
||||
"released": "2017-07-03"
|
||||
},
|
||||
"0.4.13": {
|
||||
"bugs": [],
|
||||
"released": "2017-07-06"
|
||||
},
|
||||
"0.4.2": {
|
||||
"bugs": [
|
||||
"SkipEmptyStringLiteral",
|
||||
|
@ -78,10 +78,10 @@ Alternatively, there is a testing script at ``scripts/test.sh`` which executes a
|
||||
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.
|
||||
|
||||
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`
|
||||
(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.
|
||||
@ -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
|
||||
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,
|
||||
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.
|
@ -289,7 +289,20 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
|
||||
typeLoc = DataLocation::Memory;
|
||||
}
|
||||
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
|
||||
typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
|
||||
isPointer = !_variable.isStateVariable();
|
||||
|
@ -135,6 +135,16 @@ bool SyntaxChecker::visit(Break const& _breakStatement)
|
||||
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)
|
||||
{
|
||||
if (_operation.getOperator() == Token::Add)
|
||||
|
@ -33,6 +33,7 @@ namespace solidity
|
||||
* - whether continue/break is in a for/while loop.
|
||||
* - whether a modifier contains at least one '_'
|
||||
* - issues deprecation warnings for unary '+'
|
||||
* - issues deprecation warning for throw
|
||||
*/
|
||||
class SyntaxChecker: private ASTConstVisitor
|
||||
{
|
||||
@ -59,6 +60,8 @@ private:
|
||||
virtual bool visit(Continue const& _continueStatement) 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(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 (ref->dataStoredIn(DataLocation::Storage))
|
||||
m_errorReporter.warning(
|
||||
varDecl.location(),
|
||||
"Uninitialized storage pointer. Did you mean '<type> memory " + varDecl.name() + "'?"
|
||||
);
|
||||
{
|
||||
string errorText{"Uninitialized storage pointer."};
|
||||
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()))
|
||||
m_errorReporter.typeError(
|
||||
|
@ -928,7 +928,10 @@ void ContractCompiler::appendModifierOrFunctionCode()
|
||||
);
|
||||
}
|
||||
for (VariableDeclaration const* localVariable: modifier.localVariables())
|
||||
{
|
||||
addedVariables.push_back(localVariable);
|
||||
appendStackVariableInitialisation(*localVariable);
|
||||
}
|
||||
|
||||
stackSurplus =
|
||||
CompilerUtils::sizeOnStack(modifier.parameters()) +
|
||||
|
@ -71,7 +71,7 @@ Json::Value formatErrorWithException(
|
||||
)
|
||||
{
|
||||
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
|
||||
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())
|
||||
{
|
||||
auto err = dynamic_pointer_cast<Error const>(error);
|
||||
Error const& err = dynamic_cast<Error const&>(*error);
|
||||
|
||||
errors.append(formatErrorWithException(
|
||||
*error,
|
||||
err->type() == Error::Type::Warning,
|
||||
err->typeName(),
|
||||
err.type() == Error::Type::Warning,
|
||||
err.typeName(),
|
||||
"general",
|
||||
"",
|
||||
scannerFromSourceName
|
||||
@ -357,7 +357,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
||||
if (errors.size() > 0)
|
||||
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;
|
||||
|
||||
/// 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;
|
||||
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;
|
||||
sourceResult["id"] = sourceIndex++;
|
||||
|
@ -14,6 +14,21 @@
|
||||
##
|
||||
## It will clone the Solidity git from github, determine the version,
|
||||
## 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 ]
|
||||
then
|
||||
pparepo=ethereum/ethereum-dev
|
||||
pparepo=ethereum-dev
|
||||
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum-dev/+files
|
||||
else
|
||||
pparepo=ethereum/ethereum
|
||||
pparepo=ethereum
|
||||
ppafilesurl=https://launchpad.net/~ethereum/+archive/ubuntu/ethereum/+files
|
||||
fi
|
||||
|
||||
@ -192,7 +207,8 @@ EMAIL="$email" dch -v 1:${debversion}-${versionsuffix} "git build of ${commithas
|
||||
# build source package
|
||||
# If packages is rejected because original source is already present, add
|
||||
# -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
|
||||
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
|
||||
|
||||
# upload
|
||||
dput ppa:${pparepo} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
||||
dput ${pparepo} ../${packagename}_${debversion}-${versionsuffix}_source.changes
|
||||
|
||||
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_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()
|
||||
|
||||
}
|
||||
|
@ -2817,7 +2817,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_mapping_array_variable)
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
function f() {
|
||||
mapping(uint => uint)[] x;
|
||||
mapping(uint => uint)[] storage x;
|
||||
x;
|
||||
}
|
||||
}
|
||||
@ -3103,7 +3103,7 @@ BOOST_AUTO_TEST_CASE(non_initialized_references)
|
||||
}
|
||||
function f()
|
||||
{
|
||||
s x;
|
||||
s storage x;
|
||||
x.a = 2;
|
||||
}
|
||||
}
|
||||
@ -5860,6 +5860,18 @@ BOOST_AUTO_TEST_CASE(using_interface_complex)
|
||||
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)
|
||||
{
|
||||
char const* text = R"(
|
||||
@ -6144,6 +6156,32 @@ BOOST_AUTO_TEST_CASE(shadowing_warning_can_be_removed)
|
||||
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()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user