Skip to content

Commit d07b796

Browse files
cameelMarenz
authored andcommitted
Disallow modifier declarations and definitions in interfaces
1 parent 13691df commit d07b796

11 files changed

+71
-12
lines changed

Changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ Compiler Features:
1313

1414

1515
Bugfixes:
16+
* SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions.
1617
* SMTChecker: Fix false positive in external calls from constructors.
1718
* SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants.
18-
* SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions.
19+
* Type Checker: Disallow modifier declarations and definitions in interfaces.
1920

2021

2122

docs/contracts/interfaces.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
Interfaces
77
**********
88

9-
Interfaces are similar to abstract contracts, but they cannot have any functions implemented. There are further restrictions:
9+
Interfaces are similar to abstract contracts, but they cannot have any functions implemented.
10+
There are further restrictions:
1011

1112
- They cannot inherit from other contracts, but they can inherit from other interfaces.
1213
- All declared functions must be external.
1314
- They cannot declare a constructor.
1415
- They cannot declare state variables.
16+
- They cannot declare modifiers.
1517

1618
Some of these restrictions might be lifted in the future.
1719

libsolidity/analysis/TypeChecker.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,22 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance)
314314

315315
void TypeChecker::endVisit(ModifierDefinition const& _modifier)
316316
{
317-
if (_modifier.virtualSemantics())
318-
if (auto const* contractDef = dynamic_cast<ContractDefinition const*>(_modifier.scope()))
319-
if (contractDef->isLibrary())
320-
m_errorReporter.typeError(
321-
3275_error,
322-
_modifier.location(),
323-
"Modifiers in a library cannot be virtual."
324-
);
317+
if (auto const* contractDef = dynamic_cast<ContractDefinition const*>(_modifier.scope()))
318+
{
319+
if (_modifier.virtualSemantics() && contractDef->isLibrary())
320+
m_errorReporter.typeError(
321+
3275_error,
322+
_modifier.location(),
323+
"Modifiers in a library cannot be virtual."
324+
);
325+
326+
if (contractDef->isInterface())
327+
m_errorReporter.typeError(
328+
6408_error,
329+
_modifier.location(),
330+
"Modifiers cannot be defined or declared in interfaces."
331+
);
332+
}
325333

326334
if (!_modifier.isImplemented() && !_modifier.virtualSemantics())
327335
m_errorReporter.typeError(8063_error, _modifier.location(), "Modifiers without implementation must be marked virtual.");

test/libsolidity/analysis/FunctionCallGraph.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,6 @@ BOOST_AUTO_TEST_CASE(interfaces_and_abstract_contracts)
11141114
unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R"(
11151115
interface I {
11161116
event Ev(uint);
1117-
modifier m() virtual;
11181117
11191118
function ext1() external;
11201119
function ext2() external;
@@ -1126,6 +1125,8 @@ BOOST_AUTO_TEST_CASE(interfaces_and_abstract_contracts)
11261125
}
11271126
11281127
abstract contract C is J {
1128+
modifier m() virtual;
1129+
11291130
function ext3() external override virtual;
11301131
function ext4() external { inr2();}
11311132
function inr1() internal virtual;
@@ -1167,7 +1168,7 @@ BOOST_AUTO_TEST_CASE(interfaces_and_abstract_contracts)
11671168
{"Entry", "function C.ext4()"},
11681169
{"function C.ext4()", "function C.inr2()"},
11691170
{"function C.inr2()", "function C.inr1()"},
1170-
{"function C.inr2()", "modifier I.m"},
1171+
{"function C.inr2()", "modifier C.m"},
11711172
}},
11721173
{"D", {
11731174
{"Entry", "function D.ext1()"},
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
contract C {
2+
modifier m { _; }
3+
modifier mv virtual { _; }
4+
}
5+
6+
abstract contract A {
7+
modifier m { _; }
8+
modifier mv virtual { _; }
9+
modifier muv virtual;
10+
}
11+
// ----
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
contract C {
2+
modifier mu;
3+
modifier muv virtual;
4+
}
5+
// ----
6+
// TypeError 3656: (0-57): Contract "C" should be marked as abstract.
7+
// TypeError 8063: (17-29): Modifiers without implementation must be marked virtual.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
interface I {
2+
modifier m { _; }
3+
modifier mu;
4+
modifier mv virtual { _; }
5+
modifier muv virtual;
6+
}
7+
// ----
8+
// TypeError 6408: (18-35): Modifiers cannot be defined or declared in interfaces.
9+
// TypeError 6408: (40-52): Modifiers cannot be defined or declared in interfaces.
10+
// TypeError 8063: (40-52): Modifiers without implementation must be marked virtual.
11+
// TypeError 6408: (57-83): Modifiers cannot be defined or declared in interfaces.
12+
// TypeError 6408: (88-109): Modifiers cannot be defined or declared in interfaces.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
library L {
2+
modifier mv virtual { _; }
3+
}
4+
// ----
5+
// TypeError 3275: (16-42): Modifiers in a library cannot be virtual.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
library L {
2+
modifier mu;
3+
modifier muv virtual;
4+
}
5+
// ----
6+
// TypeError 8063: (16-28): Modifiers without implementation must be marked virtual.
7+
// TypeError 3275: (33-54): Modifiers in a library cannot be virtual.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
library L {
2+
modifier m { _; }
3+
}
4+
// ----

0 commit comments

Comments
 (0)