aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/GlobalContext.cpp8
-rw-r--r--libsolidity/analysis/TypeChecker.cpp108
2 files changed, 66 insertions, 50 deletions
diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp
index 756bb540..7b4bc3aa 100644
--- a/libsolidity/analysis/GlobalContext.cpp
+++ b/libsolidity/analysis/GlobalContext.cpp
@@ -42,7 +42,7 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{
make_shared<MagicVariableDeclaration>("blockhash", make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)),
make_shared<MagicVariableDeclaration>("ecrecover", make_shared<FunctionType>(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Kind::ECRecover, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft, false, StateMutability::View)),
- make_shared<MagicVariableDeclaration>("keccak256", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA3, true, StateMutability::Pure)),
+ make_shared<MagicVariableDeclaration>("keccak256", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA3, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("log0", make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Kind::Log0)),
make_shared<MagicVariableDeclaration>("log1", make_shared<FunctionType>(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log1)),
make_shared<MagicVariableDeclaration>("log2", make_shared<FunctionType>(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log2)),
@@ -55,10 +55,10 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{
make_shared<MagicVariableDeclaration>("require", make_shared<FunctionType>(strings{"bool", "string memory"}, strings{}, FunctionType::Kind::Require, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings(), strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings{"string memory"}, strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)),
- make_shared<MagicVariableDeclaration>("ripemd160", make_shared<FunctionType>(strings(), strings{"bytes20"}, FunctionType::Kind::RIPEMD160, true, StateMutability::Pure)),
+ make_shared<MagicVariableDeclaration>("ripemd160", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes20"}, FunctionType::Kind::RIPEMD160, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("selfdestruct", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)),
- make_shared<MagicVariableDeclaration>("sha256", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA256, true, StateMutability::Pure)),
- make_shared<MagicVariableDeclaration>("sha3", make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Kind::SHA3, true, StateMutability::Pure)),
+ make_shared<MagicVariableDeclaration>("sha256", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA256, false, StateMutability::Pure)),
+ make_shared<MagicVariableDeclaration>("sha3", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA3, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("suicide", make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Kind::Selfdestruct)),
make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::Transaction))
})
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index e89ce27a..b9e3f8d0 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1712,12 +1712,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
m_errorReporter.typeError(_functionCall.location(), "\"suicide\" has been deprecated in favour of \"selfdestruct\"");
}
if (!m_insideEmitStatement && functionType->kind() == FunctionType::Kind::Event)
- {
- if (m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
- m_errorReporter.typeError(_functionCall.location(), "Event invocations have to be prefixed by \"emit\".");
- else
- m_errorReporter.warning(_functionCall.location(), "Invoking events without \"emit\" prefix is deprecated.");
- }
+ m_errorReporter.typeError(_functionCall.location(), "Event invocations have to be prefixed by \"emit\".");
TypePointers parameterTypes = functionType->parameterTypes();
@@ -1750,35 +1745,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
}
}
- if (functionType->takesSinglePackedBytesParameter())
- {
- if (
- (arguments.size() > 1) ||
- (arguments.size() == 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory)))
- )
- {
- string msg =
- "This function only accepts a single \"bytes\" argument. Please use "
- "\"abi.encodePacked(...)\" or a similar function to encode the data.";
- if (v050)
- m_errorReporter.typeError(_functionCall.location(), msg);
- else
- m_errorReporter.warning(_functionCall.location(), msg);
- }
-
- if (arguments.size() == 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory)))
- {
- string msg =
- "The provided argument of type " +
- type(*arguments.front())->toString() +
- " is not implicitly convertible to expected type bytes memory.";
- if (v050)
- m_errorReporter.typeError(_functionCall.location(), msg);
- else
- m_errorReporter.warning(_functionCall.location(), msg);
- }
- }
-
if (functionType->takesArbitraryParameters() && arguments.size() < parameterTypes.size())
{
solAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, "");
@@ -1810,6 +1776,26 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
for (auto const& member: membersRemovedForStructConstructor)
msg += " " + member;
}
+ else if (
+ functionType->kind() == FunctionType::Kind::BareCall ||
+ functionType->kind() == FunctionType::Kind::BareCallCode ||
+ functionType->kind() == FunctionType::Kind::BareDelegateCall
+ )
+ {
+ if (arguments.empty())
+ msg += " This function requires a single bytes argument. Use \"\" as argument to provide empty calldata.";
+ else
+ msg += " This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.";
+ }
+ else if (
+ functionType->kind() == FunctionType::Kind::SHA3 ||
+ functionType->kind() == FunctionType::Kind::SHA256 ||
+ functionType->kind() == FunctionType::Kind::RIPEMD160
+ )
+ msg +=
+ " This function requires a single bytes argument."
+ " Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour"
+ " or abi.encode(...) to use ABI encoding.";
m_errorReporter.typeError(_functionCall.location(), msg);
}
else if (isPositionalCall)
@@ -1846,15 +1832,31 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
}
}
else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
- m_errorReporter.typeError(
- arguments[i]->location(),
+ {
+ string msg =
"Invalid type for argument in function call. "
"Invalid implicit conversion from " +
type(*arguments[i])->toString() +
" to " +
parameterTypes[i]->toString() +
- " requested."
- );
+ " requested.";
+ if (
+ functionType->kind() == FunctionType::Kind::BareCall ||
+ functionType->kind() == FunctionType::Kind::BareCallCode ||
+ functionType->kind() == FunctionType::Kind::BareDelegateCall
+ )
+ msg += " This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.";
+ else if (
+ functionType->kind() == FunctionType::Kind::SHA3 ||
+ functionType->kind() == FunctionType::Kind::SHA256 ||
+ functionType->kind() == FunctionType::Kind::RIPEMD160
+ )
+ msg +=
+ " This function requires a single bytes argument."
+ " Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour"
+ " or abi.encode(...) to use ABI encoding.";
+ m_errorReporter.typeError(arguments[i]->location(), msg);
+ }
}
}
else
@@ -2287,14 +2289,28 @@ void TypeChecker::endVisit(Literal const& _literal)
if (_literal.looksLikeAddress())
{
- if (_literal.passesAddressChecksum())
- _literal.annotation().type = make_shared<IntegerType>(160, IntegerType::Modifier::Address);
- else
- m_errorReporter.warning(
+ // Assign type here if it even looks like an address. This prevents double error in 050 mode for invalid address
+ _literal.annotation().type = make_shared<IntegerType>(160, IntegerType::Modifier::Address);
+
+ string msg;
+ if (_literal.value().length() != 42) // "0x" + 40 hex digits
+ // looksLikeAddress enforces that it is a hex literal starting with "0x"
+ msg =
+ "This looks like an address but is not exactly 40 hex digits. It is " +
+ to_string(_literal.value().length() - 2) +
+ " hex digits.";
+ else if (!_literal.passesAddressChecksum())
+ {
+ msg = "This looks like an address but has an invalid checksum.";
+ if (!_literal.getChecksummedAddress().empty())
+ msg += " Correct checksummed address: \"" + _literal.getChecksummedAddress() + "\".";
+ }
+
+ if (!msg.empty())
+ m_errorReporter.syntaxError(
_literal.location(),
- "This looks like an address but has an invalid checksum. "
- "If this is not used as an address, please prepend '00'. " +
- (!_literal.getChecksummedAddress().empty() ? "Correct checksummed address: '" + _literal.getChecksummedAddress() + "'. " : "") +
+ msg +
+ " If this is not used as an address, please prepend '00'. " +
"For more information please see https://solidity.readthedocs.io/en/develop/types.html#address-literals"
);
}