Skip to content

Commit 0a1d70b

Browse files
committed
[MERGE #5471 @aneeshdk] Fixing an issue with super restriction state in undodefer case
Merge pull request #5471 from aneeshdk:users/aneeshd/SuperUndoDeferIssue We currently store the status of whether super call is allowed or super property is allowed in the Parser. Because of this when we do an undodefer of a member function that state information gets lost. This change is to put that information in the function node itself and use it from there while parsing super references.
2 parents 1fc4e1f + cdbc95a commit 0a1d70b

File tree

6 files changed

+65
-77
lines changed

6 files changed

+65
-77
lines changed

lib/Parser/Parse.cpp

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
9696
m_funcInArray(0),
9797
m_scopeCountNoAst(0),
9898

99-
m_parsingSuperRestrictionState(ParsingSuperRestrictionState_SuperDisallowed),
100-
10199
m_funcParenExprDepth(0),
102100
m_deferEllipsisError(false),
103101
m_deferEllipsisErrorLoc(), // calls default initializer
@@ -329,11 +327,6 @@ HRESULT Parser::ParseSourceInternal(
329327

330328
try
331329
{
332-
if ((grfscr & fscrEvalCode) != 0)
333-
{
334-
this->m_parsingSuperRestrictionState = Parser::ParsingSuperRestrictionState_SuperPropertyAllowed;
335-
}
336-
337330
if ((grfscr & fscrIsModuleCode) != 0)
338331
{
339332
// Module source flag should not be enabled unless module is enabled
@@ -961,6 +954,7 @@ ParseNodeProg * Parser::CreateProgNode(bool isModuleSource, ULONG lineNumber)
961954
pnodeProg->cbMin = this->GetScanner()->IecpMinTok();
962955
pnodeProg->lineNumber = lineNumber;
963956
pnodeProg->homeObjLocation = Js::Constants::NoRegister;
957+
pnodeProg->superRestrictionState = SuperRestrictionState::Disallowed;
964958
return pnodeProg;
965959
}
966960

@@ -3050,7 +3044,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
30503044
{
30513045
Assert((stub->fncFlags & kFunctionIsLambda) == kFunctionIsLambda);
30523046

3053-
pnode = ParseFncDeclCheckScope<true>(fFncLambda, /* resetParsingSuperRestrictionState*/ false);
3047+
pnode = ParseFncDeclCheckScope<true>(fFncLambda);
30543048
break;
30553049
}
30563050
}
@@ -3318,7 +3312,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
33183312
{
33193313
flags |= fFncAsync;
33203314
}
3321-
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, pNameHint, false, true, fUnaryOrParen);
3315+
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, pNameHint, false, true, fUnaryOrParen);
33223316
if (isAsyncExpr)
33233317
{
33243318
pnode->AsParseNodeFnc()->cbMin = iecpMin;
@@ -4286,10 +4280,8 @@ ParseNodeBin * Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint)
42864280
flags |= fFncOneArg;
42874281
}
42884282

4289-
AutoParsingSuperRestrictionStateRestorer restorer(this);
4290-
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
4291-
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, *ppNameHint,
4292-
/*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
4283+
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::PropertyAllowed, *ppNameHint,
4284+
/*needsPIDOnRCurlyScan*/ false);
42934285

42944286
if (isComputedName)
42954287
{
@@ -4610,10 +4602,8 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
46104602
// Rewind to the PID and parse a function expression.
46114603
this->GetScanner()->SeekTo(atPid);
46124604

4613-
AutoParsingSuperRestrictionStateRestorer restorer(this);
4614-
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
4615-
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), pFullNameHint,
4616-
/*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
4605+
ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), SuperRestrictionState::PropertyAllowed, pFullNameHint,
4606+
/*needsPIDOnRCurlyScan*/ false);
46174607

46184608
if (isAsyncMethod || isGenerator)
46194609
{
@@ -4825,7 +4815,7 @@ BOOL Parser::IsDeferredFnc()
48254815
}
48264816

