From 6fd0cf547e6f62e46380237b85a55cf7c4dd1072 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Feb 2021 17:03:42 +0100 Subject: [PATCH] fixup! Syntax changes for catching custom errors. --- libsolidity/analysis/TypeChecker.cpp | 27 ++++++++++--------- .../syntaxTests/tryCatch/catch_custom.sol | 14 ++++++++++ .../tryCatch/catch_custom_alias_error.sol | 18 +++++++++++++ .../catch_custom_involving_reserved.sol | 18 +++++++++++++ .../tryCatch/catch_custom_no_paren.sol | 14 ++++++++++ .../tryCatch/catch_custom_path.sol | 19 +++++++++++++ .../tryCatch/catch_custom_too_little.sol | 14 ++++++++++ .../tryCatch/catch_custom_too_many.sol | 14 ++++++++++ .../tryCatch/catch_custom_wrong_type.sol | 15 +++++++++++ .../syntaxTests/tryCatch/empty_catch.sol | 2 +- 10 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_alias_error.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_involving_reserved.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_no_paren.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_path.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_too_little.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_too_many.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_custom_wrong_type.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 097e9d2ba..afae43db3 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1007,7 +1007,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) "This try statement already has a low-level catch clause." ); lowLevelClause = &clause; - if (clause.parameters() && !clause.parameters()->parameters().empty()) + if (clause.parameters()) { if ( clause.parameters()->parameters().size() != 1 || @@ -1072,7 +1072,6 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) else { solAssert(clause.kind() == TryCatchClause::Kind::UserDefined, ""); - solAssert(*clause.errorName().annotation().requiredLookup == VirtualLookup::Static, ""); ErrorDefinition const* error = dynamic_cast(clause.errorName().annotation().referencedDeclaration); if (!error) { @@ -1091,16 +1090,20 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) !clause.parameters() || clause.parameters()->parameters().size() != error->parameters().size() ) - m_errorReporter.typeError(1271_error, clause.location(), "Expected `catch Panic(uint ...) { ... }`."); - else - for (auto&& [varDecl, parameter]: ranges::views::zip(clause.parameters()->parameters(), error->parameters())) - if (*varDecl->type() != *parameter->type()) - m_errorReporter.typeError( - 63958_error, - varDecl->location(), - ("Expected a parameter of type \"" + parameter->type()->toString(true) + "\" ") + - ("but got \"" + varDecl->type()->toString(true) + "\"") - ); + m_errorReporter.typeError( + 4873_error, + clause.location(), + ("Expected " + to_string(error->parameters().size()) + " parameters for error \"") + + (error->name() + "\" but got " + to_string(clause.parameters()->parameters().size()) + ".") + ); + for (auto&& [varDecl, parameter]: ranges::views::zip(clause.parameters()->parameters(), error->parameters())) + if (*varDecl->type() != *parameter->type()) + m_errorReporter.typeError( + 63958_error, + varDecl->location(), + ("Expected a parameter of type \"" + parameter->type()->toString(true) + "\" ") + + ("but got \"" + varDecl->type()->toString(true) + "\"") + ); } } } diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom.sol new file mode 100644 index 000000000..329029ffe --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom.sol @@ -0,0 +1,14 @@ +contract C { + error E(); + function f() public { + try this.f() { + + } catch E() { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// UnimplementedFeatureError: NONE diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_alias_error.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_alias_error.sol new file mode 100644 index 000000000..d366faac3 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_alias_error.sol @@ -0,0 +1,18 @@ +==== Source: A ==== +error E(uint); +==== Source: B ==== +import {E as Error} from "A"; + +contract C { + function f() public { + try this.f() { + + } catch Error(uint x) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError 2943: (B:104-136): Expected `catch Error(string memory ...) { ... }`. diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_involving_reserved.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_involving_reserved.sol new file mode 100644 index 000000000..6042dcef0 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_involving_reserved.sol @@ -0,0 +1,18 @@ +==== Source: A ==== +error E(uint); +==== Source: B ==== +import "A" as Error; + +contract C { + function f() public { + try this.f() { + + } catch Error.E(uint x) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// ParserError 2314: (B:106-107): Expected '(' but got '.' diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_no_paren.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_no_paren.sol new file mode 100644 index 000000000..f8d2d72b3 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_no_paren.sol @@ -0,0 +1,14 @@ +contract C { + error E(); + function f() public returns (uint, uint) { + try this.f() { + + } catch E { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// ParserError 2314: (117-118): Expected '(' but got '{' diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_path.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_path.sol new file mode 100644 index 000000000..5fc4902c3 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_path.sol @@ -0,0 +1,19 @@ +==== Source: A ==== +error E(uint); +==== Source: B ==== +import "A" as X; + +contract C { + function f() public { + try this.f() { + + } catch X.E(uint x) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// UnimplementedFeatureError: NONE +// Warning 5667: (B:101-107): Unused try/catch parameter. Remove or comment out the variable name to silence this warning. diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_little.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_little.sol new file mode 100644 index 000000000..51024bd04 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_little.sol @@ -0,0 +1,14 @@ +contract C { + error E(uint x); + function f() public returns (uint, uint) { + try this.f() { + + } catch E() { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError 4873: (115-137): Expected 1 parameters for error "E" but got 0. diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_many.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_many.sol new file mode 100644 index 000000000..a0aa165b2 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_too_many.sol @@ -0,0 +1,14 @@ +contract C { + error E(); + function f() public returns (uint, uint) { + try this.f() { + + } catch E(uint a) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError 4873: (109-137): Expected 0 parameters for error "E" but got 1. diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_custom_wrong_type.sol b/test/libsolidity/syntaxTests/tryCatch/catch_custom_wrong_type.sol new file mode 100644 index 000000000..e0536777d --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_custom_wrong_type.sol @@ -0,0 +1,15 @@ +contract C { + error E(uint a, uint8 b); + function f() public returns (uint, uint) { + try this.f() { + + } catch E(uint8 x, uint y) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError 63958: (132-139): Expected a parameter of type "uint256" but got "uint8" +// TypeError 63958: (141-147): Expected a parameter of type "uint8" but got "uint256" diff --git a/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol b/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol index d1ae8c52d..d48cdeb40 100644 --- a/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol +++ b/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol @@ -8,4 +8,4 @@ contract C { } } // ---- -// ParserError 3546: (101-102): Expected type name +// TypeError 6231: (94-115): Expected `catch (bytes memory ...) { ... }` or `catch { ... }`.