Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
7a108e43
by Simon Jakobi at 2026-09-12T18:35:59-04:00
-
82c73b22
by Alan Zimmerman at 2026-09-12T18:36:38-04:00
-
de75a9e9
by Luite Stegeman at 2026-09-14T10:12:51+02:00
-
3b1f7b57
by Luite Stegeman at 2026-09-14T08:19:42-04:00
23 changed files:
- + changelog.d/fix-control0-mask-trampoline
- + changelog.d/fix-threadlabel-segfault-27618
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- rts/ContinuationOps.cmm
- rts/PrimOps.cmm
- rts/StgMiscClosures.cmm
- rts/include/stg/MiscClosures.h
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/printer/Test20297.stdout
- + testsuite/tests/rts/T27618.hs
- + testsuite/tests/rts/T27618.stdout
- testsuite/tests/rts/all.T
- + testsuite/tests/rts/continuations/T27651.hs
- + testsuite/tests/rts/continuations/T27651.stdout
- testsuite/tests/rts/continuations/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Utils.hs
Changes:
| 1 | +section: rts
|
|
| 2 | +synopsis: Fix a crash when capturing or resuming a delimited continuation that adjusts the async exception masking state
|
|
| 3 | +issues: #27651
|
|
| 4 | +mrs: !16484
|
|
| 5 | + |
|
| 6 | +description: {
|
|
| 7 | +Capturing a continuation with ``control0#`` from inside ``mask`` or
|
|
| 8 | +``uninterruptibleMask`` left an uninitialised word on the stack while
|
|
| 9 | +restoring the masking state. When the thread had a pending asynchronous
|
|
| 10 | +exception (e.g. from ``throwTo``), raising it walked over that word and
|
|
| 11 | +crashed with a segmentation fault. Resuming such a continuation had the
|
|
| 12 | +same defect.
|
|
| 13 | +} |
| 1 | +section: rts
|
|
| 2 | +synopsis: Fix a segfault that could occur when querying the label of an
|
|
| 3 | + unlabeled thread.
|
|
| 4 | +issues: #27618
|
|
| 5 | +mrs: !16468
|
|
| 6 | +description: {
|
|
| 7 | + The ``threadLabel#`` primop returned a null pointer in the ``ByteArray#``
|
|
| 8 | + field of its result for threads that have no label. This could lead to a
|
|
| 9 | + crash during garbage collection.
|
|
| 10 | +} |
| ... | ... | @@ -320,7 +320,7 @@ data FastStringTable = FastStringTable |
| 320 | 320 | -- ^ Number of computed z-encodings for all buckets.
|
| 321 | 321 | --
|
| 322 | 322 | -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk
|
| 323 | - -- in 'mkFastStringWith' and needs to be boxed any way.
|
|
| 323 | + -- in 'internSB' and needs to be boxed any way.
|
|
| 324 | 324 | -- If this is unpacked, then we box this single 'FastMutInt' once for each
|
| 325 | 325 | -- allocated FastString.
|
| 326 | 326 | (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments
|
| ... | ... | @@ -474,9 +474,10 @@ The procedure goes like this: |
| 474 | 474 | * Otherwise, insert and return the string we created.
|
| 475 | 475 | -}
|
| 476 | 476 | |
| 477 | -mkFastStringWith
|
|
| 478 | - :: (Int -> FastMutInt-> IO FastString) -> ShortByteString -> IO FastString
|
|
| 479 | -mkFastStringWith mk_fs sbs = do
|
|
| 477 | +-- | Return the interned 'FastString' for the given bytes, creating and
|
|
| 478 | +-- inserting one on a table miss.
|
|
| 479 | +internSB :: ShortByteString -> IO FastString
|
|
| 480 | +internSB sbs = do
|
|
| 480 | 481 | FastStringTableSegment lock _ buckets# <- readIORef segmentRef
|
| 481 | 482 | let idx# = hashToIndex# buckets# hash#
|
| 482 | 483 | bucket <- IO $ readArray# buckets# idx#
|
| ... | ... | @@ -487,7 +488,7 @@ mkFastStringWith mk_fs sbs = do |
| 487 | 488 | -- only run partially and putMVar is not called after takeMVar.
|
| 488 | 489 | noDuplicate
|
| 489 | 490 | n <- get_uid
|
| 490 | - new_fs <- mk_fs n n_zencs
|
|
| 491 | + new_fs <- mkNewFastStringShortByteString sbs n n_zencs
|
|
| 491 | 492 | withMVar lock $ \_ -> insert new_fs
|
| 492 | 493 | where
|
| 493 | 494 | !(FastStringTable uid n_zencs segments#) = stringTable
|
| ... | ... | @@ -523,11 +524,11 @@ bucket_match fs sbs = go fs |
| 523 | 524 | |
| 524 | 525 | mkFastStringBytes :: Ptr Word8 -> Int -> FastString
|
| 525 | 526 | mkFastStringBytes !ptr !len =
|
| 526 | - -- NB: Might as well use unsafeDupablePerformIO, since mkFastStringWith is
|
|
| 527 | + -- NB: Might as well use unsafeDupablePerformIO, since internSB is
|
|
| 527 | 528 | -- idempotent.
|
| 528 | 529 | unsafeDupablePerformIO $ do
|
| 529 | 530 | sbs <- newSBSFromPtr ptr len
|
| 530 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 531 | + internSB sbs
|
|
| 531 | 532 | |
| 532 | 533 | newSBSFromPtr :: Ptr a -> Int -> IO ShortByteString
|
| 533 | 534 | newSBSFromPtr (Ptr src#) (I# len#) =
|
| ... | ... | @@ -541,14 +542,13 @@ newSBSFromPtr (Ptr src#) (I# len#) = |
| 541 | 542 | mkFastStringByteString :: ByteString -> FastString
|
| 542 | 543 | mkFastStringByteString bs =
|
| 543 | 544 | let sbs = SBS.toShort bs in
|
| 544 | - inlinePerformIO $
|
|
| 545 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 545 | + inlinePerformIO $ internSB sbs
|
|
| 546 | 546 | |
| 547 | 547 | -- | Create a 'FastString' from an existing 'ShortByteString' without
|
| 548 | 548 | -- copying.
|
| 549 | 549 | mkFastStringShortByteString :: ShortByteString -> FastString
|
| 550 | 550 | mkFastStringShortByteString sbs =
|
| 551 | - inlinePerformIO $ mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 551 | + inlinePerformIO $ internSB sbs
|
|
| 552 | 552 | |
| 553 | 553 | -- | Create a 'FastString' from an 'HText'
|
| 554 | 554 | mkFastStringShortText :: ShortText -> FastString
|
| ... | ... | @@ -560,7 +560,7 @@ mkFastString :: String -> FastString |
| 560 | 560 | mkFastString str =
|
| 561 | 561 | inlinePerformIO $ do
|
| 562 | 562 | let !sbs = utf8EncodeShortByteString str
|
| 563 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 563 | + internSB sbs
|
|
| 564 | 564 | |
| 565 | 565 | -- The following rule is used to avoid polluting the non-reclaimable FastString
|
| 566 | 566 | -- table with transient strings when we only want their encoding.
|
| ... | ... | @@ -290,10 +290,12 @@ type instance XLet GhcPs = (EpToken "let", EpToken "in") |
| 290 | 290 | type instance XLet GhcRn = NoExtField
|
| 291 | 291 | type instance XLet GhcTc = NoExtField
|
| 292 | 292 | |
| 293 | -type instance XDo GhcPs = (AnnList, EpaLocation)
|
|
| 293 | +type instance XDo GhcPs = DoAnn
|
|
| 294 | 294 | type instance XDo GhcRn = NoExtField
|
| 295 | 295 | type instance XDo GhcTc = Type
|
| 296 | 296 | |
| 297 | +type DoAnn = (Either (EpToken "[", EpToken "]") AnnList, EpaLocation)
|
|
| 298 | + |
|
| 297 | 299 | type instance XExplicitList GhcPs = (EpToken "[", EpToken "]")
|
| 298 | 300 | type instance XExplicitList GhcRn = NoExtField
|
| 299 | 301 | type instance XExplicitList GhcTc = Type
|
| ... | ... | @@ -1467,7 +1469,7 @@ type instance XCmdLet GhcPs = (EpToken "let", EpToken "in") |
| 1467 | 1469 | type instance XCmdLet GhcRn = NoExtField
|
| 1468 | 1470 | type instance XCmdLet GhcTc = NoExtField
|
| 1469 | 1471 | |
| 1470 | -type instance XCmdDo GhcPs = (AnnList, EpaLocation)
|
|
| 1472 | +type instance XCmdDo GhcPs = DoAnn
|
|
| 1471 | 1473 | type instance XCmdDo GhcRn = NoExtField
|
| 1472 | 1474 | type instance XCmdDo GhcTc = Type
|
| 1473 | 1475 |
| ... | ... | @@ -335,11 +335,10 @@ mkHsIntegral :: IntegralLit GhcPs -> HsOverLit GhcPs |
| 335 | 335 | mkHsFractional :: FractionalLit GhcPs -> HsOverLit GhcPs
|
| 336 | 336 | mkHsIsString :: SourceText -> HText -> HsOverLit GhcPs
|
| 337 | 337 | mkHsDo :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> HsExpr GhcPs
|
| 338 | -mkHsDoAnns :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> (AnnList, EpaLocation) -> HsExpr GhcPs
|
|
| 338 | +mkHsDoAnns :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> DoAnn -> HsExpr GhcPs
|
|
| 339 | 339 | mkHsComp :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs
|
| 340 | 340 | -> HsExpr GhcPs
|
| 341 | -mkHsCompAnns :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs
|
|
| 342 | - -> (AnnList, EpaLocation)
|
|
| 341 | +mkHsCompAnns :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs -> DoAnn
|
|
| 343 | 342 | -> HsExpr GhcPs
|
| 344 | 343 | |
| 345 | 344 | mkNPat :: LocatedAn NoEpAnns (HsOverLit GhcPs) -> Maybe (SyntaxExpr GhcPs) -> EpToken "-"
|
| ... | ... | @@ -3152,19 +3152,15 @@ aexp :: { ECP } |
| 3152 | 3152 | return $ ECP $
|
| 3153 | 3153 | $2 >>= \ $2 ->
|
| 3154 | 3154 | mkHsDoPV (comb2 $1 $2)
|
| 3155 | - (stmtlistAnns $2)
|
|
| 3155 | + (Right $ stmtlistAnns $2, glR $1)
|
|
| 3156 | 3156 | (fmap mkModuleNameFS (getDO $1))
|
| 3157 | - (stmtlistStmts $2)
|
|
| 3158 | - (glR $1)
|
|
| 3159 | - (glR $2) }
|
|
| 3157 | + (stmtlistStmts $2) }
|
|
| 3160 | 3158 | | MDO stmtlist {% hintQualifiedDo $1 >> runPV $2 >>= \ $2 ->
|
| 3161 | 3159 | fmap ecpFromExp $
|
| 3162 | 3160 | amsA' (L (comb2 $1 $2)
|
| 3163 | - (mkMDo (stmtlistAnns $2)
|
|
| 3164 | - (MDoExpr $ fmap mkModuleNameFS (getMDO $1))
|
|
| 3165 | - (stmtlistStmts $2)
|
|
| 3166 | - (glR $1)
|
|
| 3167 | - (glR $2))) }
|
|
| 3161 | + (mkHsDoAnns (MDoExpr $ fmap mkModuleNameFS (getMDO $1))
|
|
| 3162 | + (stmtlistStmts $2)
|
|
| 3163 | + (Right $ stmtlistAnns $2, glR $1))) }
|
|
| 3168 | 3164 | | 'proc' aexp '->' exp
|
| 3169 | 3165 | {% (checkPattern <=< runPV) (unECP $2) >>= \ p ->
|
| 3170 | 3166 | runPV (unECP $4) >>= \ $4@cmd ->
|
| ... | ... | @@ -3440,7 +3436,7 @@ list :: { forall b. DisambECP b => SrcSpan -> (EpaLocation, EpaLocation) -> PV ( |
| 3440 | 3436 | { \loc (ao,ac) ->
|
| 3441 | 3437 | checkMonadComp >>= \ ctxt ->
|
| 3442 | 3438 | unECP $1 >>= \ $1 -> do { t <- addTrailingVbarA $1 (epTok $2)
|
| 3443 | - ; amsA' (L loc $ mkHsCompAnns ctxt (unLoc $3) t (AnnList Nothing (ListSquare (EpTok ao) (EpTok ac)) [], noAnn))
|
|
| 3439 | + ; amsA' (L loc $ mkHsCompAnns ctxt (unLoc $3) t (Left $ (EpTok ao, EpTok ac), noAnn))
|
|
| 3444 | 3440 | >>= ecpFromExp' } }
|
| 3445 | 3441 | |
| 3446 | 3442 | lexps :: { forall b. DisambECP b => PV [LocatedA b] }
|
| ... | ... | @@ -3658,11 +3654,13 @@ apat : aexp {% (checkPattern <=< runPV) (unECP $1) } |
| 3658 | 3654 | -----------------------------------------------------------------------------
|
| 3659 | 3655 | -- Statement sequences
|
| 3660 | 3656 | |
| 3661 | -stmtlist :: { forall b. DisambECP b => PV (LocatedA ((EpToken "{", [EpToken ";"], EpToken "}"), Located [LocatedA (Stmt GhcPs (LocatedA b))])) }
|
|
| 3657 | +stmtlist :: { forall b. DisambECP b => PV (LocatedA (AnnList, Located [LocatedA (Stmt GhcPs (LocatedA b))])) }
|
|
| 3662 | 3658 | : '{' stmts '}' { $2 >>= \ $2 ->
|
| 3663 | - amsA' (sLL $1 $> ((epTok $1, fromOL $ fst $ unLoc $2, epTok $3), sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3659 | + amsA' (sLL $1 $> (AnnList (Just (spanAsAnchor $ stmtsLoc $2)) (ListBraces (epTok $1) (epTok $3)) (fromOL $ fst $ unLoc $2)
|
|
| 3660 | + , sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3664 | 3661 | | vocurly stmts close { $2 >>= \ $2 ->
|
| 3665 | - amsA' (L (stmtsLoc $2) ((noEpTok, fromOL $ fst $ unLoc $2, noEpTok), sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3662 | + amsA' (L (stmtsLoc $2) (AnnList (Just (spanAsAnchor $ stmtsLoc $2)) ListNone (fromOL $ fst $ unLoc $2)
|
|
| 3663 | + , sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3666 | 3664 | |
| 3667 | 3665 | -- do { ;; s ; s ; ; s ;; }
|
| 3668 | 3666 | -- The last Stmt should be an expression, but that's hard to enforce
|
| ... | ... | @@ -3704,7 +3702,7 @@ e_stmt :: { LStmt GhcPs (LHsExpr GhcPs) } |
| 3704 | 3702 | stmt :: { forall b. DisambECP b => PV (LStmt GhcPs (LocatedA b)) }
|
| 3705 | 3703 | : qual { $1 }
|
| 3706 | 3704 | | 'rec' stmtlist { $2 >>= \ $2 ->
|
| 3707 | - amsA' (sLL $1 $> $ mkRecStmt (hsDoAnn (epTok $1) (stmtlistAnns $2) $2)
|
|
| 3705 | + amsA' (sLL $1 $> $ mkRecStmt (stmtlistAnns $2, epTok $1)
|
|
| 3708 | 3706 | (stmtlistStmts $2)) }
|
| 3709 | 3707 | |
| 3710 | 3708 | qual :: { forall b. DisambECP b => PV (LStmt GhcPs (LocatedA b)) }
|
| ... | ... | @@ -4724,10 +4722,6 @@ commentsPA la@(L l a) = do |
| 4724 | 4722 | !cs <- getPriorCommentsFor (getLocA la)
|
| 4725 | 4723 | return (L (addCommentsToEpAnn l cs) a)
|
| 4726 | 4724 | |
| 4727 | -hsDoAnn :: EpToken "rec" -> (EpToken "{", [EpToken ";"], EpToken "}") -> LocatedAn t b -> (AnnList, EpToken "rec")
|
|
| 4728 | -hsDoAnn rec (ob, semis, cb) (L ll _)
|
|
| 4729 | - = (AnnList (Just $ spanAsAnchor (locA ll)) (ListBraces ob cb) semis, rec)
|
|
| 4730 | - |
|
| 4731 | 4725 | listAsAnchorM :: [LocatedAn t a] -> Maybe EpaLocation
|
| 4732 | 4726 | listAsAnchorM [] = Nothing
|
| 4733 | 4727 | listAsAnchorM (L l _:_) =
|
| ... | ... | @@ -4757,8 +4751,7 @@ stmtlistStmts :: LocatedA (a, Located [LocatedA (Stmt GhcPs (LocatedA b))]) |
| 4757 | 4751 | stmtlistStmts (L la (_,L l stmts))
|
| 4758 | 4752 | = L ((noAnnSrcSpan l) {comments = comments la}) stmts
|
| 4759 | 4753 | |
| 4760 | -stmtlistAnns :: LocatedA ((EpToken "{", [EpToken ";"], EpToken "}"), a)
|
|
| 4761 | - -> (EpToken "{", [EpToken ";"], EpToken "}")
|
|
| 4754 | +stmtlistAnns :: LocatedA (AnnList, a) -> AnnList
|
|
| 4762 | 4755 | stmtlistAnns (L _ (an,_)) = an
|
| 4763 | 4756 | |
| 4764 | 4757 | -- -------------------------------------
|
| ... | ... | @@ -519,8 +519,7 @@ data AnnList |
| 519 | 519 | } deriving (Data,Eq)
|
| 520 | 520 | |
| 521 | 521 | data AnnListBrackets
|
| 522 | - = ListBraces (EpToken "{") (EpToken "}")
|
|
| 523 | - | ListSquare (EpToken "[") (EpToken "]")
|
|
| 522 | + = ListBraces (EpToken "{") (EpToken "}")
|
|
| 524 | 523 | | ListNone
|
| 525 | 524 | deriving (Data,Eq)
|
| 526 | 525 | |
| ... | ... | @@ -1093,7 +1092,6 @@ instance Outputable AnnList where |
| 1093 | 1092 | |
| 1094 | 1093 | instance Outputable AnnListBrackets where
|
| 1095 | 1094 | ppr (ListBraces o c) = text "ListBraces" <+> ppr o <+> ppr c
|
| 1096 | - ppr (ListSquare o c) = text "ListSquare" <+> ppr o <+> ppr c
|
|
| 1097 | 1095 | ppr ListNone = text "ListNone"
|
| 1098 | 1096 | |
| 1099 | 1097 | instance Outputable AnnCType where
|
| ... | ... | @@ -12,7 +12,7 @@ module GHC.Parser.PostProcess ( |
| 12 | 12 | mkRdrGetField, mkRdrProjection, Fbind, -- RecordDot
|
| 13 | 13 | mkHsOpApp,
|
| 14 | 14 | mkHsIntegral, mkHsFractional, mkHsIsString,
|
| 15 | - mkHsDo, mkMDo, mkSpliceDecl,
|
|
| 15 | + mkHsDo, mkSpliceDecl,
|
|
| 16 | 16 | mkRoleAnnotDecl,
|
| 17 | 17 | mkClassDecl,
|
| 18 | 18 | mkTyData, mkDataFamInst,
|
| ... | ... | @@ -435,10 +435,6 @@ mkRoleAnnotDecl loc tycon roles anns |
| 435 | 435 | addFatalError $ mkPlainErrorMsgEnvelope loc_role $
|
| 436 | 436 | (PsErrIllegalRoleName role nearby)
|
| 437 | 437 | |
| 438 | -mkMDo :: (EpToken "{", [EpToken ";"], EpToken "}") -> HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> EpaLocation -> EpaLocation -> HsExpr GhcPs
|
|
| 439 | -mkMDo (ob, semis, cb) ctxt stmts tok loc
|
|
| 440 | - = mkHsDoAnns ctxt stmts (AnnList (Just loc) (ListBraces ob cb) semis, tok)
|
|
| 441 | - |
|
| 442 | 438 | -- | Converts a list of 'LHsTyVarBndr's annotated with their 'Specificity' to
|
| 443 | 439 | -- binders without annotations. Only accepts specified variables, and errors if
|
| 444 | 440 | -- any of the provided binders has an 'InferredSpec' annotation.
|
| ... | ... | @@ -1804,12 +1800,7 @@ class (b ~ (Body b) GhcPs, AnnoBody b) => DisambECP b where |
| 1804 | 1800 | -> PV (LocatedA b)
|
| 1805 | 1801 | -- | Disambiguate "do { ... }" (do notation)
|
| 1806 | 1802 | mkHsDoPV ::
|
| 1807 | - SrcSpan ->
|
|
| 1808 | - (EpToken "{", [EpToken ";"], EpToken "}") ->
|
|
| 1809 | - Maybe ModuleName ->
|
|
| 1810 | - LocatedA [LStmt GhcPs (LocatedA b)] ->
|
|
| 1811 | - EpaLocation -> -- Token
|
|
| 1812 | - EpaLocation -> -- Anchor
|
|
| 1803 | + SrcSpan -> DoAnn -> Maybe ModuleName -> LocatedA [LStmt GhcPs (LocatedA b)] ->
|
|
| 1813 | 1804 | PV (LocatedA b)
|
| 1814 | 1805 | -- | Disambiguate "( ... )" (parentheses)
|
| 1815 | 1806 | mkHsParPV :: SrcSpan -> EpToken "(" -> LocatedA b -> EpToken ")" -> PV (LocatedA b)
|
| ... | ... | @@ -1959,10 +1950,10 @@ instance DisambECP (HsCmd GhcPs) where |
| 1959 | 1950 | checkDoAndIfThenElse PsErrSemiColonsInCondCmd c semi1 a semi2 b
|
| 1960 | 1951 | !cs <- getCommentsFor l
|
| 1961 | 1952 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (mkHsCmdIf c a b anns)
|
| 1962 | - mkHsDoPV l (ob,semis,cb) Nothing stmts tok_loc anc = do
|
|
| 1953 | + mkHsDoPV l ann Nothing stmts = do
|
|
| 1963 | 1954 | !cs <- getCommentsFor l
|
| 1964 | - return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdDo (AnnList (Just anc) (ListBraces ob cb) semis, tok_loc) stmts)
|
|
| 1965 | - mkHsDoPV l _ (Just m) _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrQualifiedDoInCmd m
|
|
| 1955 | + return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdDo ann stmts)
|
|
| 1956 | + mkHsDoPV l _ (Just m) _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrQualifiedDoInCmd m
|
|
| 1966 | 1957 | mkHsParPV l lpar c rpar = do
|
| 1967 | 1958 | !cs <- getCommentsFor l
|
| 1968 | 1959 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdPar (lpar, rpar) c)
|
| ... | ... | @@ -2058,9 +2049,9 @@ instance DisambECP (HsExpr GhcPs) where |
| 2058 | 2049 | checkDoAndIfThenElse PsErrSemiColonsInCondExpr c semi1 a semi2 b
|
| 2059 | 2050 | !cs <- getCommentsFor l
|
| 2060 | 2051 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (mkHsIf c a b anns)
|
| 2061 | - mkHsDoPV l (ob,semis,cb) mod stmts loc_tok anc = do
|
|
| 2052 | + mkHsDoPV l ann mod stmts = do
|
|
| 2062 | 2053 | !cs <- getCommentsFor l
|
| 2063 | - return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsDo (AnnList (Just anc) (ListBraces ob cb) semis, loc_tok) (DoExpr mod) stmts)
|
|
| 2054 | + return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsDo ann (DoExpr mod) stmts)
|
|
| 2064 | 2055 | mkHsParPV l lpar e rpar = do
|
| 2065 | 2056 | !cs <- getCommentsFor l
|
| 2066 | 2057 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsPar (lpar, rpar) e)
|
| ... | ... | @@ -2156,7 +2147,7 @@ instance DisambECP (PatBuilder GhcPs) where |
| 2156 | 2147 | !cs <- getCommentsFor (locA l)
|
| 2157 | 2148 | return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t))
|
| 2158 | 2149 | mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat
|
| 2159 | - mkHsDoPV l _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat
|
|
| 2150 | + mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat
|
|
| 2160 | 2151 | mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar)
|
| 2161 | 2152 | mkHsVarPV v@(getLoc -> l) = return $ L (l2l l) (PatBuilderVar v)
|
| 2162 | 2153 | mkHsLitPV lit@(L l a) = do
|
| ... | ... | @@ -148,6 +148,7 @@ stg_control0zh_ll // explicit stack |
| 148 | 148 | // and jump to the frame’s entry code.
|
| 149 | 149 | Sp_adj(-3); // Note -3, not -2, because `mask_frame` will
|
| 150 | 150 | // try to pop itself off the stack when it returns!
|
| 151 | + Sp(0) = mask_frame; // Can't be omitted, see #27651
|
|
| 151 | 152 | Sp(1) = stg_ap_pv_info;
|
| 152 | 153 | Sp(2) = cont;
|
| 153 | 154 | R1 = f;
|
| ... | ... | @@ -230,6 +231,7 @@ stg_CONTINUATION_apply // explicit stack |
| 230 | 231 | // Now we just set up the stack so that `apply_mask_frame` will apply `io`
|
| 231 | 232 | // when it returns and jump to it.
|
| 232 | 233 | Sp_adj(-2);
|
| 234 | + Sp(0) = apply_mask_frame; // Can't be omitted, see #27651
|
|
| 233 | 235 | Sp(1) = stg_ap_v_info;
|
| 234 | 236 | R1 = io;
|
| 235 | 237 | jump %ENTRY_CODE(apply_mask_frame) [R1];
|
| ... | ... | @@ -1160,7 +1160,7 @@ stg_threadLabelzh ( gcptr tso ) |
| 1160 | 1160 | W_ r;
|
| 1161 | 1161 | r = StgTSO_label(tso);
|
| 1162 | 1162 | if (r == 0) {
|
| 1163 | - return (0, 0);
|
|
| 1163 | + return (0, stg_DEAD_SLOT_closure);
|
|
| 1164 | 1164 | } else {
|
| 1165 | 1165 | return (1, r);
|
| 1166 | 1166 | }
|
| ... | ... | @@ -726,6 +726,18 @@ INFO_TABLE_CONSTR(stg_NO_FINALIZER,0,0,0,CONSTR_NOCAF,"NO_FINALIZER","NO_FINALIZ |
| 726 | 726 | |
| 727 | 727 | CLOSURE(stg_NO_FINALIZER_closure,stg_NO_FINALIZER);
|
| 728 | 728 | |
| 729 | +/* ----------------------------------------------------------------------------
|
|
| 730 | + DEAD_SLOT
|
|
| 731 | + |
|
| 732 | + A static nullary constructor for dead pointer-typed result slots
|
|
| 733 | + that must still hold a valid closure for the GC (see #27618).
|
|
| 734 | + ------------------------------------------------------------------------- */
|
|
| 735 | + |
|
| 736 | +INFO_TABLE_CONSTR(stg_DEAD_SLOT,0,0,0,CONSTR_NOCAF,"DEAD_SLOT","DEAD_SLOT")
|
|
| 737 | +{ ccall pbarf("DEAD_SLOT object (%p) entered!", R1 "ptr") never returns; }
|
|
| 738 | + |
|
| 739 | +CLOSURE(stg_DEAD_SLOT_closure,stg_DEAD_SLOT);
|
|
| 740 | + |
|
| 729 | 741 | /* ----------------------------------------------------------------------------
|
| 730 | 742 | Stable Names are unlifted too.
|
| 731 | 743 | ------------------------------------------------------------------------- */
|
| ... | ... | @@ -200,6 +200,7 @@ RTS_ENTRY(stg_SRT_16); |
| 200 | 200 | |
| 201 | 201 | RTS_CLOSURE(stg_END_TSO_QUEUE_closure);
|
| 202 | 202 | RTS_CLOSURE(stg_NO_FINALIZER_closure);
|
| 203 | +RTS_CLOSURE(stg_DEAD_SLOT_closure);
|
|
| 203 | 204 | RTS_CLOSURE(stg_dummy_ret_closure);
|
| 204 | 205 | RTS_CLOSURE(stg_forceIO_closure);
|
| 205 | 206 | RTS_CLOSURE(stg_CLOSURE_TABLE_NULL_closure);
|
| ... | ... | @@ -211,6 +212,7 @@ RTS_CLOSURE(stg_END_STM_CHUNK_LIST_closure); |
| 211 | 212 | RTS_CLOSURE(stg_NO_TREC_closure);
|
| 212 | 213 | |
| 213 | 214 | RTS_ENTRY(stg_NO_FINALIZER);
|
| 215 | +RTS_ENTRY(stg_DEAD_SLOT);
|
|
| 214 | 216 | |
| 215 | 217 | #if IN_STG_CODE
|
| 216 | 218 | extern StgWordArray stg_CHARLIKE_closure;
|
| ... | ... | @@ -289,13 +289,12 @@ |
| 289 | 289 | { DumpParsedAstComments.hs:14:7-8 }))]))
|
| 290 | 290 | (HsDo
|
| 291 | 291 | ((,)
|
| 292 | - (AnnList
|
|
| 293 | - (Just
|
|
| 294 | - (EpaSpan { DumpParsedAstComments.hs:16:3 }))
|
|
| 295 | - (ListBraces
|
|
| 296 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 297 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 298 | - [])
|
|
| 292 | + (Right
|
|
| 293 | + (AnnList
|
|
| 294 | + (Just
|
|
| 295 | + (EpaSpan { DumpParsedAstComments.hs:16:3 }))
|
|
| 296 | + (ListNone)
|
|
| 297 | + []))
|
|
| 299 | 298 | (EpaSpan { DumpParsedAstComments.hs:14:7-8 }))
|
| 300 | 299 | (DoExpr
|
| 301 | 300 | (Nothing))
|
| ... | ... | @@ -331,13 +331,12 @@ |
| 331 | 331 | []))
|
| 332 | 332 | (HsDo
|
| 333 | 333 | ((,)
|
| 334 | - (AnnList
|
|
| 335 | - (Just
|
|
| 336 | - (EpaSpan { DumpSemis.hs:(11,3)-(12,3) }))
|
|
| 337 | - (ListBraces
|
|
| 338 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 339 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 340 | - [])
|
|
| 334 | + (Right
|
|
| 335 | + (AnnList
|
|
| 336 | + (Just
|
|
| 337 | + (EpaSpan { DumpSemis.hs:(11,3)-(12,3) }))
|
|
| 338 | + (ListNone)
|
|
| 339 | + []))
|
|
| 341 | 340 | (EpaSpan { DumpSemis.hs:10:7-8 }))
|
| 342 | 341 | (DoExpr
|
| 343 | 342 | (Nothing))
|
| ... | ... | @@ -363,20 +362,21 @@ |
| 363 | 362 | []))
|
| 364 | 363 | (HsDo
|
| 365 | 364 | ((,)
|
| 366 | - (AnnList
|
|
| 367 | - (Just
|
|
| 368 | - (EpaSpan { DumpSemis.hs:11:6-15 }))
|
|
| 369 | - (ListBraces
|
|
| 370 | - (EpTok (EpaSpan { DumpSemis.hs:11:6 }))
|
|
| 371 | - (EpTok (EpaSpan { DumpSemis.hs:11:15 })))
|
|
| 372 | - [(EpTok
|
|
| 373 | - (EpaSpan { DumpSemis.hs:11:8 }))
|
|
| 374 | - ,(EpTok
|
|
| 375 | - (EpaSpan { DumpSemis.hs:11:9 }))
|
|
| 376 | - ,(EpTok
|
|
| 377 | - (EpaSpan { DumpSemis.hs:11:10 }))
|
|
| 378 | - ,(EpTok
|
|
| 379 | - (EpaSpan { DumpSemis.hs:11:11 }))])
|
|
| 365 | + (Right
|
|
| 366 | + (AnnList
|
|
| 367 | + (Just
|
|
| 368 | + (EpaSpan { DumpSemis.hs:11:8-13 }))
|
|
| 369 | + (ListBraces
|
|
| 370 | + (EpTok (EpaSpan { DumpSemis.hs:11:6 }))
|
|
| 371 | + (EpTok (EpaSpan { DumpSemis.hs:11:15 })))
|
|
| 372 | + [(EpTok
|
|
| 373 | + (EpaSpan { DumpSemis.hs:11:8 }))
|
|
| 374 | + ,(EpTok
|
|
| 375 | + (EpaSpan { DumpSemis.hs:11:9 }))
|
|
| 376 | + ,(EpTok
|
|
| 377 | + (EpaSpan { DumpSemis.hs:11:10 }))
|
|
| 378 | + ,(EpTok
|
|
| 379 | + (EpaSpan { DumpSemis.hs:11:11 }))]))
|
|
| 380 | 380 | (EpaSpan { DumpSemis.hs:11:3-4 }))
|
| 381 | 381 | (DoExpr
|
| 382 | 382 | (Nothing))
|
| ... | ... | @@ -625,16 +625,17 @@ |
| 625 | 625 | []))
|
| 626 | 626 | (HsDo
|
| 627 | 627 | ((,)
|
| 628 | - (AnnList
|
|
| 629 | - (Just
|
|
| 630 | - (EpaSpan { DumpSemis.hs:(16,3)-(19,3) }))
|
|
| 631 | - (ListBraces
|
|
| 632 | - (EpTok (EpaSpan { DumpSemis.hs:16:3 }))
|
|
| 633 | - (EpTok (EpaSpan { DumpSemis.hs:19:3 })))
|
|
| 634 | - [(EpTok
|
|
| 635 | - (EpaSpan { DumpSemis.hs:16:5 }))
|
|
| 636 | - ,(EpTok
|
|
| 637 | - (EpaSpan { DumpSemis.hs:16:8 }))])
|
|
| 628 | + (Right
|
|
| 629 | + (AnnList
|
|
| 630 | + (Just
|
|
| 631 | + (EpaSpan { DumpSemis.hs:(16,5)-(18,5) }))
|
|
| 632 | + (ListBraces
|
|
| 633 | + (EpTok (EpaSpan { DumpSemis.hs:16:3 }))
|
|
| 634 | + (EpTok (EpaSpan { DumpSemis.hs:19:3 })))
|
|
| 635 | + [(EpTok
|
|
| 636 | + (EpaSpan { DumpSemis.hs:16:5 }))
|
|
| 637 | + ,(EpTok
|
|
| 638 | + (EpaSpan { DumpSemis.hs:16:8 }))]))
|
|
| 638 | 639 | (EpaSpan { DumpSemis.hs:15:7-8 }))
|
| 639 | 640 | (DoExpr
|
| 640 | 641 | (Nothing))
|
| ... | ... | @@ -877,16 +878,17 @@ |
| 877 | 878 | []))
|
| 878 | 879 | (HsDo
|
| 879 | 880 | ((,)
|
| 880 | - (AnnList
|
|
| 881 | - (Just
|
|
| 882 | - (EpaSpan { DumpSemis.hs:22:10-30 }))
|
|
| 883 | - (ListBraces
|
|
| 884 | - (EpTok (EpaSpan { DumpSemis.hs:22:10 }))
|
|
| 885 | - (EpTok (EpaSpan { DumpSemis.hs:22:30 })))
|
|
| 886 | - [(EpTok
|
|
| 887 | - (EpaSpan { DumpSemis.hs:22:12 }))
|
|
| 888 | - ,(EpTok
|
|
| 889 | - (EpaSpan { DumpSemis.hs:22:13 }))])
|
|
| 881 | + (Right
|
|
| 882 | + (AnnList
|
|
| 883 | + (Just
|
|
| 884 | + (EpaSpan { DumpSemis.hs:22:12-28 }))
|
|
| 885 | + (ListBraces
|
|
| 886 | + (EpTok (EpaSpan { DumpSemis.hs:22:10 }))
|
|
| 887 | + (EpTok (EpaSpan { DumpSemis.hs:22:30 })))
|
|
| 888 | + [(EpTok
|
|
| 889 | + (EpaSpan { DumpSemis.hs:22:12 }))
|
|
| 890 | + ,(EpTok
|
|
| 891 | + (EpaSpan { DumpSemis.hs:22:13 }))]))
|
|
| 890 | 892 | (EpaSpan { DumpSemis.hs:22:7-8 }))
|
| 891 | 893 | (DoExpr
|
| 892 | 894 | (Nothing))
|
| ... | ... | @@ -394,13 +394,12 @@ |
| 394 | 394 | []))
|
| 395 | 395 | (HsDo
|
| 396 | 396 | ((,)
|
| 397 | - (AnnList
|
|
| 398 | - (Just
|
|
| 399 | - (EpaSpan { Test20297.hs:11:22-26 }))
|
|
| 400 | - (ListBraces
|
|
| 401 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 402 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 403 | - [])
|
|
| 397 | + (Right
|
|
| 398 | + (AnnList
|
|
| 399 | + (Just
|
|
| 400 | + (EpaSpan { Test20297.hs:11:22-26 }))
|
|
| 401 | + (ListNone)
|
|
| 402 | + []))
|
|
| 404 | 403 | (EpaSpan { Test20297.hs:11:19-20 }))
|
| 405 | 404 | (DoExpr
|
| 406 | 405 | (Nothing))
|
| ... | ... | @@ -820,13 +819,12 @@ |
| 820 | 819 | []))
|
| 821 | 820 | (HsDo
|
| 822 | 821 | ((,)
|
| 823 | - (AnnList
|
|
| 824 | - (Just
|
|
| 825 | - (EpaSpan { Test20297.ppr.hs:9:20-24 }))
|
|
| 826 | - (ListBraces
|
|
| 827 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 828 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 829 | - [])
|
|
| 822 | + (Right
|
|
| 823 | + (AnnList
|
|
| 824 | + (Just
|
|
| 825 | + (EpaSpan { Test20297.ppr.hs:9:20-24 }))
|
|
| 826 | + (ListNone)
|
|
| 827 | + []))
|
|
| 830 | 828 | (EpaSpan { Test20297.ppr.hs:9:17-18 }))
|
| 831 | 829 | (DoExpr
|
| 832 | 830 | (Nothing))
|
| 1 | +{-# LANGUAGE NumericUnderscores #-}
|
|
| 2 | + |
|
| 3 | +-- Test for a major GC segfault triggered by threadLabel# returning NULL in
|
|
| 4 | +-- a GC pointer field on unlabeled threads. Run with -N4 -A32k.
|
|
| 5 | + |
|
| 6 | +module Main (main) where
|
|
| 7 | + |
|
| 8 | +import Control.Concurrent
|
|
| 9 | +import Control.Monad
|
|
| 10 | +import Data.IORef
|
|
| 11 | +import GHC.Conc.Sync (threadLabel)
|
|
| 12 | +import System.Mem (performMajorGC)
|
|
| 13 | + |
|
| 14 | +{-# NOINLINE queryLabel #-}
|
|
| 15 | +queryLabel :: ThreadId -> IO (Maybe String)
|
|
| 16 | +queryLabel = threadLabel
|
|
| 17 | + |
|
| 18 | +main :: IO ()
|
|
| 19 | +main = do
|
|
| 20 | + stop <- newIORef False
|
|
| 21 | + _ <- forkIO $ forever performMajorGC
|
|
| 22 | + targets <- replicateM 8 $ forkIO $ forever (threadDelay 1_000_000)
|
|
| 23 | + dones <- forM [1 :: Int .. 8] $ \_ -> do
|
|
| 24 | + done <- newEmptyMVar
|
|
| 25 | + _ <- forkIO $ do
|
|
| 26 | + let loop = do
|
|
| 27 | + s <- readIORef stop
|
|
| 28 | + unless s $ do
|
|
| 29 | + forM_ targets $ \t -> do
|
|
| 30 | + r <- queryLabel t
|
|
| 31 | + r `seq` pure ()
|
|
| 32 | + loop
|
|
| 33 | + loop
|
|
| 34 | + putMVar done ()
|
|
| 35 | + pure done
|
|
| 36 | + threadDelay 2_000_000
|
|
| 37 | + writeIORef stop True
|
|
| 38 | + mapM_ takeMVar dones
|
|
| 39 | + putStrLn "done" |
| 1 | +done |
| ... | ... | @@ -729,3 +729,7 @@ test('T27477', |
| 729 | 729 | ],
|
| 730 | 730 | compile_and_run, ['-O2'])
|
| 731 | 731 | |
| 732 | +test('T27618',
|
|
| 733 | + [req_target_smp, omit_ghci],
|
|
| 734 | + compile_and_run, ['-O2 -threaded -with-rtsopts "-N4 -A32k"'])
|
|
| 735 | + |
| 1 | +-- When capturing or resuming a continuation adjusts the async exception
|
|
| 2 | +-- masking state, the RTS trampolines through a mask/unmask frame, and the
|
|
| 3 | +-- stack must be well-formed at that point: with a blocked exception
|
|
| 4 | +-- pending, the eager raise in stg_unmaskAsyncExceptionszh_ret walks the
|
|
| 5 | +-- whole stack.
|
|
| 6 | +--
|
|
| 7 | +-- Phase 1 exercises the capture side (stg_control0zh_ll): control0# runs
|
|
| 8 | +-- inside uninterruptibleMask_ while another thread has queued an
|
|
| 9 | +-- exception via throwTo, so the capture unmasks with the exception
|
|
| 10 | +-- pending. The frame evaluated between the unmask frame and the prompt
|
|
| 11 | +-- keeps raw Int# payload live so that a stale word on the stack cannot
|
|
| 12 | +-- masquerade as a valid frame by accident.
|
|
| 13 | +--
|
|
| 14 | +-- Phase 2 exercises the resume side (stg_CONTINUATION_apply): the
|
|
| 15 | +-- continuation is captured while unmasked (inside mask/restore), so
|
|
| 16 | +-- resuming it unmasks, and it is applied from a thread that is masked
|
|
| 17 | +-- with an exception pending.
|
|
| 18 | +import Control.Concurrent
|
|
| 19 | +import Control.Exception
|
|
| 20 | +import Control.Monad
|
|
| 21 | + |
|
| 22 | +import ContIO
|
|
| 23 | + |
|
| 24 | +data Boom = Boom deriving Show
|
|
| 25 | +instance Exception Boom
|
|
| 26 | + |
|
| 27 | +{-# NOINLINE useInts #-}
|
|
| 28 | +useInts :: Int -> Int -> Int -> Int -> Int -> Int
|
|
| 29 | +useInts a b c d e = a + b * c + d * e
|
|
| 30 | + |
|
| 31 | +rounds :: Int
|
|
| 32 | +rounds = 150
|
|
| 33 | + |
|
| 34 | +phase1 :: Int -> IO ()
|
|
| 35 | +phase1 i = do
|
|
| 36 | + mv <- newEmptyMVar
|
|
| 37 | + done <- newEmptyMVar
|
|
| 38 | + let !p = i * 7919 + 3 -- raw ints to live in the continuation frame
|
|
| 39 | + !q = i * 104729 + 7
|
|
| 40 | + !u = i * 1299709 + 11
|
|
| 41 | + !v = i * 15485863 + 13
|
|
| 42 | + a <- forkIO $
|
|
| 43 | + handle (\Boom -> void (tryPutMVar done (Left Boom))) $ do
|
|
| 44 | + tag <- newPromptTag
|
|
| 45 | + r <- prompt tag $ do
|
|
| 46 | + x <- uninterruptibleMask_ $ do
|
|
| 47 | + putMVar mv ()
|
|
| 48 | + threadDelay 2000 -- let the thrower queue its exception
|
|
| 49 | + control0 tag (\_k -> pure (42 :: Int))
|
|
| 50 | + -- continuation frame between the unmask frame and the
|
|
| 51 | + -- prompt frame, carrying raw Int# payload:
|
|
| 52 | + pure (useInts x p q u v)
|
|
| 53 | + void (tryPutMVar done (Right r))
|
|
| 54 | + takeMVar mv
|
|
| 55 | + _ <- forkIO $ throwTo a Boom
|
|
| 56 | + void (takeMVar done)
|
|
| 57 | + |
|
| 58 | +phase2 :: Int -> IO ()
|
|
| 59 | +phase2 i = do
|
|
| 60 | + mv <- newEmptyMVar
|
|
| 61 | + done <- newEmptyMVar
|
|
| 62 | + kvar <- newEmptyMVar
|
|
| 63 | + let !p = i * 7919 + 3
|
|
| 64 | + !q = i * 104729 + 7
|
|
| 65 | + !u = i * 1299709 + 11
|
|
| 66 | + !v = i * 15485863 + 13
|
|
| 67 | + -- Capture a continuation whose resumption unmasks: the capture happens
|
|
| 68 | + -- inside restore, so its apply_mask_frame is the unmask frame.
|
|
| 69 | + _ <- forkIO $ do
|
|
| 70 | + tag <- newPromptTag
|
|
| 71 | + _ <- prompt tag $ mask $ \restore -> do
|
|
| 72 | + x <- restore (control0 tag (\k -> putMVar kvar k >> pure 0))
|
|
| 73 | + pure (useInts x p q u v)
|
|
| 74 | + pure ()
|
|
| 75 | + k <- takeMVar kvar
|
|
| 76 | + a <- forkIO $
|
|
| 77 | + handle (\Boom -> void (tryPutMVar done (Left Boom))) $ do
|
|
| 78 | + r <- uninterruptibleMask_ $ do
|
|
| 79 | + putMVar mv ()
|
|
| 80 | + threadDelay 2000 -- let the thrower queue its exception
|
|
| 81 | + k (pure 42) -- resuming unmasks with the exception pending
|
|
| 82 | + void (tryPutMVar done (Right r))
|
|
| 83 | + takeMVar mv
|
|
| 84 | + _ <- forkIO $ throwTo a Boom
|
|
| 85 | + void (takeMVar done)
|
|
| 86 | + |
|
| 87 | +main :: IO ()
|
|
| 88 | +main = do
|
|
| 89 | + forM_ [1 .. rounds] phase1
|
|
| 90 | + forM_ [1 .. rounds] phase2
|
|
| 91 | + putStrLn "ok" |
| 1 | +ok |
| ... | ... | @@ -9,3 +9,4 @@ test('cont_nondet_handler', [extra_files(['ContIO.hs'])], multimod_compile_and_r |
| 9 | 9 | test('cont_stack_overflow', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_stack_overflow', '-with-rtsopts "-ki1k -kc2k -kb256"'])
|
| 10 | 10 | |
| 11 | 11 | test('T23513', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['T23513', ''])
|
| 12 | +test('T27651', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['T27651', '']) |
| ... | ... | @@ -980,9 +980,6 @@ markLensBracketsO' a l = |
| 980 | 980 | ListBraces o c -> do
|
| 981 | 981 | o' <- markEpToken o
|
| 982 | 982 | return (set l (ListBraces o' c) a)
|
| 983 | - ListSquare o c -> do
|
|
| 984 | - o' <- markEpToken o
|
|
| 985 | - return (set l (ListSquare o' c) a)
|
|
| 986 | 983 | ListNone -> return (set l ListNone a)
|
| 987 | 984 | |
| 988 | 985 | markLensBracketsC :: (Monad m, Monoid w)
|
| ... | ... | @@ -996,9 +993,6 @@ markLensBracketsC' a l = |
| 996 | 993 | ListBraces o c -> do
|
| 997 | 994 | c' <- markEpToken c
|
| 998 | 995 | return (set l (ListBraces o c') a)
|
| 999 | - ListSquare o c -> do
|
|
| 1000 | - c' <- markEpToken c
|
|
| 1001 | - return (set l (ListSquare o c') a)
|
|
| 1002 | 996 | ListNone -> return (set l ListNone a)
|
| 1003 | 997 | |
| 1004 | 998 | -- -------------------------------------
|
| ... | ... | @@ -1468,6 +1462,19 @@ markKwT (AddDarrowAnn tok) = AddDarrowAnn <$> markEpUniToken tok |
| 1468 | 1462 | |
| 1469 | 1463 | -- ---------------------------------------------------------------------
|
| 1470 | 1464 | |
| 1465 | +markAnnListD :: (Monad m, Monoid w)
|
|
| 1466 | + => Either (EpToken "[", EpToken "]") AnnList
|
|
| 1467 | + -> EP w m a
|
|
| 1468 | + -> EP w m (Either (EpToken "[", EpToken "]") AnnList, a)
|
|
| 1469 | +markAnnListD (Left (o,c)) action = do
|
|
| 1470 | + o' <- markEpToken o
|
|
| 1471 | + r <- action
|
|
| 1472 | + c' <- markEpToken c
|
|
| 1473 | + return (Left (o',c'), r)
|
|
| 1474 | +markAnnListD (Right ann) action = do
|
|
| 1475 | + (ann',r) <- markAnnList' ann action
|
|
| 1476 | + return (Right ann',r)
|
|
| 1477 | + |
|
| 1471 | 1478 | markAnnList :: (Monad m, Monoid w)
|
| 1472 | 1479 | => EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a)
|
| 1473 | 1480 | markAnnList ann action = do
|
| ... | ... | @@ -3115,10 +3122,10 @@ instance ExactPrint (HsExpr GhcPs) where |
| 3115 | 3122 | e' <- markAnnotated e
|
| 3116 | 3123 | return (HsLet (tkLet',tkIn') binds' e')
|
| 3117 | 3124 | |
| 3118 | - exact (HsDo (an,l) do_or_list_comp stmts) = do
|
|
| 3125 | + exact (HsDo an do_or_list_comp stmts) = do
|
|
| 3119 | 3126 | debugM $ "HsDo"
|
| 3120 | - (an',l',stmts') <- exactDo (an,l) do_or_list_comp stmts
|
|
| 3121 | - return (HsDo (an',l') do_or_list_comp stmts')
|
|
| 3127 | + (an',stmts') <- exactDo an do_or_list_comp stmts
|
|
| 3128 | + return (HsDo an' do_or_list_comp stmts')
|
|
| 3122 | 3129 | |
| 3123 | 3130 | exact (ExplicitList (o,c) es) = do
|
| 3124 | 3131 | debugM $ "ExplicitList start"
|
| ... | ... | @@ -3290,8 +3297,8 @@ instance ExactPrint (HsExpr GhcPs) where |
| 3290 | 3297 | -- ---------------------------------------------------------------------
|
| 3291 | 3298 | |
| 3292 | 3299 | exactDo :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))
|
| 3293 | - => (AnnList, EpaLocation) -> HsDoFlavour -> LocatedAn an a
|
|
| 3294 | - -> EP w m (AnnList, EpaLocation, LocatedAn an a)
|
|
| 3300 | + => DoAnn -> HsDoFlavour -> LocatedAn an a
|
|
| 3301 | + -> EP w m (DoAnn, LocatedAn an a)
|
|
| 3295 | 3302 | exactDo (an,l) (DoExpr m) stmts = exactMdo l m "do" >>=
|
| 3296 | 3303 | \l0 -> markMaybeDodgyStmts (an,l0) stmts
|
| 3297 | 3304 | exactDo (an,l) GhciStmtCtxt stmts = printStringAtAA l "do" >>=
|
| ... | ... | @@ -3310,15 +3317,23 @@ exactMdo l (Just module_name) kw = printStringAtAA l n |
| 3310 | 3317 | n = (moduleNameString module_name) ++ "." ++ kw
|
| 3311 | 3318 | |
| 3312 | 3319 | markMaybeDodgyStmts :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))
|
| 3313 | - => (AnnList, EpaLocation) -> LocatedAn an a -> EP w m (AnnList, EpaLocation, LocatedAn an a)
|
|
| 3320 | + => DoAnn -> LocatedAn an a -> EP w m (DoAnn, LocatedAn an a)
|
|
| 3314 | 3321 | markMaybeDodgyStmts (an,l) stmts =
|
| 3315 | 3322 | if notDodgy stmts
|
| 3316 | 3323 | then do
|
| 3317 | - (an0,stmts') <- markAnnListA' an $ \a -> do
|
|
| 3318 | - r <- markAnnotatedWithLayout stmts
|
|
| 3319 | - return (a, r)
|
|
| 3320 | - return (an0, l, stmts')
|
|
| 3321 | - else return (an, l, stmts)
|
|
| 3324 | + (an0,stmts') <- case an of
|
|
| 3325 | + Left (o,c) -> do
|
|
| 3326 | + o' <- markEpToken o
|
|
| 3327 | + r <- markAnnotated stmts
|
|
| 3328 | + c' <- markEpToken c
|
|
| 3329 | + return (Left (o',c'), r)
|
|
| 3330 | + Right an' -> do
|
|
| 3331 | + (an'',r') <- markAnnListA' an' $ \a -> do
|
|
| 3332 | + r <- markAnnotatedWithLayout stmts
|
|
| 3333 | + return (a, r)
|
|
| 3334 | + return (Right an'',r')
|
|
| 3335 | + return ((an0, l), stmts')
|
|
| 3336 | + else return ((an, l), stmts)
|
|
| 3322 | 3337 | |
| 3323 | 3338 | notDodgy :: GenLocated (EpAnn ann) a -> Bool
|
| 3324 | 3339 | notDodgy (L (EpAnn anc _ _) _) = notDodgyE anc
|
| ... | ... | @@ -3601,9 +3616,7 @@ instance ExactPrint (HsCmd GhcPs) where |
| 3601 | 3616 | exact (HsCmdDo (an0,loc) es) = do
|
| 3602 | 3617 | debugM $ "HsCmdDo"
|
| 3603 | 3618 | loc' <- printStringAtAA loc "do"
|
| 3604 | - (an1,es') <- markAnnList' an0 $ do
|
|
| 3605 | - ee <- markAnnotated es
|
|
| 3606 | - return ee
|
|
| 3619 | + (an1,es') <- markAnnListD an0 $ do markAnnotated es
|
|
| 3607 | 3620 | return (HsCmdDo (an1,loc') es')
|
| 3608 | 3621 | |
| 3609 | 3622 | -- ---------------------------------------------------------------------
|
| ... | ... | @@ -343,7 +343,6 @@ insertTopLevelCppComments (HsModule (XModulePs an lo mdeprec mbDoc) mmn mexports |
| 343 | 343 | |
| 344 | 344 | annListBracketsLocs :: AnnListBrackets -> (EpaLocation,EpaLocation)
|
| 345 | 345 | annListBracketsLocs (ListBraces o c) = (getEpTokenLoc o, getEpTokenLoc c)
|
| 346 | -annListBracketsLocs (ListSquare o c) = (getEpTokenLoc o, getEpTokenLoc c)
|
|
| 347 | 346 | annListBracketsLocs ListNone = (noAnn, noAnn)
|
| 348 | 347 | |
| 349 | 348 | data SplitWhere = Before | After
|