48274817
template<bool buildAST>
4828-
ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperRestrictionState, bool fAllowIn)
4818+
ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool fAllowIn)
48294819
{
48304820
ParseNodeBlock * pnodeFncBlockScope = nullptr;
48314821
ParseNodePtr *ppnodeScopeSave = nullptr;
@@ -4853,7 +4843,7 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
48534843
}
48544844
}
48554845

4856-
ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, resetParsingSuperRestrictionState, /* fUnaryOrParen */ false, noStmtContext, fAllowIn);
4846+
ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ false, noStmtContext, SuperRestrictionState::Disallowed, fAllowIn);
48574847

48584848
if (pnodeFncBlockScope)
48594849
{
@@ -4872,22 +4862,15 @@ ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperR
48724862
}
48734863

48744864
template<bool buildAST>
4875-
ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool fAllowIn)
4865+
ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool fAllowIn)
48764866
{
48774867
Assert((flags & fFncDeclaration) == 0);
4878-
return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, resetParsingSuperRestrictionState, fUnaryOrParen, /* noStmtContext */ false, fAllowIn);
4868+
return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, fUnaryOrParen, /* noStmtContext */ false, superRestrictionState, fAllowIn);
48794869
}
48804870

48814871
template<bool buildAST>
4882-
ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool noStmtContext, bool fAllowIn)
4872+
ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState, bool fAllowIn)
48834873
{
4884-
AutoParsingSuperRestrictionStateRestorer restorer(this);
4885-
if (resetParsingSuperRestrictionState)
4886-
{
4887-
// ParseFncDecl will always reset m_parsingSuperRestrictionState to super disallowed unless explicitly disabled
4888-
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
4889-
}
4890-
48914874
ParseNodeFnc * pnodeFnc = nullptr;
48924875
ParseNodePtr *ppnodeVarSave = nullptr;
48934876

@@ -4923,6 +4906,7 @@ ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, c
49234906
pnodeFnc->nestedFuncEscapes = false;
49244907
pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
49254908
pnodeFnc->functionId = (*m_nextFunctionId)++;
4909+
pnodeFnc->superRestrictionState = superRestrictionState;
49264910

49274911

49284912
// Push new parser state with this new function node
@@ -6689,7 +6673,7 @@ void Parser::ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParent
66896673
template<bool buildAST>
66906674
ParseNodePtr Parser::GenerateModuleFunctionWrapper()
66916675
{
6692-
ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, nullptr, false, true, true);
6676+
ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, SuperRestrictionState::Disallowed, nullptr, false, true, true);
66936677
ParseNodePtr callNode = CreateCallNode(knopCall, pnodeFnc, nullptr);
66946678

66956679
return callNode;
@@ -7378,24 +7362,6 @@ LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberNa
73787362
return pFinalName;
73797363
}
73807364

7381-
class AutoParsingSuperRestrictionStateRestorer
7382-
{
7383-
public:
7384-
AutoParsingSuperRestrictionStateRestorer(Parser* parser) : m_parser(parser)
7385-
{
7386-
AssertMsg(this->m_parser != nullptr, "This just should not happen");
7387-
this->m_originalParsingSuperRestrictionState = this->m_parser->m_parsingSuperRestrictionState;
7388-
}
7389-
~AutoParsingSuperRestrictionStateRestorer()
7390-
{
7391-
AssertMsg(this->m_parser != nullptr, "This just should not happen");
7392-
this->m_parser->m_parsingSuperRestrictionState = m_originalParsingSuperRestrictionState;
7393-
}
7394-
private:
7395-
Parser * m_parser;
7396-
int m_originalParsingSuperRestrictionState;
7397-
};
7398-
73997365
template<bool buildAST>
74007366
ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, uint32 *pHintLength, uint32 *pShortNameOffset)
74017367
{
@@ -7604,12 +7570,11 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
76047570
}
76057571

76067572
{
7607-
AutoParsingSuperRestrictionStateRestorer restorer(this);
7608-
this->m_parsingSuperRestrictionState = hasExtends ? ParsingSuperRestrictionState_SuperCallAndPropertyAllowed : ParsingSuperRestrictionState_SuperPropertyAllowed;
7573+
SuperRestrictionState::State state = hasExtends ? SuperRestrictionState::CallAndPropertyAllowed : SuperRestrictionState::PropertyAllowed;
76097574

76107575
// Add the class constructor flag and base class constructor flag if pnodeExtends is nullptr
76117576
fncDeclFlags |= fFncClassConstructor | (hasExtends ? kFunctionNone : fFncBaseClassConstructor);
7612-
pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, pConstructorName, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState = */false);
7577+
pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, state, pConstructorName, /* needsPIDOnRCurlyScan */ true);
76137578
}
76147579

