mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2542 from federicobond/disallow-non-pure-constant
Disallow non-pure constant state variables (0.5.0)
This commit is contained in:
commit
cfc4e5dde3
@ -3,6 +3,7 @@
|
|||||||
Features:
|
Features:
|
||||||
* Parser: Better error message for unexpected trailing comma in parameter lists.
|
* Parser: Better error message for unexpected trailing comma in parameter lists.
|
||||||
* Syntax Checker: Unary ``+`` is now a syntax error as experimental 0.5.0 feature.
|
* Syntax Checker: Unary ``+`` is now a syntax error as experimental 0.5.0 feature.
|
||||||
|
* Type Checker: Disallow non-pure constant state variables as experimental 0.5.0 feature.
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Parser: Fix source location of VariableDeclarationStatement.
|
* Parser: Fix source location of VariableDeclarationStatement.
|
||||||
|
@ -645,15 +645,24 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
|
|||||||
if (!allowed)
|
if (!allowed)
|
||||||
m_errorReporter.typeError(_variable.location(), "Constants of non-value type not yet implemented.");
|
m_errorReporter.typeError(_variable.location(), "Constants of non-value type not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_variable.value())
|
if (!_variable.value())
|
||||||
m_errorReporter.typeError(_variable.location(), "Uninitialized \"constant\" variable.");
|
m_errorReporter.typeError(_variable.location(), "Uninitialized \"constant\" variable.");
|
||||||
else if (!_variable.value()->annotation().isPure)
|
else if (!_variable.value()->annotation().isPure)
|
||||||
|
{
|
||||||
|
if (_variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
_variable.value()->location(),
|
||||||
|
"Initial value for constant variable has to be compile-time constant."
|
||||||
|
);
|
||||||
|
else
|
||||||
m_errorReporter.warning(
|
m_errorReporter.warning(
|
||||||
_variable.value()->location(),
|
_variable.value()->location(),
|
||||||
"Initial value for constant variable has to be compile-time constant. "
|
"Initial value for constant variable has to be compile-time constant. "
|
||||||
"This will fail to compile with the next breaking version change."
|
"This will fail to compile with the next breaking version change."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!_variable.isStateVariable())
|
if (!_variable.isStateVariable())
|
||||||
{
|
{
|
||||||
if (varType->dataStoredIn(DataLocation::Memory) || varType->dataStoredIn(DataLocation::CallData))
|
if (varType->dataStoredIn(DataLocation::Memory) || varType->dataStoredIn(DataLocation::CallData))
|
||||||
|
@ -2361,17 +2361,28 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
|
|||||||
CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable.");
|
CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
|
BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable_0_4_x)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
address constant x = msg.sender;
|
address constant x = msg.sender;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
// Change to TypeError for 0.5.0.
|
|
||||||
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
|
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
pragma experimental "v0.5.0";
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
address constant x = msg.sender;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant.");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
|
BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
@ -2388,7 +2399,7 @@ BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
|
|||||||
CHECK_ERROR(text, TypeError, "Index access for string is not possible.");
|
CHECK_ERROR(text, TypeError, "Index access for string is not possible.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
|
BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant_0_4_x)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
@ -2396,10 +2407,22 @@ BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
|
|||||||
uint constant y = x();
|
uint constant y = x();
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
// Change to TypeError for 0.5.0.
|
|
||||||
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
|
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
pragma experimental "v0.5.0";
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function () constant returns (uint) x;
|
||||||
|
uint constant y = x();
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant.");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_to_const_var_involving_conversion)
|
BOOST_AUTO_TEST_CASE(assignment_to_const_var_involving_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user