mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
parent
ef269bf40d
commit
38f9667e09
@ -46,6 +46,7 @@ Breaking Changes:
|
|||||||
* Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode.
|
* Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode.
|
||||||
* Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode.
|
* Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode.
|
||||||
* Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode.
|
* Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode.
|
||||||
|
* Type Checker: Detecting cyclic dependencies in variables and structs is limited in recursion to 256.
|
||||||
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
|
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
|
||||||
* Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode.
|
* Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode.
|
||||||
* Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode.
|
* Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode.
|
||||||
|
@ -32,11 +32,13 @@ template <typename V>
|
|||||||
class CycleDetector
|
class CycleDetector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using Visitor = std::function<void(V const&, CycleDetector&, size_t)>;
|
||||||
|
|
||||||
/// Initializes the cycle detector
|
/// Initializes the cycle detector
|
||||||
/// @param _visit function that is given the current vertex
|
/// @param _visit function that is given the current vertex
|
||||||
/// and is supposed to call @a run on all
|
/// and is supposed to call @a run on all
|
||||||
/// adjacent vertices.
|
/// adjacent vertices.
|
||||||
explicit CycleDetector(std::function<void(V const&, CycleDetector&)> _visit):
|
explicit CycleDetector(Visitor _visit):
|
||||||
m_visit(std::move(_visit))
|
m_visit(std::move(_visit))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ public:
|
|||||||
m_processing.insert(&_vertex);
|
m_processing.insert(&_vertex);
|
||||||
|
|
||||||
m_depth++;
|
m_depth++;
|
||||||
m_visit(_vertex, *this);
|
m_visit(_vertex, *this, m_depth);
|
||||||
m_depth--;
|
m_depth--;
|
||||||
if (m_firstCycleVertex && m_depth == 1)
|
if (m_firstCycleVertex && m_depth == 1)
|
||||||
m_firstCycleVertex = &_vertex;
|
m_firstCycleVertex = &_vertex;
|
||||||
@ -66,7 +68,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(V const&, CycleDetector&)> m_visit;
|
Visitor m_visit;
|
||||||
std::set<V const*> m_processing;
|
std::set<V const*> m_processing;
|
||||||
std::set<V const*> m_processed;
|
std::set<V const*> m_processed;
|
||||||
size_t m_depth = 0;
|
size_t m_depth = 0;
|
||||||
|
@ -91,8 +91,11 @@ bool PostTypeChecker::visit(Identifier const& _identifier)
|
|||||||
|
|
||||||
VariableDeclaration const* PostTypeChecker::findCycle(VariableDeclaration const& _startingFrom)
|
VariableDeclaration const* PostTypeChecker::findCycle(VariableDeclaration const& _startingFrom)
|
||||||
{
|
{
|
||||||
auto visitor = [&](VariableDeclaration const& _variable, CycleDetector<VariableDeclaration>& _cycleDetector)
|
auto visitor = [&](VariableDeclaration const& _variable, CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)
|
||||||
{
|
{
|
||||||
|
if (_depth >= 256)
|
||||||
|
m_errorReporter.fatalDeclarationError(_variable.location(), "Variable definition exhausting cyclic dependency validator.");
|
||||||
|
|
||||||
// Iterating through the dependencies needs to be deterministic and thus cannot
|
// Iterating through the dependencies needs to be deterministic and thus cannot
|
||||||
// depend on the memory layout.
|
// depend on the memory layout.
|
||||||
// Because of that, we sort by AST node id.
|
// Because of that, we sort by AST node id.
|
||||||
|
@ -595,8 +595,11 @@ bool TypeChecker::visit(StructDefinition const& _struct)
|
|||||||
m_errorReporter.typeError(member->location(), "Type cannot be used in struct.");
|
m_errorReporter.typeError(member->location(), "Type cannot be used in struct.");
|
||||||
|
|
||||||
// Check recursion, fatal error if detected.
|
// Check recursion, fatal error if detected.
|
||||||
auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector)
|
auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector, size_t _depth)
|
||||||
{
|
{
|
||||||
|
if (_depth >= 256)
|
||||||
|
m_errorReporter.fatalDeclarationError(_struct.location(), "Struct definition exhausting cyclic dependency validator.");
|
||||||
|
|
||||||
for (ASTPointer<VariableDeclaration> const& member: _struct.members())
|
for (ASTPointer<VariableDeclaration> const& member: _struct.members())
|
||||||
{
|
{
|
||||||
Type const* memberType = type(*member).get();
|
Type const* memberType = type(*member).get();
|
||||||
|
@ -2119,7 +2119,7 @@ bool StructType::recursive() const
|
|||||||
{
|
{
|
||||||
if (!m_recursive.is_initialized())
|
if (!m_recursive.is_initialized())
|
||||||
{
|
{
|
||||||
auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector)
|
auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector, size_t /*_depth*/)
|
||||||
{
|
{
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: _struct.members())
|
for (ASTPointer<VariableDeclaration> const& variable: _struct.members())
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user