aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/grammar.txt5
-rw-r--r--liblll/CodeFragment.cpp8
-rw-r--r--libsolidity/analysis/TypeChecker.cpp9
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp20
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"(