diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_empty_string.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_empty_string.sol new file mode 100644 index 000000000..4fea0c70f --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_empty_string.sol @@ -0,0 +1,34 @@ +contract C { + function f1() public returns (bytes memory) { + return abi.encode(""); + } + function f2(string calldata msg) public returns (bytes memory) { + return abi.encode(msg); + } + function g1() public returns (bytes memory) { + return abi.encodePacked(""); + } + function g2(string calldata msg) public returns (bytes memory) { + return abi.encodePacked(msg); + } + function h1() public returns (bytes memory) { + return abi.encodeWithSelector(0x00000001, ""); + } + function h2(string calldata msg) public returns (bytes memory) { + return abi.encodeWithSelector(0x00000001, msg); + } +} + +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f1() -> 0x20, 0x60, 0x20, 0, 0 +// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0 +// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0 +// g1() -> 32, 0 +// g2(string): 0x20, 0 -> 0x20, 0 +// g2(string): 0x20, 0, 0 -> 0x20, 0 +// h1() -> 0x20, 0x64, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0, 0 +// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0 diff --git a/test/libsolidity/semanticTests/revertStrings/empty_v1.sol b/test/libsolidity/semanticTests/revertStrings/empty_v1.sol new file mode 100644 index 000000000..41ba00942 --- /dev/null +++ b/test/libsolidity/semanticTests/revertStrings/empty_v1.sol @@ -0,0 +1,18 @@ +pragma abicoder v1; +contract C { + function f() public { + revert(""); + } + function g(string calldata msg) public { + revert(msg); + } +} +// ==== +// ABIEncoderV1Only: true +// EVMVersion: >=byzantium +// compileViaYul: false +// revertStrings: debug +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 0, "" +// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/test/libsolidity/semanticTests/revertStrings/empty_v1_yul.sol b/test/libsolidity/semanticTests/revertStrings/empty_v1_yul.sol new file mode 100644 index 000000000..ad9543c88 --- /dev/null +++ b/test/libsolidity/semanticTests/revertStrings/empty_v1_yul.sol @@ -0,0 +1,18 @@ +contract C { + function f() public { + revert(""); + } + function g(string calldata msg) public { + revert(msg); + } +} +// ==== +// ABIEncoderV1Only: true +// EVMVersion: >=byzantium +// compileViaYul: true +// revertStrings: debug +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/test/libsolidity/semanticTests/revertStrings/empty_v2.sol b/test/libsolidity/semanticTests/revertStrings/empty_v2.sol new file mode 100644 index 000000000..eafb05268 --- /dev/null +++ b/test/libsolidity/semanticTests/revertStrings/empty_v2.sol @@ -0,0 +1,18 @@ +pragma experimental ABIEncoderV2; +contract C { + function f() public { + revert(""); + } + function g(string calldata msg) public { + revert(msg); + } +} +// ==== +// EVMVersion: >=byzantium +// compileViaYul: also +// revertStrings: debug +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/test/libsolidity/semanticTests/strings/empty_string.sol b/test/libsolidity/semanticTests/strings/empty_string.sol new file mode 100644 index 000000000..a44eec703 --- /dev/null +++ b/test/libsolidity/semanticTests/strings/empty_string.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (string memory) { + return ""; + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 0 diff --git a/test/libsolidity/semanticTests/strings/empty_string_input.sol b/test/libsolidity/semanticTests/strings/empty_string_input.sol new file mode 100644 index 000000000..c1f0bca22 --- /dev/null +++ b/test/libsolidity/semanticTests/strings/empty_string_input.sol @@ -0,0 +1,30 @@ +contract C { + function f() public pure returns (string memory) { + return ""; + } + function g(string calldata msg) public pure returns (string memory) { + return msg; + } + function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) { + return (msg, v); + } + // Adjusting order of input/output intentionally. + function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) { + return (msg1, msg2, v); + } + function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) { + return (msg1, "", v); + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 0 +// g(string): 0x20, 0, "" -> 0x20, 0 +// g(string): 0x20, 0 -> 0x20, 0 +// h(string,uint256): 0x40, 0x888, 0, "" -> 0x40, 0x0888, 0 +// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0 +// i(string,uint256,string): 0x60, 0x888, 0x60, 0, "" -> 0x60, 0x80, 0x0888, 0, 0 +// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0 +// j(string,uint256): 0x40, 0x888, 0, "" -> 0x60, 0x80, 0x0888, 0, 0 +// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0 diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index 713a8d634..11eef3767 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -503,9 +503,9 @@ void TestFileParser::Scanner::scanNextToken() return TokenDesc{Token::Identifier, _literal}; }; - auto selectToken = [this](Token _token, std::string const& _literal = "") -> TokenDesc { + auto selectToken = [this](Token _token, std::optional _literal = std::nullopt) -> TokenDesc { advance(); - return make_pair(_token, !_literal.empty() ? _literal : formatToken(_token)); + return make_pair(_token, _literal.has_value() ? *_literal : formatToken(_token)); }; TokenDesc token = make_pair(Token::Unknown, ""); diff --git a/test/libsolidity/util/TestFileParser.h b/test/libsolidity/util/TestFileParser.h index 77d563260..8178c721d 100644 --- a/test/libsolidity/util/TestFileParser.h +++ b/test/libsolidity/util/TestFileParser.h @@ -120,8 +120,6 @@ private: std::string m_line; std::string::const_iterator m_char; - std::string m_currentLiteral; - TokenDesc m_currentToken; };