aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/conf.py2
-rw-r--r--docs/contracts.rst10
-rw-r--r--docs/grammar.txt2
-rw-r--r--docs/solidity-by-example.rst12
-rw-r--r--libevmasm/AssemblyItem.cpp16
-rw-r--r--libevmasm/Instruction.h14
-rw-r--r--libsolidity/ast/Types.cpp41
-rw-r--r--libsolidity/ast/Types.h7
-rw-r--r--test/libsolidity/syntaxTests/empty_string_var.sol11
-rw-r--r--test/libsolidity/syntaxTests/types/bytes0.sol5
-rw-r--r--test/libsolidity/syntaxTests/types/bytes256.sol5
-rw-r--r--test/libsolidity/syntaxTests/types/bytes33.sol5
-rw-r--r--test/libsolidity/syntaxTests/types/bytesm.sol36
13 files changed, 110 insertions, 56 deletions
diff --git a/docs/conf.py b/docs/conf.py
index ca8c0fec..3bbee671 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -50,7 +50,7 @@ master_doc = 'index'
# General information about the project.
project = 'Solidity'
-copyright = '2016-2017, Ethereum'
+copyright = '2016-2018, Ethereum'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 17eb23f7..5c298274 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -1066,12 +1066,15 @@ Multiple Inheritance and Linearization
Languages that allow multiple inheritance have to deal with
several problems. One is the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_.
-Solidity follows the path of Python and uses "`C3 Linearization <https://en.wikipedia.org/wiki/C3_linearization>`_"
+Solidity is similar to Python in that it uses "`C3 Linearization <https://en.wikipedia.org/wiki/C3_linearization>`_"
to force a specific order in the DAG of base classes. This
results in the desirable property of monotonicity but
disallows some inheritance graphs. Especially, the order in
which the base classes are given in the ``is`` directive is
-important. In the following code, Solidity will give the
+important: You have to list the direct base contracts
+in the order from "most base-like" to "most derived".
+Note that this order is different from the one used in Python.
+In the following code, Solidity will give the
error "Linearization of inheritance graph impossible".
::
@@ -1089,9 +1092,6 @@ The reason for this is that ``C`` requests ``X`` to override ``A``
requests to override ``X``, which is a contradiction that
cannot be resolved.
-A simple rule to remember is to specify the base classes in
-the order from "most base-like" to "most derived".
-
Inheriting Different Kinds of Members of the Same Name
======================================================
diff --git a/docs/grammar.txt b/docs/grammar.txt
index b4ca5ca9..565db9a4 100644
--- a/docs/grammar.txt
+++ b/docs/grammar.txt
@@ -16,7 +16,7 @@ ContractPart = StateVariableDeclaration | UsingForDeclaration
InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* ')' )?
-StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';'
+StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )* Identifier ('=' Expression)? ';'
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
StructDefinition = 'struct' Identifier '{'
( VariableDeclaration ';' (VariableDeclaration ';')* ) '}'
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 546767e4..f6038f7d 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -66,7 +66,7 @@ of votes.
Proposal[] public proposals;
/// Create a new ballot to choose one of `proposalNames`.
- function Ballot(bytes32[] proposalNames) public {
+ constructor(bytes32[] proposalNames) public {
chairperson = msg.sender;
voters[chairperson].weight = 1;
@@ -256,7 +256,7 @@ activate themselves.
/// Create a simple auction with `_biddingTime`
/// seconds bidding time on behalf of the
/// beneficiary address `_beneficiary`.
- function SimpleAuction(
+ constructor(
uint _biddingTime,
address _beneficiary
) public {
@@ -418,7 +418,7 @@ high or low invalid bids.
modifier onlyBefore(uint _time) { require(now < _time); _; }
modifier onlyAfter(uint _time) { require(now > _time); _; }
- function BlindAuction(
+ constructor(
uint _biddingTime,
uint _revealTime,
address _beneficiary
@@ -553,7 +553,7 @@ Safe Remote Purchase
// Ensure that `msg.value` is an even number.
// Division will truncate if it is an odd number.
// Check via multiplication that it wasn't an odd number.
- function Purchase() public payable {
+ constructor() public payable {
seller = msg.sender;
value = msg.value / 2;
require((2 * value) == msg.value, "Value has to be even.");
@@ -602,7 +602,7 @@ Safe Remote Purchase
{
emit Aborted();
state = State.Inactive;
- seller.transfer(this.balance);
+ seller.transfer(address(this).balance);
}
/// Confirm the purchase as buyer.
@@ -637,7 +637,7 @@ Safe Remote Purchase
// block the refund - the withdraw pattern should be used.
buyer.transfer(value);
- seller.transfer(this.balance);
+ seller.transfer(address(this).balance);
}
}
diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp
index 5af618ff..a3a4d6b6 100644
--- a/libevmasm/AssemblyItem.cpp
+++ b/libevmasm/AssemblyItem.cpp
@@ -26,27 +26,35 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
+static_assert(sizeof(size_t) <= 8, "size_t must be at most 64-bits wide");
+
AssemblyItem AssemblyItem::toSubAssemblyTag(size_t _subId) const
{
assertThrow(data() < (u256(1) << 64), Exception, "Tag already has subassembly set.");
-
assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
+ size_t tag = size_t(u256(data()) & 0xffffffffffffffffULL);
AssemblyItem r = *this;
r.m_type = PushTag;
- r.setPushTagSubIdAndTag(_subId, size_t(data()));
+ r.setPushTagSubIdAndTag(_subId, tag);
return r;
}
pair<size_t, size_t> AssemblyItem::splitForeignPushTag() const
{
assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
- return make_pair(size_t((data()) / (u256(1) << 64)) - 1, size_t(data()));
+ u256 combined = u256(data());
+ size_t subId = size_t((combined >> 64) - 1);
+ size_t tag = size_t(combined & 0xffffffffffffffffULL);
+ return make_pair(subId, tag);
}
void AssemblyItem::setPushTagSubIdAndTag(size_t _subId, size_t _tag)
{
assertThrow(m_type == PushTag || m_type == Tag, Exception, "");
- setData(_tag + (u256(_subId + 1) << 64));
+ u256 data = _tag;
+ if (_subId != size_t(-1))
+ data |= (u256(_subId) + 1) << 64;
+ setData(data);
}
unsigned AssemblyItem::bytesRequired(unsigned _addressLength) const
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
index be788ddb..dc116f88 100644
--- a/libevmasm/Instruction.h
+++ b/libevmasm/Instruction.h
@@ -39,7 +39,7 @@ enum class Instruction: uint8_t
{
STOP = 0x00, ///< halts execution
ADD, ///< addition operation
- MUL, ///< mulitplication operation
+ MUL, ///< multiplication operation
SUB, ///< subtraction operation
DIV, ///< integer division operation
SDIV, ///< signed integer division operation
@@ -50,11 +50,11 @@ enum class Instruction: uint8_t
EXP, ///< exponential operation
SIGNEXTEND, ///< extend length of signed integer
- LT = 0x10, ///< less-than comparision
- GT, ///< greater-than comparision
- SLT, ///< signed less-than comparision
- SGT, ///< signed greater-than comparision
- EQ, ///< equality comparision
+ LT = 0x10, ///< less-than comparison
+ GT, ///< greater-than comparison
+ SLT, ///< signed less-than comparison
+ SGT, ///< signed greater-than comparison
+ EQ, ///< equality comparison
ISZERO, ///< simple not operator
AND, ///< bitwise AND operation
OR, ///< bitwise OR operation
@@ -293,7 +293,7 @@ struct InstructionInfo
/// Information on all the instructions.
InstructionInfo instructionInfo(Instruction _inst);
-/// check whether instructions exists
+/// check whether instructions exists.
bool isValidInstruction(Instruction _inst);
/// Convert from string mnemonic to Instruction type.
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 425e5045..11d7160c 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -627,8 +627,7 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return _convertTo.category() == category() ||
- _convertTo.category() == Category::Integer ||
- _convertTo.category() == Category::FixedBytes;
+ (_convertTo.category() == Category::Integer && !dynamic_cast<IntegerType const&>(_convertTo).isAddress());
}
TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const
@@ -682,13 +681,7 @@ bigint FixedPointType::minIntegerValue() const
TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
- if (
- _other->category() != Category::RationalNumber &&
- _other->category() != category() &&
- _other->category() != Category::Integer
- )
- return TypePointer();
- auto commonType = Type::commonType(shared_from_this(), _other); //might be fixed point or integer
+ auto commonType = Type::commonType(shared_from_this(), _other);
if (!commonType)
return TypePointer();
@@ -696,19 +689,16 @@ TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePoi
// All fixed types can be compared
if (Token::isCompareOp(_operator))
return commonType;
- if (Token::isBitOp(_operator) || Token::isBooleanOp(_operator))
+ if (Token::isBitOp(_operator) || Token::isBooleanOp(_operator) || _operator == Token::Exp)
return TypePointer();
- if (auto fixType = dynamic_pointer_cast<FixedPointType const>(commonType))
- {
- if (Token::Exp == _operator)
- return TypePointer();
- }
- else if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType))
- if (intType->isAddress())
- return TypePointer();
return commonType;
}
+std::shared_ptr<IntegerType> FixedPointType::asIntegerType() const
+{
+ return std::make_shared<IntegerType>(numBits(), isSigned() ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned);
+}
+
tuple<bool, rational> RationalNumberType::parseRational(string const& _value)
{
rational value;
@@ -1148,7 +1138,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
auto fixed = fixedPointType();
solAssert(fixed, "");
int fractionalDigits = fixed->fractionalDigits();
- shiftedValue = (m_value.numerator() / m_value.denominator()) * pow(bigint(10), fractionalDigits);
+ shiftedValue = m_value.numerator() * pow(bigint(10), fractionalDigits) / m_value.denominator();
}
// we ignore the literal and hope that the type was correctly determined
@@ -1274,17 +1264,12 @@ bool StringLiteralType::isValidUTF8() const
return dev::validateUTF8(m_value);
}
-shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
-{
- if (_literal.length() <= 32)
- return make_shared<FixedBytesType>(_literal.length());
- return shared_ptr<FixedBytesType>();
-}
-
FixedBytesType::FixedBytesType(int _bytes): m_bytes(_bytes)
{
- solAssert(m_bytes >= 0 && m_bytes <= 32,
- "Invalid byte number for fixed bytes type: " + dev::toString(m_bytes));
+ solAssert(
+ m_bytes > 0 && m_bytes <= 32,
+ "Invalid byte number for fixed bytes type: " + dev::toString(m_bytes)
+ );
}
bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 345f84a1..a9536657 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -396,6 +396,9 @@ public:
/// smallest value in general.
bigint minIntegerValue() const;
+ /// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.
+ std::shared_ptr<IntegerType> asIntegerType() const;
+
private:
int m_totalBits;
int m_fractionalDigits;
@@ -502,10 +505,6 @@ class FixedBytesType: public Type
public:
virtual Category category() const override { return Category::FixedBytes; }
- /// @returns the smallest bytes type for the given literal or an empty pointer
- /// if no type fits.
- static std::shared_ptr<FixedBytesType> smallestTypeForLiteral(std::string const& _literal);
-
explicit FixedBytesType(int _bytes);
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
diff --git a/test/libsolidity/syntaxTests/empty_string_var.sol b/test/libsolidity/syntaxTests/empty_string_var.sol
new file mode 100644
index 00000000..e9837590
--- /dev/null
+++ b/test/libsolidity/syntaxTests/empty_string_var.sol
@@ -0,0 +1,11 @@
+contract C {
+ function f() {
+ var a = "";
+ bytes1 b = bytes1(a);
+ bytes memory c = bytes(a);
+ string memory d = string(a);
+ }
+}
+// ----
+// Warning: (34-39): Use of the "var" keyword is deprecated.
+// TypeError: (61-70): Explicit type conversion not allowed from "string memory" to "bytes1".
diff --git a/test/libsolidity/syntaxTests/types/bytes0.sol b/test/libsolidity/syntaxTests/types/bytes0.sol
new file mode 100644
index 00000000..7c6d5974
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/bytes0.sol
@@ -0,0 +1,5 @@
+contract C {
+ bytes0 b0 = 1;
+}
+// ----
+// DeclarationError: (15-21): Identifier not found or not unique.
diff --git a/test/libsolidity/syntaxTests/types/bytes256.sol b/test/libsolidity/syntaxTests/types/bytes256.sol
new file mode 100644
index 00000000..22b5408d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/bytes256.sol
@@ -0,0 +1,5 @@
+contract C {
+ bytes256 b256 = 1;
+}
+// ----
+// DeclarationError: (15-23): Identifier not found or not unique.
diff --git a/test/libsolidity/syntaxTests/types/bytes33.sol b/test/libsolidity/syntaxTests/types/bytes33.sol
new file mode 100644
index 00000000..7edf13d3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/bytes33.sol
@@ -0,0 +1,5 @@
+contract C {
+ bytes33 b33 = 1;
+}
+// ----
+// DeclarationError: (15-22): Identifier not found or not unique.
diff --git a/test/libsolidity/syntaxTests/types/bytesm.sol b/test/libsolidity/syntaxTests/types/bytesm.sol
new file mode 100644
index 00000000..550760b9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/bytesm.sol
@@ -0,0 +1,36 @@
+contract C {
+ byte b = byte(1);
+ bytes1 b1 = b;
+ bytes2 b2 = b1;
+ bytes3 b3 = b2;
+ bytes4 b4 = b3;
+ bytes5 b5 = b4;
+ bytes6 b6 = b5;
+ bytes7 b7 = b6;
+ bytes8 b8 = b7;
+ bytes9 b9 = b8;
+ bytes10 b10 = b9;
+ bytes11 b11 = b10;
+ bytes12 b12 = b11;
+ bytes13 b13 = b12;
+ bytes14 b14 = b13;
+ bytes15 b15 = b14;
+ bytes16 b16 = b15;
+ bytes17 b17 = b16;
+ bytes18 b18 = b17;
+ bytes19 b19 = b18;
+ bytes20 b20 = b19;
+ bytes21 b21 = b20;
+ bytes22 b22 = b21;
+ bytes23 b23 = b22;
+ bytes24 b24 = b23;
+ bytes25 b25 = b24;
+ bytes26 b26 = b25;
+ bytes27 b27 = b26;
+ bytes28 b28 = b27;
+ bytes29 b29 = b28;
+ bytes30 b30 = b29;
+ bytes31 b31 = b30;
+ bytes32 b32 = b31;
+}
+// ----