diff options
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | docs/style-guide.rst | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 17 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 4 | ||||
-rw-r--r-- | test/libsolidity/ASTJSON.cpp | 16 |
5 files changed, 36 insertions, 4 deletions
diff --git a/Changelog.md b/Changelog.md index bd8d924f..27f88cd2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -34,6 +34,7 @@ Features: * Commandline interface: Using ``-`` as filename allows reading from stdin. * Interface Json: Fallback function is now part of the ABI. * Interface: Version string now semver compatible. + * Code generator: Do not provide "new account gas" if we know the called account exists. Bugfixes: diff --git a/docs/style-guide.rst b/docs/style-guide.rst index f4b419c0..d2d922df 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -355,7 +355,7 @@ No:: selfdestruct(owner); } -For long function declarations, it is recommended to drop each arguent onto +For long function declarations, it is recommended to drop each argument onto it's own line at the same indentation level as the function body. The closing parenthesis and opening bracket should be placed on their own line as well at the same indentation level as the function declaration. diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 49ee6d34..0ea5e093 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -22,6 +22,7 @@ #include <libsolidity/ast/ASTJsonConverter.h> #include <boost/algorithm/string/join.hpp> +#include <libdevcore/UTF8.h> #include <libsolidity/ast/AST.h> using namespace std; @@ -397,9 +398,21 @@ bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) bool ASTJsonConverter::visit(Literal const& _node) { char const* tokenString = Token::toString(_node.token()); + size_t invalidPos = 0; + Json::Value value{_node.value()}; + if (!dev::validate(_node.value(), invalidPos)) + value = Json::nullValue; + Token::Value subdenomination = Token::Value(_node.subDenomination()); addJsonNode(_node, "Literal", { - make_pair("string", tokenString ? tokenString : Json::Value()), - make_pair("value", _node.value()), + make_pair("token", tokenString ? tokenString : Json::Value()), + make_pair("value", value), + make_pair("hexvalue", toHex(_node.value())), + make_pair( + "subdenomination", + subdenomination == Token::Illegal ? + Json::nullValue : + Json::Value{Token::toString(subdenomination)} + ), make_pair("type", type(_node)) }); return true; diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index de937b42..1cc4a50d 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1526,11 +1526,13 @@ void ExpressionCompiler::appendExternalFunctionCall( m_context << u256(0); m_context << dupInstruction(m_context.baseToCurrentStackOffset(contractStackPos)); + bool existenceChecked = false; // Check the the target contract exists (has code) for non-low-level calls. if (funKind == FunctionKind::External || funKind == FunctionKind::CallCode || funKind == FunctionKind::DelegateCall) { m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; m_context.appendConditionalJumpTo(m_context.errorTag()); + existenceChecked = true; } if (_functionType.gasSet()) @@ -1542,7 +1544,7 @@ void ExpressionCompiler::appendExternalFunctionCall( u256 gasNeededByCaller = eth::GasCosts::callGas + 10; if (_functionType.valueSet()) gasNeededByCaller += eth::GasCosts::callValueTransferGas; - if (!isCallCode && !isDelegateCall) + if (!isCallCode && !isDelegateCall && !existenceChecked) gasNeededByCaller += eth::GasCosts::callNewAccountGas; // we never know m_context << gasNeededByCaller << diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp index 882496d9..a0fc5dd7 100644 --- a/test/libsolidity/ASTJSON.cpp +++ b/test/libsolidity/ASTJSON.cpp @@ -195,6 +195,22 @@ BOOST_AUTO_TEST_CASE(placeholder_statement) BOOST_CHECK_EQUAL(placeholder["src"], "26:1:1"); } +BOOST_AUTO_TEST_CASE(non_utf8) +{ + CompilerStack c; + c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }"); + c.parse(); + map<string, unsigned> sourceIndices; + sourceIndices["a"] = 1; + Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); + Json::Value literal = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][1]; + BOOST_CHECK_EQUAL(literal["name"], "Literal"); + BOOST_CHECK_EQUAL(literal["attributes"]["hexvalue"], "ff"); + BOOST_CHECK_EQUAL(literal["attributes"]["token"], Json::nullValue); + BOOST_CHECK_EQUAL(literal["attributes"]["value"], Json::nullValue); + BOOST_CHECK(literal["attributes"]["type"].asString().find("invalid") != string::npos); +} + BOOST_AUTO_TEST_SUITE_END() } |