aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp22
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp44
3 files changed, 67 insertions, 0 deletions
diff --git a/Changelog.md b/Changelog.md
index c3482c4b..670182af 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,7 @@
Features:
* Optimizer: Add new optimization step to remove unused ``JUMPDEST``s.
+ * Type Checker: Warn on using literals as tight packing parameters in ``keccak256``, ``sha3``, ``sha256`` and ``ripemd160``.
Bugfixes:
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 99f3c64c..d594a060 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1446,6 +1446,28 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
_functionCall.annotation().type = make_shared<TupleType>(functionType->returnParameterTypes());
TypePointers parameterTypes = functionType->parameterTypes();
+
+ if (!functionType->padArguments())
+ {
+ for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ auto const& argType = type(*arguments[i]);
+ if (auto literal = dynamic_cast<RationalNumberType const*>(argType.get()))
+ {
+ /* If no mobile type is available an error will be raised elsewhere. */
+ if (literal->mobileType())
+ m_errorReporter.warning(
+ _functionCall.location(),
+ "The type of \"" +
+ argType->toString() +
+ "\" was inferred as " +
+ literal->mobileType()->toString() +
+ ". This is probably not desired. Use an explicit type to silence this warning."
+ );
+ }
+ }
+ }
+
if (!functionType->takesArbitraryParameters() && parameterTypes.size() != arguments.size())
{
string msg =
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 380978e8..15b06125 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -6744,6 +6744,50 @@ BOOST_AUTO_TEST_CASE(reject_interface_constructors)
CHECK_ERROR(text, TypeError, "Wrong argument count for constructor call: 1 arguments given but expected 0.");
}
+BOOST_AUTO_TEST_CASE(tight_packing_literals)
+{
+ char const* text = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return keccak256(1);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
+ text = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return keccak256(uint8(1));
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return sha3(1);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
+ text = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return sha256(1);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
+ text = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return ripemd160(1);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}