aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/style-guide.rst2
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp17
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp4
-rw-r--r--test/libsolidity/ASTJSON.cpp16
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()
}