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

Commits:

30 changed files:

Changes:

  • changelog.d/T27131
    1
    +section: rts
    
    2
    +synopsis: Add rts Message to set/unset TSO flags
    
    3
    +issues: #27131
    
    4
    +mrs: !15831
    
    5
    +description: This enables e.g. toggling breakpoints from different threads,
    
    6
    +    which is necessary to safely implement features like pausing, per-thread
    
    7
    +    step-in, and more in the haskell debugger.
    
    8
    +

  • changelog.d/cmm-import-syntax-changes
    1
    +section: cmm
    
    2
    +synopsis: Changes to Cmm hand-written syntax for symbol imports.
    
    3
    +issues: #27162
    
    4
    +mrs: !15135
    
    5
    +
    
    6
    +description: {
    
    7
    +  In hand-written Cmm, there is syntax to declare symbol names from outside of
    
    8
    +  the current .cmm file (e.g. .c or .cmm files).
    
    9
    +
    
    10
    +  The existing syntax is
    
    11
    +
    
    12
    +  > import foo;         -- for a function
    
    13
    +  > import CLOSURE foo; -- for data
    
    14
    +
    
    15
    +  and this implicitly meant that the symbol (`foo`) could be found in an
    
    16
    +  external shared library, not the current one. There was no syntax to specify
    
    17
    +  that the symbol should be found in the current shared library, i.e. in a
    
    18
    +  .cmm file (or .hs file) in the current Haskell package.
    
    19
    +
    
    20
    +  The new syntax assumes local by default and allows specifying external:
    
    21
    +
    
    22
    +  > import foo;               -- for a function in the current lib
    
    23
    +  > import DATA foo;          -- for data in the current lib
    
    24
    +  > import extern foo;        -- for a function in an external lib
    
    25
    +  > import extern DATA foo;   -- for data in an external lib
    
    26
    +  > import "unitid" foo;      -- for a function in the Haskell unit "unitid"
    
    27
    +  > import "unitid" DATA foo; -- for data in the Haskell unit "unitid"
    
    28
    +
    
    29
    +  In practice, the only platform where this can be expected to make a
    
    30
    +  difference is on Windows, and only when compiling each Haskell package as a
    
    31
    +  separate .dll dynamic library.
    
    32
    +}
    
    33
    +
    
    34
    +

  • compiler/GHC/ByteCode/Binary.hs
    ... ... @@ -20,7 +20,7 @@ module GHC.ByteCode.Binary (
    20 20
     import GHC.Prelude
    
    21 21
     
    
    22 22
     import GHC.ByteCode.Types
    
    23
    -import GHC.Data.FastString
    
    23
    +import qualified GHC.Data.Word64Map.Strict as Word64Map
    
    24 24
     import GHC.Types.Name
    
    25 25
     import GHC.Types.Name.Cache
    
    26 26
     import GHC.Types.Name.Env
    
    ... ... @@ -291,9 +291,8 @@ addBinNameWriter bh' = do
    291 291
             | otherwise -> do
    
    292 292
                 putByte bh 1
    
    293 293
                 key <- getBinNameKey env_ref nm
    
    294
    -            -- Delimit the OccName from the deterministic counter to keep the
    
    295
    -            -- encoding injective, avoiding collisions like "foo1" vs "foo#1".
    
    296
    -            put_ bh (occNameFS (occName nm) `appendFS` mkFastString ('#' : show key))
    
    294
    +            put_ bh $ occNameFS $ occName nm
    
    295
    +            put_ bh key
    
    297 296
       where
    
    298 297
         -- Find a deterministic key for local names. This
    
    299 298
         getBinNameKey ref name = do
    
    ... ... @@ -304,7 +303,7 @@ addBinNameWriter bh' = do
    304 303
     
    
    305 304
     addBinNameReader :: NameCache -> ReadBinHandle -> IO ReadBinHandle
    
    306 305
     addBinNameReader nc bh' = do
    
    307
    -  env_ref <- newIORef emptyOccEnv
    
    306
    +  env_ref <- newIORef Word64Map.empty
    
    308 307
       pure $ flip addReaderToUserData bh' $ BinaryReader $ \bh -> do
    
    309 308
         t <- getByte bh
    
    310 309
         case t of
    
    ... ... @@ -313,15 +312,16 @@ addBinNameReader nc bh' = do
    313 312
             pure $ BinName nm
    
    314 313
           1 -> do
    
    315 314
             occ <- mkVarOccFS <$> get bh
    
    315
    +        key <- get bh
    
    316 316
             -- We don't want to get a new unique from the NameCache each time we
    
    317 317
             -- see a name.
    
    318 318
             nm' <- unsafeInterleaveIO $ do
    
    319 319
               u <- takeUniqFromNameCache nc
    
    320 320
               evaluate $ mkInternalName u occ noSrcSpan
    
    321 321
             fmap BinName $ atomicModifyIORef' env_ref $ \env ->
    
    322
    -          case lookupOccEnv env occ of
    
    322
    +          case Word64Map.lookup key env of
    
    323 323
                 Just nm -> (env, nm)
    
    324
    -            _ -> nm' `seq` (extendOccEnv env occ nm', nm')
    
    324
    +            _ -> nm' `seq` (Word64Map.insert key nm' env, nm')
    
    325 325
           _ -> panic "Binary BinName: invalid byte"
    
    326 326
     
    
    327 327
     -- Note [Serializing Names in bytecode]
    

  • compiler/GHC/Cmm/Lexer.x
    ... ... @@ -174,6 +174,8 @@ data CmmToken
    174 174
       | CmmT_return
    
    175 175
       | CmmT_returns
    
    176 176
       | CmmT_import
    
    177
    +  | CmmT_extern
    
    178
    +  | CmmT_DATA
    
    177 179
       | CmmT_switch
    
    178 180
       | CmmT_case
    
    179 181
       | CmmT_default
    
    ... ... @@ -273,6 +275,8 @@ reservedWordsFM = listToUFM $
    273 275
             ( "return",             CmmT_return ),
    
    274 276
             ( "returns",            CmmT_returns ),
    
    275 277
             ( "import",             CmmT_import ),
    
    278
    +        ( "extern",             CmmT_extern ),
    
    279
    +        ( "DATA",               CmmT_DATA ),
    
    276 280
             ( "switch",             CmmT_switch ),
    
    277 281
             ( "case",               CmmT_case ),
    
    278 282
             ( "default",            CmmT_default ),
    

  • compiler/GHC/Cmm/Parser.y
    ... ... @@ -372,6 +372,8 @@ import qualified Data.ByteString.Char8 as BS8
    372 372
             'return'        { L _ (CmmT_return) }
    
    373 373
             'returns'       { L _ (CmmT_returns) }
    
    374 374
             'import'        { L _ (CmmT_import) }
    
    375
    +        'extern'        { L _ (CmmT_extern) }
    
    376
    +        'DATA'          { L _ (CmmT_DATA) }
    
    375 377
             'switch'        { L _ (CmmT_switch) }
    
    376 378
             'case'          { L _ (CmmT_case) }
    
    377 379
             'default'       { L _ (CmmT_default) }
    
    ... ... @@ -643,18 +645,42 @@ importNames
    643 645
     importName
    
    644 646
             :: { (FastString,  CLabel) }
    
    645 647
     
    
    646
    -        -- A label imported without an explicit packageId.
    
    647
    -        --      These are taken to come from some foreign, unnamed package.
    
    648
    +        -- A code label imported from within the same shared library.
    
    648 649
             : NAME
    
    649
    -        { ($1, mkForeignLabel $1 ForeignLabelInExternalPackage IsFunction) }
    
    650
    +        { ($1, mkForeignLabel $1 ForeignLabelInThisPackage IsFunction) }
    
    650 651
     
    
    651
    -        -- as previous 'NAME', but 'IsData'
    
    652
    -        | 'CLOSURE' NAME
    
    653
    -        { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsData) }
    
    652
    +        -- A data label imported from within the same shared library.
    
    653
    +        | 'DATA' NAME
    
    654
    +        { ($2, mkForeignLabel $2 ForeignLabelInThisPackage IsData) }
    
    654 655
     
    
    655
    -        -- A label imported with an explicit UnitId.
    
    656
    +        -- CLOSURE is a historical alias for DATA in this context.
    
    657
    +        | 'CLOSURE' NAME
    
    658
    +        { ($2, mkForeignLabel $2 ForeignLabelInThisPackage IsData) }
    
    659
    +
    
    660
    +        -- A code label imported from another unamed shared library. These may
    
    661
    +        -- come from a foreign shared library, or from the shared library for
    
    662
    +        -- an unnamed Haskell package. This corresponds on Windows/PE to
    
    663
    +        -- __declspec(dllimport) in C.
    
    664
    +        | 'extern' NAME
    
    665
    +        { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsFunction) }
    
    666
    +
    
    667
    +        -- A data label imported from another unamed shared library.
    
    668
    +        -- This corresponds on Windows/PE to __declspec(dllimport) in C (but
    
    669
    +        -- cmm doesn't know about data vs function symbols so we have to say).
    
    670
    +        | 'extern' 'DATA' NAME
    
    671
    +        { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage IsData) }
    
    672
    +
    
    673
    +        -- A code label imported from the shared library for a Haskell package
    
    674
    +        -- with the given UnitId. Such labels behave as local when used within
    
    675
    +        -- the specified unit, or as extern otherwise.
    
    656 676
             | STRING NAME
    
    657
    -        { ($2, mkCmmCodeLabel (UnitId (mkFastString $1)) $2) }
    
    677
    +        { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsFunction) }
    
    678
    +
    
    679
    +        -- A data label imported from the shared library for a Haskell package
    
    680
    +        -- with the given UnitId. Such labels behave as local when used within
    
    681
    +        -- the specified unit, or as extern otherwise.
    
    682
    +        | STRING 'DATA' NAME
    
    683
    +        { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsData) }
    
    658 684
     
    
    659 685
     
    
    660 686
     names   :: { [FastString] }
    

  • compiler/GHC/Driver/Flags.hs
    ... ... @@ -1112,9 +1112,9 @@ data WarningFlag =
    1112 1112
            -- ^ @since 9.14, scheduled to be removed in 9.18
    
    1113 1113
            --
    
    1114 1114
            -- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
    
    1115
    -   | Opt_WarnUnusableUnpackPragmas                   -- Since 9.14
    
    1116
    -   | Opt_WarnPatternNamespaceSpecifier               -- Since 9.14
    
    1117
    -   | Opt_WarnUnrecognisedModifiers                   -- ^ @since 9.16
    
    1115
    +   | Opt_WarnUnusableUnpackPragmas                   -- ^ @since 9.14
    
    1116
    +   | Opt_WarnPatternNamespaceSpecifier               -- ^ @since 9.14
    
    1117
    +   | Opt_WarnUnrecognisedModifiers                   -- ^ @since 10.0
    
    1118 1118
        deriving (Eq, Ord, Show, Enum, Bounded)
    
    1119 1119
     
    
    1120 1120
     -- | Return the names of a WarningFlag
    
    ... ... @@ -1377,7 +1377,7 @@ standardWarnings -- see Note [Documenting warning flags]
    1377 1377
             Opt_WarnTypeEqualityRequiresOperators,
    
    1378 1378
             Opt_WarnInconsistentFlags,
    
    1379 1379
             Opt_WarnTypeEqualityOutOfScope,
    
    1380
    -        Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 9.16
    
    1380
    +        Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 10.2 (#25911)
    
    1381 1381
             Opt_WarnViewPatternSignatures,
    
    1382 1382
             Opt_WarnUselessSpecialisations,
    
    1383 1383
             Opt_WarnDeprecatedPragmas,
    

  • docs/users_guide/debug-info.rst
    ... ... @@ -478,7 +478,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table
    478 478
         :type: dynamic
    
    479 479
         :category: debugging
    
    480 480
     
    
    481
    -    :since: 9.16
    
    481
    +    :since: 10.0
    
    482 482
     
    
    483 483
         Disable generation of distinct info tables for all constructors.
    
    484 484
     
    
    ... ... @@ -488,7 +488,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table
    488 488
         :type: dynamic
    
    489 489
         :category: debugging
    
    490 490
     
    
    491
    -    :since: 9.16
    
    491
    +    :since: 10.0
    
    492 492
     
    
    493 493
         The entries in the info table map resulting from
    
    494 494
         :ghc-flag:`-fdistinct-constructor-tables` flag may significantly
    

  • docs/users_guide/exts/explicit_namespaces.rst
    ... ... @@ -121,7 +121,7 @@ there is a need to support older GHC versions.
    121 121
     Wildcards in import/export lists
    
    122 122
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    123 123
     
    
    124
    -**Since:** GHC 9.16
    
    124
    +**Since:** GHC 10.0
    
    125 125
     
    
    126 126
     Namespace-specified wildcards ``type ..`` and ``data ..`` may be used to import
    
    127 127
     all names in the corresponding namespace from a module: ::
    

  • docs/users_guide/exts/linear_types.rst
    ... ... @@ -318,7 +318,7 @@ hidden; it is an essential part of the exposed interface.)
    318 318
     
    
    319 319
     Interaction with Modifiers
    
    320 320
     --------------------------
    
    321
    -Since GHC version 9.16, Linear types use :extension:`Modifiers` syntax, and by
    
    321
    +Since GHC version 10.0, Linear types use :extension:`Modifiers` syntax, and by
    
    322 322
     default enable that extension. In earlier versions, linear types used a more
    
    323 323
     restricted variant of that syntax.
    
    324 324
     
    

  • docs/users_guide/exts/modifiers.rst
    ... ... @@ -6,7 +6,7 @@ Modifiers
    6 6
     .. extension:: Modifiers
    
    7 7
         :shortdesc: Allow experimental modifier syntax.
    
    8 8
     
    
    9
    -    :since: 9.16
    
    9
    +    :since: 10.0
    
    10 10
         :status: Experimental
    
    11 11
     
    
    12 12
         Enable modifier syntax in various places, such as arrows (``a %m -> b``) and
    
    ... ... @@ -138,10 +138,10 @@ and limitations.
    138 138
          let %1  (Just x) = ... -- (2b)
    
    139 139
          let %1 !(Just x) = ... -- (2c)
    
    140 140
     
    
    141
    -  In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 9.16, (1a)
    
    141
    +  In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 10.0, (1a)
    
    142 142
       parses as (1d), and (2a) fails to parse.
    
    143 143
     
    
    144
    -  Note that linear bindings must be strict. (1c) and (2c) parse in 9.16 the same
    
    144
    +  Note that linear bindings must be strict. (1c) and (2c) parse in 10.0 the same
    
    145 145
       as in 9.14. But with ``-XStrict`` enabled, (1a) and (2a) would previously have
    
    146 146
       been accepted, and are now rejected, even with
    
    147 147
       ``-XLinearTypes -XNoModifiers``.

  • docs/users_guide/exts/qualified_strings.rst
    ... ... @@ -6,7 +6,7 @@ Qualified string literals
    6 6
     .. extension:: QualifiedStrings
    
    7 7
         :shortdesc: Enable qualified string literals.
    
    8 8
     
    
    9
    -    :since: 9.16.1
    
    9
    +    :since: 10.0.1
    
    10 10
     
    
    11 11
         Enable qualified string literals.
    
    12 12
     
    

  • docs/users_guide/exts/required_type_arguments.rst
    ... ... @@ -303,7 +303,7 @@ A few limitations apply:
    303 303
       * In term syntax, in positions where ``*`` is a direct argument to ``->``, e.g.
    
    304 304
         in ``f (* -> * -> *)`` and ``f (* -> Constraint)``, the ``*``\s stand for
    
    305 305
         ``Type``, provided the :extension:`StarIsType` extension is enabled.
    
    306
    -    This is supported from GHC 9.16 onwards; earlier versions will produce
    
    306
    +    This is supported from GHC 10.0 onwards; earlier versions will produce
    
    307 307
         a parse error.
    
    308 308
     
    
    309 309
       What to do instead: use ``Type`` from the ``Data.Kind`` module.
    

  • docs/users_guide/using-warnings.rst
    ... ... @@ -2711,7 +2711,7 @@ of ``-W(no-)*``.
    2711 2711
         :type: dynamic
    
    2712 2712
         :reverse: -Wno-unrecognised-modifiers
    
    2713 2713
     
    
    2714
    -    :since: 9.16
    
    2714
    +    :since: 10.0
    
    2715 2715
     
    
    2716 2716
         :default: on
    
    2717 2717
     
    

  • docs/users_guide/using.rst
    ... ... @@ -1618,7 +1618,7 @@ Some flags only make sense for particular target platforms.
    1618 1618
         :type: dynamic
    
    1619 1619
         :category: platform-options
    
    1620 1620
     
    
    1621
    -    :since: 9.16.1
    
    1621
    +    :since: 10.0.1
    
    1622 1622
         :implies: :ghc-flag:`-mavx512f`
    
    1623 1623
     
    
    1624 1624
         (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
    
    ... ... @@ -1639,7 +1639,7 @@ Some flags only make sense for particular target platforms.
    1639 1639
         :type: dynamic
    
    1640 1640
         :category: platform-options
    
    1641 1641
     
    
    1642
    -    :since: 9.16.1
    
    1642
    +    :since: 10.0.1
    
    1643 1643
         :implies: :ghc-flag:`-mavx512f`
    
    1644 1644
     
    
    1645 1645
         (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
    
    ... ... @@ -1684,7 +1684,7 @@ Some flags only make sense for particular target platforms.
    1684 1684
         :type: dynamic
    
    1685 1685
         :category: platform-options
    
    1686 1686
     
    
    1687
    -    :since: 9.16.1
    
    1687
    +    :since: 10.0.1
    
    1688 1688
         :implies: :ghc-flag:`-mavx512f`
    
    1689 1689
     
    
    1690 1690
         (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
    
    ... ... @@ -1823,7 +1823,7 @@ Some flags only make sense for particular target platforms.
    1823 1823
         :type: dynamic
    
    1824 1824
         :category: platform-options
    
    1825 1825
     
    
    1826
    -    :since: 9.16.1
    
    1826
    +    :since: 10.0.1
    
    1827 1827
     
    
    1828 1828
         (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
    
    1829 1829
         or the :ref:`LLVM backend <llvm-code-gen>`) to emit x86 GFNI instructions.
    

  • hadrian/src/Builder.hs
    ... ... @@ -345,11 +345,7 @@ instance H.Builder Builder where
    345 345
     
    
    346 346
                     Haddock BuildPackage -> runHaddock path buildArgs buildInputs
    
    347 347
     
    
    348
    -                Ghc FindHsDependencies _ -> do
    
    349
    -                  -- Use a response file for ghc -M invocations, to
    
    350
    -                  -- avoid issues with command line size limit on
    
    351
    -                  -- Windows (#26637)
    
    352
    -                  runGhcWithResponse path buildArgs buildInputs
    
    348
    +                Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
    
    353 349
     
    
    354 350
                     HsCpp    -> captureStdout
    
    355 351
     
    
    ... ... @@ -393,14 +389,19 @@ runHaddock haddockPath flagArgs fileInputs = withResponseFile $ \tmp -> do
    393 389
         writeFile' tmp $ escapeArgs fileInputs
    
    394 390
         cmd [haddockPath] flagArgs ('@' : tmp)
    
    395 391
     
    
    396
    -runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
    
    397
    -runGhcWithResponse ghcPath flagArgs fileInputs = withResponseFile $ \tmp -> do
    
    398
    -    writeFile' tmp $ escapeArgs fileInputs
    
    399
    -    -- We can't put the flags in a response file, because some flags
    
    400
    -    -- require empty arguments (such as the -dep-suffix flag), but
    
    401
    -    -- that isn't supported yet due to #26560.
    
    402
    -    cmd [ghcPath] flagArgs ('@' : tmp)
    
    403
    -
    
    392
    +-- | Use a response file for ghc invocations to avoid issues with command line
    
    393
    +-- size limit on Windows (#26637).
    
    394
    +runGhcWithResponse :: FilePath -- ^ Path to ghc
    
    395
    +  -> [String] -- ^ Arguments passed on the command line
    
    396
    +  -> [FilePath] -- ^ Input file paths (passed via response file)
    
    397
    +  -> [CmdOption]
    
    398
    +  -> Action ()
    
    399
    +runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withResponseFile $ \tmp -> do
    
    400
    +  -- We can't put the buildArgs in a response file, because some flags require
    
    401
    +  -- empty arguments (such as the -dep-suffix flag), but that isn't supported
    
    402
    +  -- yet due to #26560.
    
    403
    +  writeFile' tmp (escapeArgs buildInputs)
    
    404
    +  cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
    
    404 405
     
    
    405 406
     -- TODO: Some builders are required only on certain platforms. For example,
    
    406 407
     -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
    

  • hadrian/src/Hadrian/Builder.hs
    ... ... @@ -29,7 +29,9 @@ import Hadrian.Utilities
    29 29
     
    
    30 30
     -- | This data structure captures all information relevant to invoking a builder.
    
    31 31
     data BuildInfo = BuildInfo {
    
    32
    -    -- | Command line arguments.
    
    32
    +    -- | Command line arguments. Some builders (e.g. Ar, Ghc, Haddock) omit
    
    33
    +    -- buildInputs from buildArgs so that buildInputs can be passed separately
    
    34
    +    -- using a response file.
    
    33 35
         buildArgs :: [String],
    
    34 36
         -- | Input files.
    
    35 37
         buildInputs :: [FilePath],
    

  • hadrian/src/Hadrian/Utilities.hs
    ... ... @@ -334,13 +334,23 @@ keepResponseFiles = do
    334 334
     withResponseFile :: (FilePath -> Action a) -> Action a
    
    335 335
     withResponseFile action = do
    
    336 336
         keep <- keepResponseFiles
    
    337
    +    let putVerboseResponseFile tmp = do
    
    338
    +            verbosity <- getVerbosity
    
    339
    +            when (verbosity >= Verbose) $ do
    
    340
    +                tmpContent <- liftIO (readFile tmp)
    
    341
    +                putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
    
    337 342
         if keep
    
    338 343
             then do
    
    339 344
                 (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
    
    340 345
                 liftIO $ hClose h
    
    341 346
                 putInfo $ "Keeping response file: " ++ tmp
    
    342
    -            action tmp
    
    343
    -        else withTempFile action
    
    347
    +            result <- action tmp
    
    348
    +            putVerboseResponseFile tmp
    
    349
    +            return result
    
    350
    +        else withTempFile $ \tmp -> do
    
    351
    +            result <- action tmp
    
    352
    +            putVerboseResponseFile tmp
    
    353
    +            return result
    
    344 354
     
    
    345 355
     -- | Link a file tracking the link target. Create the target directory if
    
    346 356
     -- missing.
    

  • hadrian/src/Settings/Builders/Ghc.hs
    ... ... @@ -62,7 +62,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do
    62 62
                       [ arg "-fwrite-ide-info"
    
    63 63
                       , arg "-hiedir", arg hie_path
    
    64 64
                       ]
    
    65
    -            , getInputs
    
    66 65
                 , arg "-o", arg =<< getOutput ]
    
    67 66
     
    
    68 67
     compileC :: Args
    
    ... ... @@ -78,7 +77,6 @@ compileC = builder (Ghc CompileCWithGhc) ? do
    78 77
                 , mconcat (map (map ("-optc" ++) <$>) ccArgs)
    
    79 78
                 , defaultGhcWarningsArgs
    
    80 79
                 , arg "-c"
    
    81
    -            , getInputs
    
    82 80
                 , arg "-o"
    
    83 81
                 , arg =<< getOutput ]
    
    84 82
     
    
    ... ... @@ -95,7 +93,6 @@ compileCxx = builder (Ghc CompileCppWithGhc) ? do
    95 93
                 , mconcat (map (map ("-optcxx" ++) <$>) ccArgs)
    
    96 94
                 , defaultGhcWarningsArgs
    
    97 95
                 , arg "-c"
    
    98
    -            , getInputs
    
    99 96
                 , arg "-o"
    
    100 97
                 , arg =<< getOutput ]
    
    101 98
     
    

  • rts/Interpreter.c
    ... ... @@ -416,12 +416,22 @@ void rts_disableStopNextBreakpointAll(void)
    416 416
     
    
    417 417
     void rts_enableStopNextBreakpoint(StgTSO* tso)
    
    418 418
     {
    
    419
    -    tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
    
    419
    +#if defined(THREADED_RTS)
    
    420
    +  Capability* cap = rts_unsafeGetMyCapability();
    
    421
    +  setThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
    
    422
    +#else
    
    423
    +  tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
    
    424
    +#endif
    
    420 425
     }
    
    421 426
     
    
    422 427
     void rts_disableStopNextBreakpoint(StgTSO* tso)
    
    423 428
     {
    
    424
    -    tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
    
    429
    +#if defined(THREADED_RTS)
    
    430
    +  Capability* cap = rts_unsafeGetMyCapability();
    
    431
    +  unsetThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
    
    432
    +#else
    
    433
    +  tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
    
    434
    +#endif
    
    425 435
     }
    
    426 436
     
    
    427 437
     /* ---------------------------------------------------------------------------
    
    ... ... @@ -430,12 +440,22 @@ void rts_disableStopNextBreakpoint(StgTSO* tso)
    430 440
     
    
    431 441
     void rts_enableStopAfterReturn(StgTSO* tso)
    
    432 442
     {
    
    443
    +#if defined(THREADED_RTS)
    
    444
    +  Capability* cap = rts_unsafeGetMyCapability();
    
    445
    +  setThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
    
    446
    +#else
    
    433 447
       tso->flags |= TSO_STOP_AFTER_RETURN;
    
    448
    +#endif
    
    434 449
     }
    
    435 450
     
    
    436 451
     void rts_disableStopAfterReturn(StgTSO* tso)
    
    437 452
     {
    
    453
    +#if defined(THREADED_RTS)
    
    454
    +  Capability* cap = rts_unsafeGetMyCapability();
    
    455
    +  unsetThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
    
    456
    +#else
    
    438 457
       tso->flags &= ~TSO_STOP_AFTER_RETURN;
    
    458
    +#endif
    
    439 459
     }
    
    440 460
     
    
    441 461
     /*
    

  • rts/Messages.c
    ... ... @@ -35,7 +35,9 @@ void sendMessage(Capability *from_cap, Capability *to_cap, Message *msg)
    35 35
                 i != &stg_MSG_TRY_WAKEUP_info &&
    
    36 36
                 i != &stg_IND_info && // can happen if a MSG_BLACKHOLE is revoked
    
    37 37
                 i != &stg_WHITEHOLE_info &&
    
    38
    -            i != &stg_MSG_CLONE_STACK_info) {
    
    38
    +            i != &stg_MSG_CLONE_STACK_info &&
    
    39
    +            i != &stg_MSG_SET_TSO_FLAG_info &&
    
    40
    +            i != &stg_MSG_UNSET_TSO_FLAG_info) {
    
    39 41
                 barf("sendMessage: %p", i);
    
    40 42
             }
    
    41 43
         }
    
    ... ... @@ -137,6 +139,16 @@ loop:
    137 139
             MessageCloneStack *cloneStackMessage = (MessageCloneStack*) m;
    
    138 140
             handleCloneStackMessage(cap, cloneStackMessage);
    
    139 141
         }
    
    142
    +    else if(i == &stg_MSG_SET_TSO_FLAG_info){
    
    143
    +        MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
    
    144
    +        u->tso->flags |= u->flag;
    
    145
    +        return;
    
    146
    +    }
    
    147
    +    else if(i == &stg_MSG_UNSET_TSO_FLAG_info){
    
    148
    +        MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
    
    149
    +        u->tso->flags &= ~u->flag;
    
    150
    +        return;
    
    151
    +    }
    
    140 152
         else
    
    141 153
         {
    
    142 154
             barf("executeMessage: %p", i);
    

  • rts/StgMiscClosures.cmm
    ... ... @@ -855,6 +855,12 @@ INFO_TABLE_CONSTR(stg_MSG_NULL,1,0,0,PRIM,"MSG_NULL","MSG_NULL")
    855 855
     INFO_TABLE_CONSTR(stg_MSG_CLONE_STACK,3,0,0,PRIM,"MSG_CLONE_STACK","MSG_CLONE_STACK")
    
    856 856
     { ccall pbarf("stg_MSG_CLONE_STACK object (%p) entered!", R1 "ptr") never returns; }
    
    857 857
     
    
    858
    +INFO_TABLE_CONSTR(stg_MSG_SET_TSO_FLAG,2,1,0,PRIM,"MSG_SET_TSO_FLAG","MSG_SET_TSO_FLAG")
    
    859
    +{ foreign "C" barf("stg_MSG_SET_TSO_FLAG object (%p) entered!", R1) never returns; }
    
    860
    +
    
    861
    +INFO_TABLE_CONSTR(stg_MSG_UNSET_TSO_FLAG,2,1,0,PRIM,"MSG_UNSET_TSO_FLAG","MSG_UNSET_TSO_FLAG")
    
    862
    +{ foreign "C" barf("stg_MSG_UNSET_TSO_FLAG object (%p) entered!", R1) never returns; }
    
    863
    +
    
    858 864
     /* ----------------------------------------------------------------------------
    
    859 865
        END_TSO_QUEUE
    
    860 866
     
    

  • rts/Threads.c
    ... ... @@ -376,6 +376,38 @@ migrateThread (Capability *from, StgTSO *tso, Capability *to)
    376 376
         tryWakeupThread(from, tso);
    
    377 377
     }
    
    378 378
     
    
    379
    +/* ----------------------------------------------------------------------------
    
    380
    +   {set,unset}ThreadFlag
    
    381
    +
    
    382
    +   sets or unsets a flag in a given TSO
    
    383
    +   ------------------------------------------------------------------------- */
    
    384
    +
    
    385
    +#if defined(THREADED_RTS)
    
    386
    +static void
    
    387
    +updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info);
    
    388
    +
    
    389
    +void setThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
    
    390
    +{
    
    391
    +    updThreadFlag(from, tso, flag, &stg_MSG_SET_TSO_FLAG_info);
    
    392
    +}
    
    393
    +
    
    394
    +void unsetThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
    
    395
    +{
    
    396
    +    updThreadFlag(from, tso, flag, &stg_MSG_UNSET_TSO_FLAG_info);
    
    397
    +}
    
    398
    +
    
    399
    +static void
    
    400
    +updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info)
    
    401
    +{
    
    402
    +    MessageUpdTSOFlag *msg;
    
    403
    +    msg = (MessageUpdTSOFlag *)allocate(from,sizeofW(MessageUpdTSOFlag));
    
    404
    +    msg->tso  = tso;
    
    405
    +    msg->flag = flag;
    
    406
    +    SET_HDR_RELEASE(msg, info, CCS_SYSTEM);
    
    407
    +    sendMessage(from, tso->cap, (Message*)msg);
    
    408
    +}
    
    409
    +#endif
    
    410
    +
    
    379 411
     /* ----------------------------------------------------------------------------
    
    380 412
        awakenBlockedQueue
    
    381 413
     
    

  • rts/Threads.h
    ... ... @@ -19,6 +19,11 @@ void checkBlockingQueues (Capability *cap, StgTSO *tso);
    19 19
     void tryWakeupThread     (Capability *cap, StgTSO *tso);
    
    20 20
     void migrateThread       (Capability *from, StgTSO *tso, Capability *to);
    
    21 21
     
    
    22
    +#if defined(THREADED_RTS)
    
    23
    +void setThreadFlag       (Capability *from, StgTSO *tso, StgWord32 flag);
    
    24
    +void unsetThreadFlag     (Capability *from, StgTSO *tso, StgWord32 flag);
    
    25
    +#endif
    
    26
    +
    
    22 27
     // Wakes up a thread on a Capability (probably a different Capability
    
    23 28
     // from the one held by the current Task).
    
    24 29
     //
    

  • rts/include/rts/storage/Closures.h
    ... ... @@ -620,6 +620,12 @@ typedef struct MessageCloneStack_ {
    620 620
         StgTSO    *tso;
    
    621 621
     } MessageCloneStack;
    
    622 622
     
    
    623
    +typedef struct MessageUpdTSOFlag_ {
    
    624
    +    StgHeader header;
    
    625
    +    Message   *link;
    
    626
    +    StgTSO    *tso;
    
    627
    +    StgWord   flag;
    
    628
    +} MessageUpdTSOFlag;
    
    623 629
     
    
    624 630
     /* ----------------------------------------------------------------------------
    
    625 631
        Compact Regions
    

  • rts/include/stg/MiscClosures.h
    ... ... @@ -152,6 +152,8 @@ RTS_ENTRY(stg_MSG_TRY_WAKEUP);
    152 152
     RTS_ENTRY(stg_MSG_THROWTO);
    
    153 153
     RTS_ENTRY(stg_MSG_BLACKHOLE);
    
    154 154
     RTS_ENTRY(stg_MSG_CLONE_STACK);
    
    155
    +RTS_ENTRY(stg_MSG_SET_TSO_FLAG);
    
    156
    +RTS_ENTRY(stg_MSG_UNSET_TSO_FLAG);
    
    155 157
     RTS_ENTRY(stg_MSG_NULL);
    
    156 158
     RTS_ENTRY(stg_MVAR_TSO_QUEUE);
    
    157 159
     RTS_ENTRY(stg_catch);
    

  • testsuite/tests/rts/T27131.hs
    1
    +{-# LANGUAGE MagicHash #-}
    
    2
    +{-# LANGUAGE UnliftedFFITypes #-}
    
    3
    +
    
    4
    +module Main where
    
    5
    +
    
    6
    +import Control.Concurrent
    
    7
    +import Control.Monad
    
    8
    +import Foreign.C.Types
    
    9
    +import GHC.Conc.Sync (ThreadId(..), forkOn, myThreadId, setNumCapabilities)
    
    10
    +import GHC.Exts (ThreadId#)
    
    11
    +
    
    12
    +foreign import ccall unsafe "rts_enableStopNextBreakpoint"
    
    13
    +  rts_enableStopNextBreakpoint :: ThreadId# -> IO ()
    
    14
    +
    
    15
    +foreign import ccall unsafe "rts_disableStopNextBreakpoint"
    
    16
    +  rts_disableStopNextBreakpoint :: ThreadId# -> IO ()
    
    17
    +
    
    18
    +foreign import ccall unsafe "rts_enableStopAfterReturn"
    
    19
    +  rts_enableStopAfterReturn :: ThreadId# -> IO ()
    
    20
    +
    
    21
    +foreign import ccall unsafe "rts_disableStopAfterReturn"
    
    22
    +  rts_disableStopAfterReturn :: ThreadId# -> IO ()
    
    23
    +
    
    24
    +foreign import ccall unsafe "has_local_stop_next_breakpoint"
    
    25
    +  c_hasLocalStopNextBreakpoint :: IO CInt
    
    26
    +
    
    27
    +foreign import ccall unsafe "has_local_stop_after_return"
    
    28
    +  c_hasLocalStopAfterReturn :: IO CInt
    
    29
    +
    
    30
    +main :: IO ()
    
    31
    +main = do
    
    32
    +  setNumCapabilities 2
    
    33
    +  checkFlag
    
    34
    +    "TSO_STOP_NEXT_BREAKPOINT"
    
    35
    +    rts_enableStopNextBreakpoint
    
    36
    +    rts_disableStopNextBreakpoint
    
    37
    +    c_hasLocalStopNextBreakpoint
    
    38
    +  checkFlag
    
    39
    +    "TSO_STOP_AFTER_RETURN"
    
    40
    +    rts_enableStopAfterReturn
    
    41
    +    rts_disableStopAfterReturn
    
    42
    +    c_hasLocalStopAfterReturn
    
    43
    +
    
    44
    +checkFlag
    
    45
    +  :: String
    
    46
    +  -> (ThreadId# -> IO ())
    
    47
    +  -> (ThreadId# -> IO ())
    
    48
    +  -> IO CInt
    
    49
    +  -> IO ()
    
    50
    +checkFlag label enable disable isMyThreadFlagSet = do
    
    51
    +  -- Print the main thread's capability (should be 0)
    
    52
    +  print =<< threadCapability =<< myThreadId
    
    53
    +
    
    54
    +  -- Target thread will write its own flag value here
    
    55
    +  targetCheckVar <- newEmptyMVar
    
    56
    +
    
    57
    +  -- Run the new TSO runs on capability 1
    
    58
    +  ThreadId tid# <- forkOn 1 $ do
    
    59
    +    replicateM_ 2 $ do
    
    60
    +      replyVar <- takeMVar targetCheckVar
    
    61
    +      isSet <- (/= 0) <$> isMyThreadFlagSet
    
    62
    +      putMVar replyVar isSet
    
    63
    +
    
    64
    +  -- Enable the other TSO's flag
    
    65
    +  enable tid#
    
    66
    +  -- It will check whether it is set and reply here
    
    67
    +  renderCheck label "set" =<< checkTarget targetCheckVar
    
    68
    +
    
    69
    +  -- Ditto.
    
    70
    +  disable tid#
    
    71
    +  renderCheck label "unset" . not =<< checkTarget targetCheckVar
    
    72
    +
    
    73
    +checkTarget :: MVar (MVar Bool) -> IO Bool
    
    74
    +checkTarget targetCheckVar = do
    
    75
    +  replyVar <- newEmptyMVar
    
    76
    +  putMVar targetCheckVar replyVar
    
    77
    +  takeMVar replyVar
    
    78
    +
    
    79
    +renderCheck :: String -> String -> Bool -> IO ()
    
    80
    +renderCheck label state ok = putStrLn $
    
    81
    +  label ++ " " ++ state ++ ": " ++ if ok then "ok" else "failed"

  • testsuite/tests/rts/T27131.stdout
    1
    +(0,False)
    
    2
    +TSO_STOP_NEXT_BREAKPOINT set: ok
    
    3
    +TSO_STOP_NEXT_BREAKPOINT unset: ok
    
    4
    +(0,False)
    
    5
    +TSO_STOP_AFTER_RETURN set: ok
    
    6
    +TSO_STOP_AFTER_RETURN unset: ok

  • testsuite/tests/rts/T27131_c.c
    1
    +#include "Rts.h"
    
    2
    +
    
    3
    +int has_local_stop_next_breakpoint(void)
    
    4
    +{
    
    5
    +    CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
    
    6
    +    StgTSO *tso = cap->r.rCurrentTSO;
    
    7
    +    return (tso->flags & TSO_STOP_NEXT_BREAKPOINT) != 0;
    
    8
    +}
    
    9
    +
    
    10
    +int has_local_stop_after_return(void)
    
    11
    +{
    
    12
    +    CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
    
    13
    +    StgTSO *tso = cap->r.rCurrentTSO;
    
    14
    +    return (tso->flags & TSO_STOP_AFTER_RETURN) != 0;
    
    15
    +}

  • testsuite/tests/rts/all.T
    ... ... @@ -623,6 +623,12 @@ test('T20201b', [js_skip, exit_code(1)], compile_and_run, ['-with-rtsopts -A64z'
    623 623
     
    
    624 624
     test('T22012', [js_skip, extra_ways(['ghci'])], compile_and_run, ['T22012_c.c'])
    
    625 625
     
    
    626
    +test('T27131',
    
    627
    +     [ only_ways(['threaded1', 'threaded2'])
    
    628
    +     , req_ghc_with_threaded_rts
    
    629
    +     ],
    
    630
    +     compile_and_run, ['T27131_c.c'])
    
    631
    +
    
    626 632
     # Skip for JS platform as the JS RTS is always single threaded
    
    627 633
     test('T22795a', [only_ways(['normal']), js_skip, req_ghc_with_threaded_rts], compile_and_run, ['-threaded'])
    
    628 634
     test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-threaded'])
    

  • testsuite/tests/typecheck/should_fail/all.T
    ... ... @@ -720,7 +720,7 @@ test('T17940', normal, compile_fail, [''])
    720 720
     test('ErrorIndexLinks', normal, compile_fail, ['-fprint-error-index-links=always'])
    
    721 721
     test('T24064', normal, compile_fail, [''])
    
    722 722
     test('T24090a', normal, compile_fail, [''])
    
    723
    -test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 9.16
    
    723
    +test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 10.2 (#25911)
    
    724 724
     test('T24298', normal, compile_fail, [''])
    
    725 725
     test('T24279', normal, compile, [''])  # Now accepted (Nov 2025)
    
    726 726
     test('T24318', normal, compile_fail, [''])