Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

23 changed files:

Changes:

  • changelog.d/fix-control0-mask-trampoline
    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
    +}

  • changelog.d/fix-threadlabel-segfault-27618
    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
    +}

  • compiler/GHC/Data/FastString.hs
    ... ... @@ -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.
    

  • compiler/GHC/Hs/Expr.hs
    ... ... @@ -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
     
    

  • compiler/GHC/Hs/Utils.hs
    ... ... @@ -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 "-"
    

  • compiler/GHC/Parser.y
    ... ... @@ -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
     -- -------------------------------------
    

  • compiler/GHC/Parser/Annotation.hs
    ... ... @@ -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
    

  • compiler/GHC/Parser/PostProcess.hs
    ... ... @@ -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
    

  • rts/ContinuationOps.cmm
    ... ... @@ -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];
    

  • rts/PrimOps.cmm
    ... ... @@ -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
         }
    

  • rts/StgMiscClosures.cmm
    ... ... @@ -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
        ------------------------------------------------------------------------- */
    

  • rts/include/stg/MiscClosures.h
    ... ... @@ -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;
    

  • testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
    ... ... @@ -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))
    

  • testsuite/tests/parser/should_compile/DumpSemis.stderr
    ... ... @@ -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))
    

  • testsuite/tests/printer/Test20297.stdout
    ... ... @@ -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))
    

  • testsuite/tests/rts/T27618.hs
    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"

  • testsuite/tests/rts/T27618.stdout
    1
    +done

  • testsuite/tests/rts/all.T
    ... ... @@ -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
    +

  • testsuite/tests/rts/continuations/T27651.hs
    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"

  • testsuite/tests/rts/continuations/T27651.stdout
    1
    +ok

  • testsuite/tests/rts/continuations/all.T
    ... ... @@ -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', ''])

  • utils/check-exact/ExactPrint.hs
    ... ... @@ -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
     -- ---------------------------------------------------------------------
    

  • utils/check-exact/Utils.hs
    ... ... @@ -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