aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFederico Bond <federicobond@gmail.com>2017-09-30 05:45:17 +0800
committerFederico Bond <federicobond@gmail.com>2017-09-30 06:17:31 +0800
commit6d9544795543498e9bc92943c41f07c2daf3bb78 (patch)
treedcddcbd78f6f76db0c8197334006f4e57f58c6c0
parentba7c5d2305d3486ddd699637a881ee229627082f (diff)
downloaddexon-solidity-6d9544795543498e9bc92943c41f07c2daf3bb78.tar.gz
dexon-solidity-6d9544795543498e9bc92943c41f07c2daf3bb78.tar.zst
dexon-solidity-6d9544795543498e9bc92943c41f07c2daf3bb78.zip
Emit error when declaring event with same name and arguments twice
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp44
-rw-r--r--libsolidity/analysis/TypeChecker.h1
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp55
4 files changed, 101 insertions, 0 deletions
diff --git a/Changelog.md b/Changelog.md
index 008b3c86..81f0b3a6 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -9,6 +9,7 @@ Bugfixes:
* Type Checker: Properly check array length and don't rely on an assertion in code generation.
* Type Checker: Properly support overwriting members inherited from ``address`` in a contract
(such as ``balance``, ``transfer``, etc.)
+ * Type Checker: Prevent duplicate event declarations.
### 0.4.17 (2017-09-21)
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 43930125..60154758 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -75,6 +75,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
ASTNode::listAccept(_contract.baseContracts(), *this);
checkContractDuplicateFunctions(_contract);
+ checkContractDuplicateEvents(_contract);
checkContractIllegalOverrides(_contract);
checkContractAbstractFunctions(_contract);
checkContractAbstractConstructors(_contract);
@@ -218,6 +219,49 @@ void TypeChecker::checkContractDuplicateFunctions(ContractDefinition const& _con
}
}
+void TypeChecker::checkContractDuplicateEvents(ContractDefinition const& _contract)
+{
+ /// Checks that two events with the same name defined in this contract have different
+ /// argument types
+ map<string, vector<EventDefinition const*>> events;
+ for (EventDefinition const* event: _contract.events())
+ events[event->name()].push_back(event);
+
+ for (auto const& it: events)
+ {
+ vector<EventDefinition const*> const& overloads = it.second;
+ set<size_t> reported;
+ for (size_t i = 0; i < overloads.size() && !reported.count(i); ++i)
+ {
+ SecondarySourceLocation ssl;
+
+ for (size_t j = i + 1; j < overloads.size(); ++j)
+ if (FunctionType(*overloads[i]).hasEqualArgumentTypes(FunctionType(*overloads[j])))
+ {
+ ssl.append("Other declaration is here:", overloads[j]->location());
+ reported.insert(j);
+ }
+
+ if (ssl.infos.size() > 0)
+ {
+ string msg = "Event with same name and arguments defined twice.";
+ size_t occurrences = ssl.infos.size();
+ if (occurrences > 32)
+ {
+ ssl.infos.resize(32);
+ msg += " Truncated from " + boost::lexical_cast<string>(occurrences) + " to the first 32 occurrences.";
+ }
+
+ m_errorReporter.declarationError(
+ overloads[i]->location(),
+ ssl,
+ msg
+ );
+ }
+ }
+ }
+}
+
void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _contract)
{
// Mapping from name to function definition (exactly one per argument type equality class) and
diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h
index 0c6f54d3..929be6e6 100644
--- a/libsolidity/analysis/TypeChecker.h
+++ b/libsolidity/analysis/TypeChecker.h
@@ -61,6 +61,7 @@ private:
/// Checks that two functions defined in this contract with the same name have different
/// arguments and that there is at most one constructor.
void checkContractDuplicateFunctions(ContractDefinition const& _contract);
+ void checkContractDuplicateEvents(ContractDefinition const& _contract);
void checkContractIllegalOverrides(ContractDefinition const& _contract);
/// Reports a type error with an appropiate message if overriden function signature differs.
/// Also stores the direct super function in the AST annotations.
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index c3a1ce08..8b112257 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -1395,6 +1395,61 @@ BOOST_AUTO_TEST_CASE(events_with_same_name)
BOOST_CHECK(success(text));
}
+BOOST_AUTO_TEST_CASE(events_with_same_name_unnamed_arguments)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint);
+ event A(uint, uint);
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(events_with_same_name_different_types)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint);
+ event A(bytes);
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint i);
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration_ignores_anonymous)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint i) anonymous;
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration_ignores_indexed)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint indexed i);
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
BOOST_AUTO_TEST_CASE(event_call)
{
char const* text = R"(