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

Commits:

16 changed files:

Changes:

  • changelog.d/T27022
    1
    +section: compiler
    
    2
    +synopsis: Fix a divergence in the interaction between ``recover`` and ``putQ`` between the internal and external interpreter
    
    3
    +description: The ``recover`` method in TemplateHaskell now behaves the same 
    
    4
    +  with the internal and external interpreter.
    
    5
    +  In the past, when an error was encountered in a computation in a ``recover`` block,
    
    6
    +  the external interpreter would discard any state changes from ``putQ``,
    
    7
    +  whereas the internal interpreter would not.
    
    8
    +  This was a long-standing error in the implementation of the external interpreter.
    
    9
    +  Both now keep state changes from ``putQ`` in ``recover`` blocks.
    
    10
    +mrs: !15994
    
    11
    +issues: #27022

  • compiler/GHC/Unit/Module/Deps.hs
    ... ... @@ -96,7 +96,7 @@ data Dependencies = Deps
    96 96
        , dep_boot_mods_ :: Set (UnitId, ModuleNameWithIsBoot)
    
    97 97
           -- ^ All modules which have boot files below this one, and whether we
    
    98 98
           -- should use the boot file or not.
    
    99
    -      -- This information is only used to populate the eps_is_boot field.
    
    99
    +      -- This information is only used to populate the 'eps_is_boot' field.
    
    100 100
           -- See Note [Structure of dep_boot_mods]
    
    101 101
     
    
    102 102
        , dep_orphs_ :: [Module]
    
    ... ... @@ -605,7 +605,7 @@ hash of the module. The export hash is computed in `GHC.Iface.Recomp.addFingerpr
    605 605
     -}
    
    606 606
     
    
    607 607
     {-
    
    608
    -Note [Structure of dep_boot_deps]
    
    608
    +Note [Structure of dep_boot_mods]
    
    609 609
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    610 610
     
    
    611 611
     In `-c` mode we always need to know whether to load the normal or boot version of
    

  • hadrian/src/Settings/Packages.hs
    ... ... @@ -322,6 +322,7 @@ rtsPackageArgs = package rts ? do
    322 322
               , Profiling `wayUnit` way          ? arg "-DPROFILING"
    
    323 323
               , Threaded  `wayUnit` way          ? arg "-DTHREADED_RTS"
    
    324 324
               , notM targetSupportsSMP           ? arg "-optc-DNOSMP"
    
    325
    +          , isWinHost                        ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
    
    325 326
     
    
    326 327
                 -- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
    
    327 328
                 --
    

  • libraries/ghci/GHCi/TH.hs
    ... ... @@ -119,7 +119,7 @@ initQState :: Pipe -> QState
    119 119
     initQState p = QState M.empty Nothing p
    
    120 120
     
    
    121 121
     -- | The monad in which we run TH computations on the server
    
    122
    -newtype GHCiQ a = GHCiQ { runGHCiQ :: QState -> IO (a, QState) }
    
    122
    +newtype GHCiQ a = GHCiQ { runGHCiQ :: IORef QState -> IO a }
    
    123 123
     
    
    124 124
     -- | The exception thrown by "fail" in the GHCiQ monad
    
    125 125
     data GHCiQException = GHCiQException QState String
    
    ... ... @@ -128,52 +128,54 @@ data GHCiQException = GHCiQException QState String
    128 128
     instance Exception GHCiQException
    
    129 129
     
    
    130 130
     instance Functor GHCiQ where
    
    131
    -  fmap f (GHCiQ s) = GHCiQ $ fmap (\(x,s') -> (f x,s')) . s
    
    131
    +  fmap f (GHCiQ m) = GHCiQ $ fmap f . m
    
    132 132
     
    
    133 133
     instance Applicative GHCiQ where
    
    134 134
       f <*> a = GHCiQ $ \s ->
    
    135
    -    do (f',s')  <- runGHCiQ f s
    
    136
    -       (a',s'') <- runGHCiQ a s'
    
    137
    -       return (f' a', s'')
    
    138
    -  pure x = GHCiQ (\s -> return (x,s))
    
    135
    +    do f'  <- runGHCiQ f s
    
    136
    +       a' <- runGHCiQ a s
    
    137
    +       return $ f' a'
    
    138
    +  pure x = GHCiQ $ \_ -> return x
    
    139 139
     
    
    140 140
     instance Monad GHCiQ where
    
    141 141
       m >>= f = GHCiQ $ \s ->
    
    142
    -    do (m', s')  <- runGHCiQ m s
    
    143
    -       (a,  s'') <- runGHCiQ (f m') s'
    
    144
    -       return (a, s'')
    
    142
    +    do m'  <- runGHCiQ m s
    
    143
    +       a <- runGHCiQ (f m') s
    
    144
    +       return a
    
    145 145
     
    
    146 146
     instance MonadFail GHCiQ where
    
    147
    -  fail err  = GHCiQ $ \s -> throwIO (GHCiQException s err)
    
    147
    +  fail err  = GHCiQ $ \sRef -> readIORef sRef >>= \s -> throwIO (GHCiQException s err)
    
    148 148
     
    
    149 149
     getState :: GHCiQ QState
    
    150
    -getState = GHCiQ $ \s -> return (s,s)
    
    150
    +getState = GHCiQ $ \sRef -> readIORef sRef
    
    151 151
     
    
    152 152
     noLoc :: TH.Loc
    
    153 153
     noLoc = TH.Loc "<no file>" "<no package>" "<no module>" (0,0) (0,0)
    
    154 154
     
    
    155 155
     -- | Send a 'THMessage' to GHC and return the result.
    
    156 156
     ghcCmd :: Binary a => THMessage (THResult a) -> GHCiQ a
    
    157
    -ghcCmd m = GHCiQ $ \s -> do
    
    157
    +ghcCmd m = GHCiQ $ \sRef -> do
    
    158
    +  s <- readIORef sRef
    
    158 159
       r <- remoteTHCall (qsPipe s) m
    
    159 160
       case r of
    
    160 161
         THException str -> throwIO (GHCiQException s str)
    
    161
    -    THComplete res -> return (res, s)
    
    162
    +    THComplete res -> return res
    
    162 163
     
    
    163 164
     instance MonadIO GHCiQ where
    
    164
    -  liftIO m = GHCiQ $ \s -> fmap (,s) m
    
    165
    +  liftIO m = GHCiQ $ \_ -> m
    
    165 166
     
    
    166 167
     instance TH.Quasi GHCiQ where
    
    167 168
       qNewName str = ghcCmd (NewName str)
    
    168 169
       qReport isError msg = ghcCmd (Report isError msg)
    
    169 170
     
    
    170 171
       -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
    
    171
    -  qRecover (GHCiQ h) a = GHCiQ $ \s -> mask $ \unmask -> do
    
    172
    +  qRecover (GHCiQ h) a = GHCiQ $ \sRef -> mask $ \unmask -> do
    
    173
    +    s <- readIORef sRef
    
    172 174
         remoteTHCall (qsPipe s) StartRecover
    
    173
    -    e <- try $ unmask $ runGHCiQ (a <* ghcCmd FailIfErrs) s
    
    175
    +    e <- try $ unmask $ runGHCiQ (a <* ghcCmd FailIfErrs) sRef
    
    174 176
         remoteTHCall (qsPipe s) (EndRecover (isLeft e))
    
    175 177
         case e of
    
    176
    -      Left GHCiQException{} -> h s
    
    178
    +      Left GHCiQException{} -> h sRef
    
    177 179
           Right r -> return r
    
    178 180
       qLookupName isType occ = ghcCmd (LookupName isType occ)
    
    179 181
       qReify name = ghcCmd (Reify name)
    
    ... ... @@ -200,15 +202,16 @@ instance TH.Quasi GHCiQ where
    200 202
       qAddTempFile suffix = ghcCmd (AddTempFile suffix)
    
    201 203
       qAddTopDecls decls = ghcCmd (AddTopDecls decls)
    
    202 204
       qAddForeignFilePath lang fp = ghcCmd (AddForeignFilePath lang fp)
    
    203
    -  qAddModFinalizer fin = GHCiQ (\s -> mkRemoteRef fin >>= return . (, s)) >>=
    
    205
    +  qAddModFinalizer fin = GHCiQ (\_ -> mkRemoteRef fin) >>=
    
    204 206
                              ghcCmd . AddModFinalizer
    
    205 207
       qAddCorePlugin str = ghcCmd (AddCorePlugin str)
    
    206
    -  qGetQ = GHCiQ $ \s ->
    
    208
    +  qGetQ = do
    
    209
    +    s <- getState
    
    207 210
         let lookup :: forall a. Typeable a => Map TypeRep Dynamic -> Maybe a
    
    208 211
             lookup m = fromDynamic =<< M.lookup (typeOf (undefined::a)) m
    
    209
    -    in return (lookup (qsMap s), s)
    
    210
    -  qPutQ k = GHCiQ $ \s ->
    
    211
    -    return ((), s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
    
    212
    +    return $ lookup (qsMap s)
    
    213
    +  qPutQ k = GHCiQ $ \sRef ->
    
    214
    +    modifyIORef' sRef (\s -> s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
    
    212 215
       qIsExtEnabled x = ghcCmd (IsExtEnabled x)
    
    213 216
       qExtsEnabled = ghcCmd ExtsEnabled
    
    214 217
       qPutDoc l s = ghcCmd (PutDoc l s)
    
    ... ... @@ -231,7 +234,8 @@ runModFinalizerRefs pipe rstate qrefs = do
    231 234
       qs <- mapM localRef qrefs
    
    232 235
       qstateref <- localRef rstate
    
    233 236
       qstate <- readIORef qstateref
    
    234
    -  _ <- runGHCiQ (TH.runQ $ sequence_ qs) qstate { qsPipe = pipe }
    
    237
    +  qstate' <- newIORef $ qstate { qsPipe = pipe }
    
    238
    +  _ <- runGHCiQ (TH.runQ $ sequence_ qs) qstate'
    
    235 239
       return ()
    
    236 240
     
    
    237 241
     -- | The implementation of the 'RunTH' message
    
    ... ... @@ -267,8 +271,6 @@ runTHQ
    267 271
       -> IO ByteString
    
    268 272
     runTHQ pipe rstate mb_loc ghciq = do
    
    269 273
       qstateref <- localRef rstate
    
    270
    -  qstate <- readIORef qstateref
    
    271
    -  let st = qstate { qsLocation = mb_loc, qsPipe = pipe }
    
    272
    -  (r,new_state) <- runGHCiQ (TH.runQ ghciq) st
    
    273
    -  writeIORef qstateref new_state
    
    274
    +  modifyIORef' qstateref (\qstate -> qstate { qsLocation = mb_loc, qsPipe = pipe })
    
    275
    +  r <- runGHCiQ (TH.runQ ghciq) qstateref
    
    274 276
       return $! LB.toStrict (runPut (put r))

  • rts/IOManager.h
    ... ... @@ -21,6 +21,15 @@
    21 21
     
    
    22 22
     #include "sm/GC.h" // for evac_fn
    
    23 23
     
    
    24
    +#if defined(mingw32_HOST_OS)
    
    25
    +/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
    
    26
    + * to be shared with the I/O code in the base library to tell us which style
    
    27
    + * of I/O manager we are using: one that uses the Windows native API HANDLEs,
    
    28
    + * or one that uses Posix style fds.
    
    29
    + */
    
    30
    +extern bool rts_IOManagerIsWin32Native;
    
    31
    +#endif
    
    32
    +
    
    24 33
     #include "BeginPrivate.h"
    
    25 34
     
    
    26 35
     /* The ./configure gives us a set of CPP flags, one for each named I/O manager:
    
    ... ... @@ -160,14 +169,6 @@ typedef enum {
    160 169
     /* Global var to tell us which I/O manager impl we are using */
    
    161 170
     extern IOManagerType iomgr_type;
    
    162 171
     
    
    163
    -#if defined(mingw32_HOST_OS)
    
    164
    -/* Global var (only on Windows) that is exported to be shared with the I/O code
    
    165
    - * in the base library to tell us which style of I/O manager we are using: one
    
    166
    - * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
    
    167
    - */
    
    168
    -extern bool rts_IOManagerIsWin32Native;
    
    169
    -#endif
    
    170
    -
    
    171 172
     
    
    172 173
     /* The CapIOManager is the per-capability data structure belonging to the I/O
    
    173 174
      * manager. It is defined in full in IOManagerInternals.h. The opaque forward
    

  • rts/Linker.c
    ... ... @@ -478,16 +478,7 @@ initLinker_ (int retain_cafs)
    478 478
         symhash = allocStrHashTable();
    
    479 479
     
    
    480 480
         /* populate the symbol table with stuff from the RTS */
    
    481
    -    IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
    
    482
    -    for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
    
    483
    -        IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    484
    -        if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    485
    -                                    symhash, sym->lbl, sym->addr,
    
    486
    -                                    sym->strength, sym->type, 0, NULL)) {
    
    487
    -            barf("ghciInsertSymbolTable failed");
    
    488
    -        }
    
    489
    -    }
    
    490
    -    IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
    
    481
    +    initLinkerRtsSyms(symhash);
    
    491 482
     
    
    492 483
         /* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
    
    493 484
          * that can be overrided by linking in an object with a corresponding
    

  • rts/LinkerInternals.h
    ... ... @@ -502,4 +502,6 @@ ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
    502 502
     void initSegment(Segment *s, void *start, size_t size, SegmentProt prot, int n_sections);
    
    503 503
     void freeSegments(ObjectCode *oc);
    
    504 504
     
    
    505
    +void initLinkerRtsSyms(StrHashTable *symhash);
    
    506
    +
    
    505 507
     #include "EndPrivate.h"

  • rts/RtsSymbols.c
    ... ... @@ -9,6 +9,8 @@
    9 9
     #include "ghcplatform.h"
    
    10 10
     #include "Rts.h"
    
    11 11
     #include "RtsSymbols.h"
    
    12
    +#include "LinkerInternals.h"
    
    13
    +#include "PathUtils.h"
    
    12 14
     
    
    13 15
     #include "TopHandler.h"
    
    14 16
     #include "HsFFI.h"
    
    ... ... @@ -51,6 +53,20 @@ extern char **environ;
    51 53
     
    
    52 54
     /* -----------------------------------------------------------------------------
    
    53 55
      * Symbols to be inserted into the RTS symbol table.
    
    56
    + *
    
    57
    + * Note [Naming Scheme for Symbol Macros]
    
    58
    + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    59
    + *
    
    60
    + * SymI_*: symbol is internal to the RTS. It resides in an object
    
    61
    + *         file/library that is linked into the RTS library (as a static
    
    62
    + *         archive or dynamic shared library).
    
    63
    + * SymE_*: symbol is external to the RTS library. It might be linked
    
    64
    + *         dynamically.
    
    65
    + *
    
    66
    + * Sym*_HasProto  : the symbol prototype is imported in an include file
    
    67
    + *                  or defined explicitly
    
    68
    + * Sym*_NeedsProto: the symbol is undefined and we add a dummy
    
    69
    + *                  default proto extern void sym(void);
    
    54 70
      */
    
    55 71
     
    
    56 72
     #define Maybe_Stable_Names      SymI_HasProto(stg_mkWeakzh)                   \
    
    ... ... @@ -162,7 +178,7 @@ extern char **environ;
    162 178
           SymI_HasProto(stg_asyncWritezh)                    \
    
    163 179
           SymI_HasProto(stg_asyncDoProczh)                   \
    
    164 180
           SymI_HasProto(rts_InstallConsoleEvent)             \
    
    165
    -      SymI_HasProto(rts_IOManagerIsWin32Native)          \
    
    181
    +      SymI_HasDataProto(rts_IOManagerIsWin32Native)          \
    
    166 182
           SymI_HasProto(rts_ConsoleHandlerDone)              \
    
    167 183
           SymI_NeedsProto(__mingw_module_is_dll)             \
    
    168 184
           RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms))      \
    
    ... ... @@ -914,7 +930,7 @@ extern char **environ;
    914 930
           SymI_HasProto(freeExecPage)                                       \
    
    915 931
           SymI_HasProto(getAllocations)                                     \
    
    916 932
           SymI_HasProto(revertCAFs)                                         \
    
    917
    -      SymI_HasProto(RtsFlags)                                           \
    
    933
    +      SymI_HasDataProto(RtsFlags)                                           \
    
    918 934
           SymI_NeedsDataProto(rts_breakpoint_io_action)                     \
    
    919 935
           SymI_NeedsDataProto(rts_stop_next_breakpoint)                     \
    
    920 936
           SymI_NeedsDataProto(rts_stop_on_exception)                        \
    
    ... ... @@ -925,9 +941,9 @@ extern char **environ;
    925 941
           SymI_NeedsProto(rts_enableStopAfterReturn)                        \
    
    926 942
           SymI_NeedsProto(rts_disableStopAfterReturn)                       \
    
    927 943
           SymI_HasProto(stopTimer)                                          \
    
    928
    -      SymI_HasProto(n_capabilities)                                     \
    
    929
    -      SymI_HasProto(max_n_capabilities)                                 \
    
    930
    -      SymI_HasProto(enabled_capabilities)                               \
    
    944
    +      SymI_HasDataProto(n_capabilities)                                     \
    
    945
    +      SymI_HasDataProto(max_n_capabilities)                                 \
    
    946
    +      SymI_HasDataProto(enabled_capabilities)                               \
    
    931 947
           SymI_HasDataProto(stg_traceEventzh)                                   \
    
    932 948
           SymI_HasDataProto(stg_traceMarkerzh)                                  \
    
    933 949
           SymI_HasDataProto(stg_traceBinaryEventzh)                             \
    
    ... ... @@ -1145,12 +1161,27 @@ extern char **environ;
    1145 1161
           SymI_HasProto(hs_word2float64)
    
    1146 1162
     
    
    1147 1163
     
    
    1148
    -/* entirely bogus claims about types of these symbols */
    
    1149
    -#define SymI_NeedsProto(vvv)  extern void vvv(void);
    
    1150
    -#define SymI_NeedsDataProto(vvv)  extern StgWord vvv[];
    
    1151
    -#define SymE_NeedsProto(vvv)  SymI_NeedsProto(vvv);
    
    1152
    -#define SymE_NeedsDataProto(vvv)  SymI_NeedsDataProto(vvv);
    
    1153
    -#define SymE_HasProto(vvv)    SymI_HasProto(vvv);
    
    1164
    +/* Declare prototypes for the symbols that need it, so we can refer
    
    1165
    + * to them in the rtsSyms table below.
    
    1166
    + *
    
    1167
    + * In particular, for the external ones (SymE_*) we use the dllimport attribute
    
    1168
    + * to indicate that (on Windows) they come from external DLLs. This attribute
    
    1169
    + * is ignored on other platforms.
    
    1170
    + *
    
    1171
    + * The claims about the types of these symbols are entirely bogus.
    
    1172
    + */
    
    1173
    +#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
    
    1174
    +#define DLLIMPORT __attribute__((dllimport))
    
    1175
    +#else
    
    1176
    +#define DLLIMPORT /**/
    
    1177
    +#endif
    
    1178
    +
    
    1179
    +#define SymI_NeedsProto(vvv)      extern           void vvv(void);
    
    1180
    +#define SymI_NeedsDataProto(vvv)  extern           StgWord vvv[];
    
    1181
    +#define SymE_NeedsProto(vvv)      extern DLLIMPORT void vvv(void);
    
    1182
    +#define SymE_NeedsDataProto(vvv)  extern DLLIMPORT StgWord vvv[];
    
    1183
    +
    
    1184
    +#define SymE_HasProto(vvv) /**/
    
    1154 1185
     #define SymI_HasProto(vvv) /**/
    
    1155 1186
     #define SymI_HasDataProto(vvv) /**/
    
    1156 1187
     #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
    
    ... ... @@ -1179,6 +1210,8 @@ RTS_SYMBOLS_PRIM
    1179 1210
     #undef SymE_NeedsProto
    
    1180 1211
     #undef SymE_NeedsDataProto
    
    1181 1212
     
    
    1213
    +/* See Note [Naming Scheme for Symbol Macros] */
    
    1214
    +
    
    1182 1215
     #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
    
    1183 1216
                         (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
    
    1184 1217
     #define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
    
    ... ... @@ -1199,7 +1232,16 @@ RTS_SYMBOLS_PRIM
    1199 1232
         { MAYBE_LEADING_UNDERSCORE_STR(#vvv),    \
    
    1200 1233
           (void*)(&(xxx)), strength, ty },
    
    1201 1234
     
    
    1202
    -RtsSymbolVal rtsSyms[] = {
    
    1235
    +
    
    1236
    +
    
    1237
    +/* Initialize (if not already initialized) and return an array of symbols with stuff from the RTS. */
    
    1238
    +void initLinkerRtsSyms (StrHashTable *symhash) {
    
    1239
    +    /* The address of data symbols with the dllimport attribute are not
    
    1240
    +     * compile-time constants and so cannot be used in constant initialisers.
    
    1241
    +     * For this reason, rtsSyms is a local variable within this function
    
    1242
    +     * rather than a global constant (as it was historically).
    
    1243
    +     */
    
    1244
    +    const RtsSymbolVal rtsSyms[] = {
    
    1203 1245
           RTS_SYMBOLS
    
    1204 1246
           RTS_RET_SYMBOLS
    
    1205 1247
           RTS_POSIX_ONLY_SYMBOLS
    
    ... ... @@ -1214,7 +1256,20 @@ RtsSymbolVal rtsSyms[] = {
    1214 1256
           RTS_SYMBOLS_PRIM
    
    1215 1257
           SymI_HasDataProto(nonmoving_write_barrier_enabled)
    
    1216 1258
           { 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
    
    1217
    -};
    
    1259
    +    };
    
    1260
    +
    
    1261
    +    IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
    
    1262
    +    for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
    
    1263
    +        IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    1264
    +        if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    1265
    +                                    symhash, sym->lbl, sym->addr,
    
    1266
    +                                    sym->strength, sym->type, 0, NULL)) {
    
    1267
    +            barf("ghciInsertSymbolTable failed");
    
    1268
    +        }
    
    1269
    +    }
    
    1270
    +    IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
    
    1271
    +}
    
    1272
    +
    
    1218 1273
     
    
    1219 1274
     
    
    1220 1275
     // Note [Extra RTS symbols]
    

  • rts/RtsSymbols.h
    ... ... @@ -46,8 +46,6 @@ typedef struct _RtsSymbolVal {
    46 46
         SymType type;
    
    47 47
     } RtsSymbolVal;
    
    48 48
     
    
    49
    -extern RtsSymbolVal rtsSyms[];
    
    50
    -
    
    51 49
     extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
    
    52 50
     
    
    53 51
     /* See Note [_iob_func symbol].  */
    

  • rts/linker/Elf.c
    ... ... @@ -76,18 +76,6 @@
    76 76
      *
    
    77 77
      * See bug #781
    
    78 78
      * See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
    
    79
    - *
    
    80
    - * Naming Scheme for Symbol Macros
    
    81
    - *
    
    82
    - * SymI_*: symbol is internal to the RTS. It resides in an object
    
    83
    - *         file/library that is statically.
    
    84
    - * SymE_*: symbol is external to the RTS library. It might be linked
    
    85
    - *         dynamically.
    
    86
    - *
    
    87
    - * Sym*_HasProto  : the symbol prototype is imported in an include file
    
    88
    - *                  or defined explicitly
    
    89
    - * Sym*_NeedsProto: the symbol is undefined and we add a dummy
    
    90
    - *                  default proto extern void sym(void);
    
    91 79
      */
    
    92 80
     #define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
    
    93 81
     
    

  • testsuite/tests/MiniQuickCheck.hs
    ... ... @@ -2,6 +2,7 @@
    2 2
     {-# LANGUAGE DerivingStrategies         #-}
    
    3 3
     {-# LANGUAGE GeneralisedNewtypeDeriving #-}
    
    4 4
     {-# LANGUAGE RecordWildCards            #-}
    
    5
    +{-# LANGUAGE TypeApplications           #-}
    
    5 6
     {-# LANGUAGE TypeFamilies               #-}
    
    6 7
     
    
    7 8
     -- | A minimal QuickCheck-like property testing framework for use in the GHC
    
    ... ... @@ -52,6 +53,8 @@ module MiniQuickCheck
    52 53
       ) where
    
    53 54
     
    
    54 55
     -- base
    
    56
    +import Control.Exception
    
    57
    +  ( SomeException, displayException, evaluate, try )
    
    55 58
     import Control.Monad.IO.Class
    
    56 59
       ( liftIO )
    
    57 60
     import Data.Bits
    
    ... ... @@ -181,16 +184,39 @@ nest :: String -> ReaderT RunS IO a -> ReaderT RunS IO a
    181 184
     nest c = local (\s -> s { depth = depth s + 1, context = c : context s })
    
    182 185
     
    
    183 186
     runPropertyCheck :: PropertyCheck -> ReaderT RunS IO Result
    
    184
    -runPropertyCheck (PropertyBinaryOp ok desc s1 s2) =
    
    185
    -  if ok
    
    186
    -    then return Success
    
    187
    -    else do
    
    188
    -      ctx <- context <$> ask
    
    189
    -      let msg = "Failure: " ++ s1 ++ " " ++ desc ++ " " ++ s2
    
    190
    -      putMsg msg
    
    191
    -      return (Failure [msg : ctx])
    
    192
    -runPropertyCheck (PropertyAnd a b) =
    
    193
    -  (<>) <$> runPropertyCheck a <*> runPropertyCheck b
    
    187
    +runPropertyCheck pcThunk = do
    
    188
    +  -- See Note [Catching exceptions in property evaluation].
    
    189
    +  pcRes <- liftIO $ try @SomeException (evaluate pcThunk)
    
    190
    +  case pcRes of
    
    191
    +    Left  e -> reportFailure ("Failure: exception: " ++ displayException e)
    
    192
    +    Right (PropertyAnd a b) ->
    
    193
    +      (<>) <$> runPropertyCheck a <*> runPropertyCheck b
    
    194
    +    Right (PropertyBinaryOp ok desc s1 s2) -> do
    
    195
    +      okRes <- liftIO $ try @SomeException (evaluate ok)
    
    196
    +      case okRes of
    
    197
    +        Right True  -> return Success
    
    198
    +        Right False -> reportFailure ("Failure: " ++ s1 ++ " " ++ desc ++ " " ++ s2)
    
    199
    +        Left  e     -> reportFailure ("Failure: exception: " ++ displayException e)
    
    200
    +
    
    201
    +reportFailure :: String -> ReaderT RunS IO Result
    
    202
    +reportFailure msg = do
    
    203
    +  ctx <- context <$> ask
    
    204
    +  putMsg msg
    
    205
    +  return (Failure [msg : ctx])
    
    206
    +
    
    207
    +-- Note [Catching exceptions in property evaluation]
    
    208
    +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    209
    +-- A property like `\a b -> let !r = a `div` 0 in r === b` builds a
    
    210
    +-- `PropertyCheck` thunk whose forcing raises an exception -- in this case
    
    211
    +-- already at the `PropertyBinaryOp` constructor, before its `ok` field is
    
    212
    +-- ever inspected. Other properties may force `ok = (s1 == s2)` instead and
    
    213
    +-- raise from there.
    
    214
    +--
    
    215
    +-- To handle both, we `evaluate` first the `PropertyCheck` thunk and then
    
    216
    +-- the `ok` field, each inside `try`, and report any exception through the
    
    217
    +-- normal `reportFailure` path. The surrounding loop then still prints
    
    218
    +-- "With arguments ... (Seed: ...)" and the test driver continues with
    
    219
    +-- subsequent properties instead of aborting.
    
    194 220
     
    
    195 221
     runProperty :: Iterations -> Property -> ReaderT RunS IO Result
    
    196 222
     runProperty (Iterations iters) (Prop p) = do
    

  • testsuite/tests/linters/notes.stdout
    ... ... @@ -27,7 +27,6 @@ ref compiler/GHC/Tc/Solver/Rewrite.hs:1020:7: Note [Stability of rewritin
    27 27
     ref    compiler/GHC/Tc/TyCl.hs:1662:6:     Note [Unification variables need fresh Names]
    
    28 28
     ref    compiler/GHC/Tc/Types/Constraint.hs:209:9:     Note [NonCanonical Semantics]
    
    29 29
     ref    compiler/GHC/Types/Demand.hs:304:25:     Note [Preserving Boxity of results is rarely a win]
    
    30
    -ref    compiler/GHC/Unit/Module/Deps.hs:97:13:     Note [Structure of dep_boot_mods]
    
    31 30
     ref    compiler/GHC/Utils/Monad.hs:415:34:     Note [multiShotIO]
    
    32 31
     ref    compiler/Language/Haskell/Syntax/Binds.hs:206:31:     Note [fun_id in Match]
    
    33 32
     ref    configure.ac:205:10:     Note [Linking ghc-bin against threaded stage0 RTS]
    

  • testsuite/tests/numeric/should_run/foundation.hs
    ... ... @@ -77,13 +77,42 @@ testMultiplicative _ = Group "Multiplicative"
    77 77
         , Property "a * b == Integer(a) * Integer(b)" $ \(a :: a) (b :: a) -> a * b === fromInteger (toInteger a * toInteger b)
    
    78 78
         ]
    
    79 79
     
    
    80
    -testDividible :: forall a . (Show a, Eq a, Integral a, Num a, Arbitrary a, Typeable a)
    
    80
    +-- | Divisibility test for Bounded Integral types (Int, Int{8,16,32,64},
    
    81
    +-- Word, Word{8,16,32,64}).
    
    82
    +testDivisible :: forall a . (Show a, Eq a, Bounded a, Integral a, Num a, Arbitrary a, Typeable a)
    
    81 83
                   => Proxy a -> Test
    
    82
    -testDividible _ = Group "Divisible"
    
    84
    +testDivisible _ = Group "Divisible"
    
    85
    +    [ Property "(x `div` y) * y + (x `mod` y) == x" $ \(a :: a) (NonZero b) ->
    
    86
    +            -- See Note [Skipping minBound `div` (-1)].
    
    87
    +            if (minBound :: a) < 0 && a == minBound && b == (-1)
    
    88
    +              then True === True
    
    89
    +              else a === (a `div` b) * b + (a `mod` b)
    
    90
    +    ]
    
    91
    +
    
    92
    +-- | Divisibility test for unbounded Integral types (Integer). No overflow
    
    93
    +-- can occur here, so the property holds without exception for all NonZero b.
    
    94
    +testDivisibleUnbounded :: forall a . (Show a, Eq a, Integral a, Num a, Arbitrary a, Typeable a)
    
    95
    +                       => Proxy a -> Test
    
    96
    +testDivisibleUnbounded _ = Group "Divisible"
    
    83 97
         [ Property "(x `div` y) * y + (x `mod` y) == x" $ \(a :: a) (NonZero b) ->
    
    84 98
                 a === (a `div` b) * b + (a `mod` b)
    
    85 99
         ]
    
    86 100
     
    
    101
    +-- Note [Skipping minBound `div` (-1)]
    
    102
    +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    103
    +-- For a fixed-width *signed* Integral type, `minBound `div` (-1)` raises
    
    104
    +-- ArithException(Overflow) because `-minBound` is not representable in the
    
    105
    +-- type (e.g., for Int8, `-(-128)` would be 128, out of range). The div/mod
    
    106
    +-- identity property cannot hold there, so we skip exactly that one pair.
    
    107
    +--
    
    108
    +-- We detect "signed Bounded" with `(minBound :: a) < 0`: True for Int{N},
    
    109
    +-- False for Word{N}. This way unsigned Bounded types lose no coverage,
    
    110
    +-- and only the genuine overflow sample is skipped for signed types.
    
    111
    +--
    
    112
    +-- For the unbounded `Integer`, no overflow can occur and we use a separate
    
    113
    +-- 'testDivisibleUnbounded' (without the Bounded constraint or the skip).
    
    114
    +-- See #27222.
    
    115
    +
    
    87 116
     testOperatorPrecedence :: forall a . (Show a, Eq a, Prelude.Num a, Integral a, Num a,  Arbitrary a, Typeable a)
    
    88 117
                            => Proxy a -> Test
    
    89 118
     testOperatorPrecedence _ = Group "Precedence"
    
    ... ... @@ -101,14 +130,26 @@ testOperatorPrecedence _ = Group "Precedence"
    101 130
         ]
    
    102 131
     
    
    103 132
     
    
    104
    -testNumber :: (Show a, Eq a, Prelude.Num a, Integral a, Num a, Arbitrary a, Typeable a)
    
    133
    +testNumber :: (Show a, Eq a, Prelude.Num a, Bounded a, Integral a, Num a, Arbitrary a, Typeable a)
    
    105 134
                => String -> Proxy a -> Test
    
    106 135
     testNumber name proxy = Group name
    
    107 136
         [ testIntegral proxy
    
    108 137
         , testEqOrd proxy
    
    109 138
         , testAdditive proxy
    
    110 139
         , testMultiplicative proxy
    
    111
    -    , testDividible proxy
    
    140
    +    , testDivisible proxy
    
    141
    +    , testOperatorPrecedence proxy
    
    142
    +    ]
    
    143
    +
    
    144
    +-- | Variant of 'testNumber' for unbounded Integral types (e.g., Integer).
    
    145
    +testNumberUnbounded :: (Show a, Eq a, Prelude.Num a, Integral a, Num a, Arbitrary a, Typeable a)
    
    146
    +                    => String -> Proxy a -> Test
    
    147
    +testNumberUnbounded name proxy = Group name
    
    148
    +    [ testIntegral proxy
    
    149
    +    , testEqOrd proxy
    
    150
    +    , testAdditive proxy
    
    151
    +    , testMultiplicative proxy
    
    152
    +    , testDivisibleUnbounded proxy
    
    112 153
         , testOperatorPrecedence proxy
    
    113 154
         ]
    
    114 155
     
    
    ... ... @@ -119,7 +160,7 @@ testNumberRefs = Group "ALL"
    119 160
         , testNumber "Int16" (Proxy :: Proxy Int16)
    
    120 161
         , testNumber "Int32" (Proxy :: Proxy Int32)
    
    121 162
         , testNumber "Int64" (Proxy :: Proxy Int64)
    
    122
    -    , testNumber "Integer" (Proxy :: Proxy Integer)
    
    163
    +    , testNumberUnbounded "Integer" (Proxy :: Proxy Integer)
    
    123 164
         , testNumber "Word" (Proxy :: Proxy Word)
    
    124 165
         , testNumber "Word8" (Proxy :: Proxy Word8)
    
    125 166
         , testNumber "Word16" (Proxy :: Proxy Word16)
    
    ... ... @@ -399,7 +440,7 @@ testPrimops = Group "primop"
    399 440
       , testPrimop "-#" (Primop.-#) (Wrapper.-#)
    
    400 441
       , testPrimop "*#" (Primop.*#) (Wrapper.*#)
    
    401 442
       , testPrimop "timesInt2#" Primop.timesInt2# Wrapper.timesInt2#
    
    402
    -  , testPrimop "mulIntMayOflo#" Primop.mulIntMayOflo# Wrapper.mulIntMayOflo#
    
    443
    +  , testPrimopMayOflo "mulIntMayOflo#" Primop.mulIntMayOflo# Wrapper.mulIntMayOflo#
    
    403 444
       , testPrimopDivLike "quotInt#" Primop.quotInt# Wrapper.quotInt#
    
    404 445
       , testPrimopDivLike "remInt#" Primop.remInt# Wrapper.remInt#
    
    405 446
       , testPrimopDivLike "quotRemInt#" Primop.quotRemInt# Wrapper.quotRemInt#
    
    ... ... @@ -497,6 +538,31 @@ instance TestPrimop (Int# -> Int# -> Int#) where
    497 538
       testPrimopDivLike s l r = Property s $ twoNonZero $ \ (uInt#-> x0) (uInt#-> x1) -> wInt# (l x0 x1) === wInt# (r x0 x1)
    
    498 539
       testPrimopShift s l r = Property s $ \ (uInt#-> x0) (BoundedShiftAmount @Int shift) -> wInt# (l x0 (uInt# shift)) === wInt# (r x0 (uInt# shift))
    
    499 540
     
    
    541
    +-- | Compare two 'mulIntMayOflo#'-like primops only on whether their result
    
    542
    +-- is zero. See Note [Comparing mulIntMayOflo# results].
    
    543
    +testPrimopMayOflo :: String
    
    544
    +                  -> (Int# -> Int# -> Int#)
    
    545
    +                  -> (Int# -> Int# -> Int#)
    
    546
    +                  -> Test
    
    547
    +testPrimopMayOflo s l r =
    
    548
    +    Property s $ \ (uInt# -> x0) (uInt# -> x1) ->
    
    549
    +        (wInt# (l x0 x1) == 0) === (wInt# (r x0 x1) == 0)
    
    550
    +
    
    551
    +-- Note [Comparing mulIntMayOflo# results]
    
    552
    +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    553
    +-- The 'mulIntMayOflo#' primop is only specified to return 0 if the signed
    
    554
    +-- multiplication does not overflow, and a non-zero value if it /may/
    
    555
    +-- overflow (see Note [MO_S_MulMayOflo significant width] in
    
    556
    +-- GHC.Cmm.MachOp). The exact non-zero value is unspecified and legitimately
    
    557
    +-- differs between backends and between inlined vs. non-inlined call sites
    
    558
    +-- (e.g., the LLVM backend's `isSMulOK` returns `sext_signbit(low) - high`,
    
    559
    +-- which is some arbitrary non-zero word on overflow).
    
    560
    +--
    
    561
    +-- Comparing the raw Int# results bit-for-bit is therefore too strict and
    
    562
    +-- causes spurious test failures whenever the random arguments happen to
    
    563
    +-- overflow. We compare zero/non-zero instead, which matches the spec.
    
    564
    +-- See #27222.
    
    565
    +
    
    500 566
     instance TestPrimop (Int# -> Int# -> (# Int#,Int# #)) where
    
    501 567
       testPrimop s l r = Property s $ \ (uInt#-> x0) (uInt#-> x1) -> WTUP2(wInt#,wInt#, (l x0 x1)) === WTUP2(wInt#,wInt#, (r x0 x1))
    
    502 568
       testPrimopDivLike s l r = Property s $ twoNonZero $ \ (uInt#-> x0) (uInt#-> x1) -> WTUP2(wInt#,wInt#, (l x0 x1)) === WTUP2(wInt#,wInt#, (r x0 x1))
    

  • testsuite/tests/th/T27022.hs
    1
    +{-# LANGUAGE TemplateHaskell #-}
    
    2
    +-- | This tests the behaviour of TH's recover method.
    
    3
    +-- It should behave the same in the internal and external interperter.
    
    4
    +-- In the past, they have diverged, and the external interpreter would roll back the state of putQ/getQ whereas the internal interpreter would not.
    
    5
    +module Main where
    
    6
    +
    
    7
    +import Language.Haskell.TH.Syntax
    
    8
    +main = print $(putQ "0" >> recover (pure ()) (putQ "42" >> fail "oops")  >> getQ @String >>= lift )

  • testsuite/tests/th/T27022.stdout
    1
    +Just "42"

  • testsuite/tests/th/all.T
    ... ... @@ -650,3 +650,4 @@ test('GadtConSigs_th_dump1', normal, compile, ['-v0 -ddump-splices -dsuppress-un
    650 650
     test('T26099', normal, compile_fail, [''])
    
    651 651
     test('T8306_th', only_ways(['ghci']), ghci_script, ['T8306_th.script'])
    
    652 652
     test('T26862_th', only_ways(['ghci']), ghci_script, ['T26862_th.script'])
    
    653
    +test('T27022', normal, compile_and_run, [''])