76157580
if (pnodeConstructor->IsGenerator())
@@ -7671,11 +7636,8 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
76717636

76727637
ParseNodeFnc * pnodeFnc = nullptr;
76737638
{
7674-
AutoParsingSuperRestrictionStateRestorer restorer(this);
7675-
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
76767639
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isGetter ? fFncNoArg : fFncOneArg),
7677-
pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true,
7678-
/* resetParsingSuperRestrictionState */false);
7640+
SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
76797641
}
76807642

76817643
pnodeFnc->SetIsStaticMember(isStatic);
@@ -7703,14 +7665,11 @@ ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint,
77037665

77047666
ParseNodeFnc * pnodeFnc = nullptr;
77057667
{
7706-
AutoParsingSuperRestrictionStateRestorer restorer(this);
7707-
this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
7708-
77097668
if (isAsyncMethod)
77107669
{
77117670
fncDeclFlags |= fFncAsync;
77127671
}
7713-
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState */false);
7672+
pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
77147673
if (isAsyncMethod)
77157674
{
77167675
pnodeFnc->cbMin = iecpMin;
@@ -8823,7 +8782,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
88238782
this->GetScanner()->SeekTo(termStart);
88248783
}
88258784
}
8826-
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan = */false, /* resetParsingSuperRestrictionState = */false, /* fUnaryOrParen = */ false, fAllowIn);
8785+
pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan = */false, /* fUnaryOrParen = */ false, fAllowIn);
88278786
if (isAsyncMethod)
88288787
{
88298788
pnode->AsParseNodeFnc()->cbMin = iecpMin;
@@ -11466,7 +11425,7 @@ ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, char
1146611425
flags |= fFncLambda;
1146711426
}
1146811427

11469-
ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags, /* resetParsingSuperRestrictionState*/ false);
11428+
ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags);
1147011429
pnodeProg->pnodeBody = nullptr;
1147111430
AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, pnodeFnc);
1147211431

