Skip to content

Commit 1eb26f5

Browse files
committed
Hardening of Parser against illegal flag combinations
Avoids accidental combinations of term and type flags.
1 parent 4e49976 commit 1eb26f5

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ object Parsers {
13431343
private def flagOfToken(tok: Int): FlagSet = tok match {
13441344
case ABSTRACT => Abstract
13451345
case FINAL => Final
1346-
case IMPLICIT => Implicit
1346+
case IMPLICIT => ImplicitCommon
13471347
case LAZY => Lazy
13481348
case OVERRIDE => Override
13491349
case PRIVATE => Private
@@ -1377,12 +1377,21 @@ object Parsers {
13771377
|| flags1.isTypeFlags && flags2.isTypeFlags
13781378
)
13791379

1380-
def addFlag(mods: Modifiers, flag: FlagSet): Modifiers =
1380+
def addFlag(mods: Modifiers, flag: FlagSet): Modifiers = {
1381+
def incompatible(kind: String) = {
1382+
syntaxError(s"modifier(s) `${mods.flags}' not allowed for $kind")
1383+
Modifiers(flag)
1384+
}
13811385
if (compatible(mods.flags, flag)) mods | flag
1382-
else {
1383-
syntaxError(s"illegal modifier combination: ${mods.flags} and $flag")
1384-
mods
1386+
else flag match {
1387+
case Trait => incompatible("trait")
1388+
case Method => incompatible("method")
1389+
case Mutable => incompatible("variable")
1390+
case _ =>
1391+
syntaxError(s"illegal modifier combination: ${mods.flags} and $flag")
1392+
mods
13851393
}
1394+
}
13861395

13871396
/** AccessQualifier ::= "[" (Id | this) "]"
13881397
*/
@@ -1726,6 +1735,7 @@ object Parsers {
17261735
}
17271736
makeConstructor(Nil, vparamss, rhs).withMods(mods)
17281737
} else {
1738+
val mods1 = addFlag(mods, Method)
17291739
val name = ident()
17301740
val tparams = typeParamClauseOpt(ParamOwner.Def)
17311741
val vparamss = paramClauses(name)
@@ -1735,7 +1745,7 @@ object Parsers {
17351745
if (atScala2Brace) tpt = scalaUnit else accept(EQUALS)
17361746
expr()
17371747
} else EmptyTree
1738-
DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods | Method)
1748+
DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods1)
17391749
}
17401750
}
17411751

@@ -1792,7 +1802,7 @@ object Parsers {
17921802
*/
17931803
def tmplDef(start: Int, mods: Modifiers): Tree = in.token match {
17941804
case TRAIT =>
1795-
classDef(posMods(start, mods | Trait))
1805+
classDef(posMods(start, addFlag(mods, Trait)))
17961806
case CLASS =>
17971807
classDef(posMods(start, mods))
17981808
case CASECLASS =>
@@ -2009,7 +2019,7 @@ object Parsers {
20092019
}
20102020

20112021
def localDef(start: Int, implicitFlag: FlagSet): Tree =
2012-
defOrDcl(start, defAnnotsMods(localModifierTokens) | implicitFlag)
2022+
defOrDcl(start, addFlag(defAnnotsMods(localModifierTokens), implicitFlag))
20132023

20142024
/** BlockStatSeq ::= { BlockStat semi } [ResultExpr]
20152025
* BlockStat ::= Import
@@ -2038,7 +2048,7 @@ object Parsers {
20382048
if (in.token == IMPLICIT) {
20392049
val start = in.skipToken()
20402050
if (isIdent) stats += implicitClosure(start, Location.InBlock)
2041-
else stats += localDef(start, Implicit)
2051+
else stats += localDef(start, ImplicitCommon)
20422052
} else {
20432053
stats += localDef(in.offset, EmptyFlags)
20442054
}

0 commit comments

Comments
 (0)