diff options
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/grammar.txt | 5 | ||||
-rw-r--r-- | liblll/CodeFragment.cpp | 8 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 9 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 20 |
5 files changed, 40 insertions, 3 deletions
diff --git a/Changelog.md b/Changelog.md index c7b8ac35..fdba5a46 100644 --- a/Changelog.md +++ b/Changelog.md @@ -17,6 +17,7 @@ Bugfixes: * Fixed crash concerning non-callable types. * Unused variable warnings no longer issued for variables used inside inline assembly. * Inline Assembly: Enforce function arguments when parsing functional instructions. + * Fixed segfault with constant function parameters ### 0.4.11 (2017-05-03) diff --git a/docs/grammar.txt b/docs/grammar.txt index 09e492f3..b38b7ffa 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -88,7 +88,6 @@ Expression = | Expression '||' Expression | Expression '?' Expression ':' Expression | Expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') Expression - | Expression? (',' Expression) | PrimaryExpression PrimaryExpression = Identifier @@ -96,6 +95,7 @@ PrimaryExpression = Identifier | NumberLiteral | HexLiteral | StringLiteral + | TupleExpression | ElementaryTypeNameExpression ExpressionList = Expression ( ',' Expression )* @@ -120,6 +120,9 @@ Identifier = [a-zA-Z_$] [a-zA-Z_$0-9]* HexNumber = '0x' [0-9a-fA-F]+ DecimalNumber = [0-9]+ +TupleExpression = '(' ( Expression ( ',' Expression )* )? ')' + | '[' ( Expression ( ',' Expression )* )? ']' + ElementaryTypeNameExpression = ElementaryTypeName ElementaryTypeName = 'address' | 'bool' | 'string' | 'var' diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp index afef63e9..1329ec9b 100644 --- a/liblll/CodeFragment.cpp +++ b/liblll/CodeFragment.cpp @@ -192,7 +192,13 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) { if (_t.size() != 2) error<IncorrectParameterCount>(); - m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm); + string fileName = firstAsString(); + if (fileName.empty()) + error<InvalidName>("Empty file name provided"); + string contents = contentsString(fileName); + if (contents.empty()) + error<InvalidName>(std::string("File not found (or empty): ") + fileName); + m_asm.append(CodeFragment::compile(contents, _s).m_asm); } else if (us == "SET") { diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2a8d1ff6..4194e1c2 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -463,6 +463,8 @@ bool TypeChecker::visit(FunctionDefinition const& _function) m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->interfaceType(isLibraryFunction))) m_errorReporter.fatalTypeError(var->location(), "Internal type is not allowed for public or external functions."); + + var->accept(*this); } for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers()) visitManually( @@ -487,7 +489,12 @@ bool TypeChecker::visit(FunctionDefinition const& _function) bool TypeChecker::visit(VariableDeclaration const& _variable) { - if (m_scope->contractKind() == ContractDefinition::ContractKind::Interface) + // Forbid any variable declarations inside interfaces unless they are part of + // a function's input/output parameters. + if ( + m_scope->contractKind() == ContractDefinition::ContractKind::Interface + && !_variable.isCallableParameter() + ) m_errorReporter.typeError(_variable.location(), "Variables cannot be declared in interfaces."); // Variables can be declared without type (with "var"), in which case the first assignment diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 0b3cb481..c4b1250f 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1597,6 +1597,16 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) CHECK_SUCCESS(text); } +BOOST_AUTO_TEST_CASE(constant_input_parameter) +{ + char const* text = R"( + contract test { + function f(uint[] constant a) { } + } + )"; + CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Illegal use of \"constant\" specifier."); +} + BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* text = R"( @@ -5582,6 +5592,16 @@ BOOST_AUTO_TEST_CASE(interface_variables) CHECK_ERROR(text, TypeError, "Variables cannot be declared in interfaces"); } +BOOST_AUTO_TEST_CASE(interface_function_parameters) +{ + char const* text = R"( + interface I { + function f(uint a) returns(bool); + } + )"; + success(text); +} + BOOST_AUTO_TEST_CASE(interface_enums) { char const* text = R"( |