@@ -12278,6 +12237,7 @@ template <bool buildAST>
1227812237
IdentPtr Parser::ParseSuper(bool fAllowCall)
1227912238
{
1228012239
ParseNodeFnc * currentNodeFunc = GetCurrentFunctionNode();
12240+
ParseNodeFnc * currentNonLambdaFunc = GetCurrentNonLambdaFunctionNode();
1228112241
IdentPtr superPid = nullptr;
1228212242

1228312243
switch (m_token.tk)
@@ -12309,12 +12269,14 @@ IdentPtr Parser::ParseSuper(bool fAllowCall)
1230912269
{
1231012270
Error(ERRInvalidSuper); // new super() is not allowed
1231112271
}
12312-
else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperCallAndPropertyAllowed)
12272+
else if ((currentNodeFunc->IsConstructor() && currentNodeFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed)
12273+
|| (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed))
1231312274
{
1231412275
// Any super access is good within a class constructor
1231512276
}
12316-
else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperPropertyAllowed)
12277+
else if ((this->m_grfscr & fscrEval) == fscrEval || currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::PropertyAllowed)
1231712278
{
12279+
// Currently for eval cases during compile time we use propertyallowed and throw during runtime for error cases
1231812280
if (m_token.tk == tkLParen)
1231912281
{
1232012282
if ((this->m_grfscr & fscrEval) == fscrNil)

lib/Parser/Parse.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -493,15 +493,6 @@ class Parser
493493
charcount_t m_funcInArray;
494494
uint m_scopeCountNoAst;
495495

496-
/*
497-
* Parsing states for super restriction
498-
*/
499-
static const uint ParsingSuperRestrictionState_SuperDisallowed = 0;
500-
static const uint ParsingSuperRestrictionState_SuperCallAndPropertyAllowed = 1;
501-
static const uint ParsingSuperRestrictionState_SuperPropertyAllowed = 2;
502-
uint m_parsingSuperRestrictionState;
503-
friend class AutoParsingSuperRestrictionStateRestorer;
504-
505496
// Used for issuing spread and rest errors when there is ambiguity with lambda parameter lists and parenthesized expressions
506497
uint m_funcParenExprDepth;
507498
bool m_deferEllipsisError;
@@ -829,9 +820,9 @@ class Parser
829820

830821
template<bool buildAST> void ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint = nullptr, uint32 *pNameLength = nullptr, uint32 *pShortNameOffset = nullptr);
831822
template<bool buildAST> ParseNodeBin * ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint);
832-
template<bool buildAST> ParseNode * ParseFncDeclCheckScope(ushort flags, bool resetParsingSuperRestrictionState = true, bool fAllowIn = true);
833-
template<bool buildAST> ParseNodeFnc * ParseFncDeclNoCheckScope(ushort flags, LPCOLESTR pNameHint = nullptr, const bool needsPIDOnRCurlyScan = false, bool resetParsingSuperRestrictionState = true, bool fUnaryOrParen = false, bool fAllowIn = true);
834-
template<bool buildAST> ParseNodeFnc * ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen, bool noStmtContext, bool fAllowIn = true);
823+
template<bool buildAST> ParseNode * ParseFncDeclCheckScope(ushort flags, bool fAllowIn = true);
824+
template<bool buildAST> ParseNodeFnc * ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState = SuperRestrictionState::Disallowed, LPCOLESTR pNameHint = nullptr, const bool needsPIDOnRCurlyScan = false, bool fUnaryOrParen = false, bool fAllowIn = true);
825+
template<bool buildAST> ParseNodeFnc * ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState = SuperRestrictionState::Disallowed, bool fAllowIn = true);
835826
template<bool buildAST> void ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncNamePid = nullptr);
836827
template<bool buildAST> void ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParentFnc, ushort flags, bool isTopLevelDeferredFunc = false);
837828
template<bool buildAST> void ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals = false, IdentPtr* pFncNamePid = nullptr, bool fAllowIn = true);

lib/Parser/ptree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,8 @@ ParseNodeFnc::ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim)
433433
#endif
434434
this->pRestorePoint = nullptr;
435435
this->deferredStub = nullptr;
436-
437436
this->capturedNames = nullptr;
437+
this->superRestrictionState = SuperRestrictionState::Disallowed;
438438
}
439439

440440
ParseNodeClass::ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim)

lib/Parser/ptree.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,14 @@ enum FncFlags : uint
455455
struct RestorePoint;
456456
struct DeferredFunctionStub;
457457

458+
namespace SuperRestrictionState {
459+
enum State {
460+
Disallowed = 0,
461+
CallAndPropertyAllowed = 1,
462+
PropertyAllowed = 2
463+
};
464+
}
465+
458466
// function declaration
459467
class ParseNodeFnc : public ParseNode
460468
{
@@ -504,6 +512,8 @@ class ParseNodeFnc : public ParseNode
504512

505513
static const int32 MaxStackClosureAST = 800000;
506514

515+
SuperRestrictionState::State superRestrictionState;
516+
507517
static bool CanBeRedeferred(FncFlags flags) { return !(flags & (kFunctionIsGenerator | kFunctionIsAsync)); }
508518

509519
private:

test/Bugs/SuperUndoDeferIssue.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
var obj = {
7+
mSloppy() {
8+
try {
9+
super[
10+
__v_12000] = 55;
11+
} catch (__v_12004) {
12+
}
13+
try {
14+
} catch (__v_12005) {
15+
}
16+
}
17+
};
18+
// There shouldn't be any SyntaxError
19+
print("PASSED");

test/Bugs/rlexe.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,5 +505,11 @@
505505
<default>
506506
<files>bug_OS17614914.js</files>
507507
</default>
508-
</test>
508+
</test>
509+
<test>
510+
<default>
511+
<files>SuperUndoDeferIssue.js</files>
512+
<compile-flags>-forceundodefer</compile-flags>
513+
</default>
514+
</test>
509515
</regress-exe>

0 commit comments

Comments
 (0)