mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix for constant strings.
This commit is contained in:
parent
ea981cb0f5
commit
985eb80695
@ -81,15 +81,16 @@ void ContractDefinition::checkTypeRequirements()
|
|||||||
if (!function->isFullyImplemented())
|
if (!function->isFullyImplemented())
|
||||||
setFullyImplemented(false);
|
setFullyImplemented(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ASTPointer<VariableDeclaration> const& variable: m_stateVariables)
|
||||||
|
variable->checkTypeRequirements();
|
||||||
|
|
||||||
for (ASTPointer<ModifierDefinition> const& modifier: functionModifiers())
|
for (ASTPointer<ModifierDefinition> const& modifier: functionModifiers())
|
||||||
modifier->checkTypeRequirements();
|
modifier->checkTypeRequirements();
|
||||||
|
|
||||||
for (ASTPointer<FunctionDefinition> const& function: definedFunctions())
|
for (ASTPointer<FunctionDefinition> const& function: definedFunctions())
|
||||||
function->checkTypeRequirements();
|
function->checkTypeRequirements();
|
||||||
|
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: m_stateVariables)
|
|
||||||
variable->checkTypeRequirements();
|
|
||||||
|
|
||||||
checkExternalTypeClashes();
|
checkExternalTypeClashes();
|
||||||
// check for hash collisions in function signatures
|
// check for hash collisions in function signatures
|
||||||
set<FixedHash<4>> hashes;
|
set<FixedHash<4>> hashes;
|
||||||
@ -559,9 +560,18 @@ void VariableDeclaration::checkTypeRequirements()
|
|||||||
BOOST_THROW_EXCEPTION(createTypeError("Illegal use of \"constant\" specifier."));
|
BOOST_THROW_EXCEPTION(createTypeError("Illegal use of \"constant\" specifier."));
|
||||||
if (!m_value)
|
if (!m_value)
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Uninitialized \"constant\" variable."));
|
BOOST_THROW_EXCEPTION(createTypeError("Uninitialized \"constant\" variable."));
|
||||||
else if (m_type && !m_type->isValueType())
|
if (m_type && !m_type->isValueType())
|
||||||
// TODO: const is implemented only for uint, bytesXX and enums types.
|
{
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Illegal use of \"constant\" specifier. \"constant\" is not implemented for this type yet."));
|
// TODO: const is implemented only for uint, bytesXX, string and enums types.
|
||||||
|
bool constImplemented = false;
|
||||||
|
if (auto arrayType = dynamic_cast<ArrayType const*>(m_type.get()))
|
||||||
|
constImplemented = arrayType->isByteArray();
|
||||||
|
if (!constImplemented)
|
||||||
|
BOOST_THROW_EXCEPTION(createTypeError(
|
||||||
|
"Illegal use of \"constant\" specifier. \"constant\" "
|
||||||
|
" is not yet implemented for this type."
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_type)
|
if (m_type)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,7 @@ void ExpressionCompiler::appendConstStateVariableAccessor(VariableDeclaration co
|
|||||||
{
|
{
|
||||||
solAssert(_varDecl.isConstant(), "");
|
solAssert(_varDecl.isConstant(), "");
|
||||||
_varDecl.value()->accept(*this);
|
_varDecl.value()->accept(*this);
|
||||||
|
utils().convertType(*_varDecl.value()->type(), *_varDecl.type());
|
||||||
|
|
||||||
// append return
|
// append return
|
||||||
m_context << eth::dupInstruction(_varDecl.type()->sizeOnStack() + 1);
|
m_context << eth::dupInstruction(_varDecl.type()->sizeOnStack() + 1);
|
||||||
@ -918,7 +919,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
|||||||
if (!variable->isConstant())
|
if (!variable->isConstant())
|
||||||
setLValueFromDeclaration(*declaration, _identifier);
|
setLValueFromDeclaration(*declaration, _identifier);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
variable->value()->accept(*this);
|
variable->value()->accept(*this);
|
||||||
|
utils().convertType(*variable->value()->type(), *variable->type());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<ContractDefinition const*>(declaration))
|
else if (dynamic_cast<ContractDefinition const*>(declaration))
|
||||||
{
|
{
|
||||||
|
@ -457,6 +457,14 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (_variable.isConstant())
|
||||||
|
{
|
||||||
|
if (loc != Location::Default && loc != Location::Memory)
|
||||||
|
BOOST_THROW_EXCEPTION(_variable.createTypeError(
|
||||||
|
"Storage location has to be \"memory\" (or unspecified) for constants."
|
||||||
|
));
|
||||||
|
loc = Location::Memory;
|
||||||
|
}
|
||||||
if (loc == Location::Default)
|
if (loc == Location::Default)
|
||||||
loc = _variable.isCallableParameter() ? Location::Memory : Location::Storage;
|
loc = _variable.isCallableParameter() ? Location::Memory : Location::Storage;
|
||||||
bool isPointer = !_variable.isStateVariable();
|
bool isPointer = !_variable.isStateVariable();
|
||||||
|
@ -5183,6 +5183,38 @@ BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable)
|
|||||||
BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(555)));
|
BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(555)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(constant_string_literal)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract Test {
|
||||||
|
bytes32 constant public b = "abcdefghijklmnopq";
|
||||||
|
string constant public x = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca";
|
||||||
|
|
||||||
|
function Test() {
|
||||||
|
var xx = x;
|
||||||
|
var bb = b;
|
||||||
|
}
|
||||||
|
function getB() returns (bytes32) { return b; }
|
||||||
|
function getX() returns (string) { return x; }
|
||||||
|
function getX2() returns (string r) { r = x; }
|
||||||
|
function unused() returns (uint) {
|
||||||
|
"unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
string longStr = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca";
|
||||||
|
string shortStr = "abcdefghijklmnopq";
|
||||||
|
BOOST_CHECK(callContractFunction("b()") == encodeArgs(shortStr));
|
||||||
|
BOOST_CHECK(callContractFunction("x()") == encodeDyn(longStr));
|
||||||
|
BOOST_CHECK(callContractFunction("getB()") == encodeArgs(shortStr));
|
||||||
|
BOOST_CHECK(callContractFunction("getX()") == encodeDyn(longStr));
|
||||||
|
BOOST_CHECK(callContractFunction("getX2()") == encodeDyn(longStr));
|
||||||
|
BOOST_CHECK(callContractFunction("unused()") == encodeArgs(2));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_string_as_mapping_key_without_variable)
|
BOOST_AUTO_TEST_CASE(storage_string_as_mapping_key_without_variable)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user