From b540ba527a70df440299de9c0bf44f9d11ac6ef6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 27 Mar 2018 14:38:28 +0100 Subject: Disallow empty structs --- Changelog.md | 1 + docs/grammar.txt | 2 +- libsolidity/analysis/SyntaxChecker.cpp | 7 +++++++ libsolidity/analysis/SyntaxChecker.h | 2 ++ test/libsolidity/SolidityNameAndTypeResolution.cpp | 2 +- test/libsolidity/syntaxTests/empty_struct.sol | 5 +++++ 6 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/empty_struct.sol diff --git a/Changelog.md b/Changelog.md index 9235ed3a..3fa0c485 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Bugfixes: * Commandline interface: Support ``--evm-version constantinople`` properly. * DocString Parser: Fix error message for empty descriptions. * Standard JSON: Support ``constantinople`` as ``evmVersion`` properly. + * Syntax Checker: Issue error for empty structs. * Type System: Make external library functions accessible. ### 0.4.21 (2018-03-07) diff --git a/docs/grammar.txt b/docs/grammar.txt index a5c2acf3..b4ca5ca9 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -19,7 +19,7 @@ InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';' UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';' StructDefinition = 'struct' Identifier '{' - ( VariableDeclaration ';' (VariableDeclaration ';')* )? '}' + ( VariableDeclaration ';' (VariableDeclaration ';')* ) '}' ModifierDefinition = 'modifier' Identifier ParameterList? Block ModifierInvocation = Identifier ( '(' ExpressionList? ')' )? diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index ddac194b..e03417a9 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -255,3 +255,10 @@ bool SyntaxChecker::visit(VariableDeclaration const& _declaration) } return true; } + +bool SyntaxChecker::visit(StructDefinition const& _struct) +{ + if (_struct.members().empty()) + m_errorReporter.syntaxError(_struct.location(), "Defining empty structs is disallowed."); + return true; +} diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h index 871bf0a9..1579df57 100644 --- a/libsolidity/analysis/SyntaxChecker.h +++ b/libsolidity/analysis/SyntaxChecker.h @@ -71,6 +71,8 @@ private: virtual bool visit(VariableDeclaration const& _declaration) override; + virtual bool visit(StructDefinition const& _struct) override; + ErrorReporter& m_errorReporter; /// Flag that indicates whether a function modifier actually contains '_'. diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index c5abac03..6163aed0 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -7279,7 +7279,7 @@ BOOST_AUTO_TEST_CASE(modifiers_access_storage_pointer) { char const* text = R"( contract C { - struct S { } + struct S { uint a; } modifier m(S storage x) { x; _; diff --git a/test/libsolidity/syntaxTests/empty_struct.sol b/test/libsolidity/syntaxTests/empty_struct.sol new file mode 100644 index 00000000..87bc2ffe --- /dev/null +++ b/test/libsolidity/syntaxTests/empty_struct.sol @@ -0,0 +1,5 @@ +contract test { + struct A {} +} +// ---- +// SyntaxError: Defining empty structs is disallowed. -- cgit