[Git][ghc/ghc][wip/andreask/cbv_array] Add strict array read/write primops.
by Andreas Klebinger (@AndreasK) 09 Nov '25
by Andreas Klebinger (@AndreasK) 09 Nov '25
09 Nov '25
Andreas Klebinger pushed to branch wip/andreask/cbv_array at Glasgow Haskell Compiler / GHC
Commits:
471d9a01 by Andreas Klebinger at 2025-11-09T17:32:56+01:00
Add strict array read/write primops.
Those will enfore argument evaluation using the EPT mechanism for writes.
For reads the compiler has knowledge that those are evaluated references
allowing us to skip eval checks.
- - - - -
17 changed files:
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/Setup.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Lint.hs
- hadrian/src/Settings/Builders/GenPrimopCode.hs
- utils/genprimopcode/Lexer.x
- utils/genprimopcode/Main.hs
- utils/genprimopcode/Parser.y
- utils/genprimopcode/ParserM.hs
- utils/genprimopcode/Syntax.hs
Changes:
=====================================
compiler/GHC/Builtin/PrimOps.hs
=====================================
@@ -9,7 +9,7 @@
module GHC.Builtin.PrimOps (
PrimOp(..), PrimOpVecCat(..), allThePrimOps,
- primOpType, primOpSig, primOpResultType,
+ primOpType, primOpSig, primOpResultType, primOpCbv,
primOpTag, maxPrimOpTag, primOpOcc,
primOpWrapperId,
pprPrimOp,
@@ -146,6 +146,22 @@ primOpStrictness :: PrimOp -> Arity -> DmdSig
-- this function isn't exported.
#include "primop-strictness.hs-incl"
+{-
+************************************************************************
+* *
+\subsubsection{Call by value info}
+* *
+************************************************************************
+
+Some primops require us to only pass evaluated and properly tagged
+pointers for boxed arguments.
+
+See Note [Evaluated and Properly Tagged]
+-}
+
+primOpCbv :: PrimOp -> [CbvMark]
+#include "primop-cbv.hs-incl"
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Builtin/primops.txt.pp
=====================================
@@ -150,6 +150,7 @@ defaults
div_like = False -- Second argument expected to be non zero - used for tests
shift_like = False -- Second argument expected to be atmost first argument's word size -1 - used for tests
defined_bits = Nothing -- The number of bits the operation is defined for (if not all bits)
+ cbv_marks = []
-- Note [When do out-of-line primops go in primops.txt.pp]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1621,6 +1622,28 @@ primop ReadArrayOp "readArray#" GenPrimOp
effect = ReadWriteEffect
can_fail_warning = YesWarnCanFail
+primop ReadStrictArrayOp "unsafeReadStrictArray#" GenPrimOp
+ MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
+ {Read from specified index of mutable array. Result is evaluated.
+
+ GHC will assume the value at the given index has been written
+ by writeStrictArray#. This can allow GHC to elid an eval check when using the
+ read value. Potentially given a performance benefit.
+
+ WARNING: Behaviour is undefined if the value read
+ was not written using writeStrictArray#.
+
+ At runtime "strict" arrays and regular arrays have the same representation.
+ The only difference is in the read/write operations.
+
+ The strict write operations ensure stored values are evaluated and properly
+ tagged. Strict reads assume this fact, allowing GHC to sometimes avoid
+ checking for thunks when using the read value.
+ }
+ with
+ effect = ReadWriteEffect
+ can_fail_warning = YesWarnCanFail
+
primop WriteArrayOp "writeArray#" GenPrimOp
MutableArray# s a_levpoly -> Int# -> a_levpoly -> State# s -> State# s
{Write to specified index of mutable array.}
@@ -1629,6 +1652,15 @@ primop WriteArrayOp "writeArray#" GenPrimOp
can_fail_warning = YesWarnCanFail
code_size = 2 -- card update too
+primop WriteStrictArrayOp "writeStrictArray#" GenPrimOp
+ MutableArray# s a_levpoly -> Int# -> a_levpoly -> State# s -> State# s
+ {Write to specified index of mutable array. Evaluates the argument before writing it.}
+ with
+ effect = ReadWriteEffect
+ can_fail_warning = YesWarnCanFail
+ code_size = 2 -- card update too
+ cbv_marks = [!,!,!]
+
primop SizeofArrayOp "sizeofArray#" GenPrimOp
Array# a_levpoly -> Int#
{Return the number of elements in the array.}
@@ -1637,6 +1669,23 @@ primop SizeofMutableArrayOp "sizeofMutableArray#" GenPrimOp
MutableArray# s a_levpoly -> Int#
{Return the number of elements in the array.}
+primop IndexStrictArrayOp "unsafeIndexStrictArray#" GenPrimOp
+ Array# a_levpoly -> Int# -> (# a_levpoly #)
+ {Read from the specified index of an immutable array. The result is packaged
+ into an unboxed unary tuple; the result itself is evaluated.
+ Pattern matching on the tuple forces the indexing of the
+ array to happen.
+
+ GHC will assume the value at the given index has been written
+ by writeStrictArray#. This can allow GHC to elid an eval check when using the
+ read value. Potentially given a performance benefit.
+
+ WARNING: Behaviour is undefined if the value read
+ was not written using writeStrictArray#.
+ }
+ with
+ effect = CanFail
+
primop IndexArrayOp "indexArray#" GenPrimOp
Array# a_levpoly -> Int# -> (# a_levpoly #)
{Read from the specified index of an immutable array. The result is packaged
@@ -1838,6 +1887,27 @@ primop ReadSmallArrayOp "readSmallArray#" GenPrimOp
effect = ReadWriteEffect
can_fail_warning = YesWarnCanFail
+primop ReadSmallStrictArrayOp "unsafeReadSmallStrictArray#" GenPrimOp
+ SmallMutableArray# s a -> Int# -> State# s -> (# State# s, a #)
+ {Read from specified index of mutable array.
+
+ GHC will assume the value at the given index has been evaluted *and tagged*
+ by writeStrictArray#. This can allow GHC to elid an eval check when using the
+ read value. Potentially given a performance benefit.
+
+ WARNING: Behaviour is undefined if the value read
+ was not written using writeStrictArray#.
+
+ At runtime "strict" arrays and regular arrays have the same representation.
+ The only difference is in the read/write operations.
+
+ The strict write operations ensure stored values are evaluated and properly
+ tagged. Strict reads assume this fact, allowing GHC to sometimes avoid
+ checking for thunks when using the read value.}
+ with
+ effect = ReadWriteEffect
+ can_fail_warning = YesWarnCanFail
+
primop WriteSmallArrayOp "writeSmallArray#" GenPrimOp
SmallMutableArray# s a_levpoly -> Int# -> a_levpoly -> State# s -> State# s
{Write to specified index of mutable array.}
@@ -1845,6 +1915,16 @@ primop WriteSmallArrayOp "writeSmallArray#" GenPrimOp
effect = ReadWriteEffect
can_fail_warning = YesWarnCanFail
+primop WriteSmallStrictArrayOp "writeSmallStrictArray#" GenPrimOp
+ SmallMutableArray# s a_levpoly -> Int# -> a_levpoly -> State# s -> State# s
+ {Write to specified index of mutable array.
+
+ Evaluates the argument before storing it.}
+ with
+ effect = ReadWriteEffect
+ can_fail_warning = YesWarnCanFail
+ cbv_marks = [!,!,!]
+
primop SizeofSmallArrayOp "sizeofSmallArray#" GenPrimOp
SmallArray# a_levpoly -> Int#
{Return the number of elements in the array.}
@@ -1870,6 +1950,20 @@ primop IndexSmallArrayOp "indexSmallArray#" GenPrimOp
with
effect = CanFail
+primop IndexSmallStrictArrayOp "unsafeIndexSmallStrictArray#" GenPrimOp
+ SmallArray# a -> Int# -> (# a #)
+ {Read from specified index of immutable array. Result is packaged into
+ an unboxed singleton;
+
+ GHC will assume the value at the given index has been written
+ by writeSmallStrictArray#. This can allow GHC to elid an eval check when using the
+ read value. Potentially given a performance benefit.
+
+ WARNING: Behaviour is undefined if the value read
+ was not written using writeSmallStrictArray#}
+ with
+ effect = CanFail
+
primop UnsafeFreezeSmallArrayOp "unsafeFreezeSmallArray#" GenPrimOp
SmallMutableArray# s a_levpoly -> State# s -> (# State# s, SmallArray# a_levpoly #)
{Make a mutable array immutable, without copying.}
=====================================
compiler/GHC/Stg/EnforceEpt.hs
=====================================
@@ -9,6 +9,7 @@ module GHC.Stg.EnforceEpt ( enforceEpt ) where
import GHC.Prelude hiding (id)
+import qualified GHC.Builtin.PrimOps as PrimOps
import GHC.Core.DataCon
import GHC.Core.Type
import GHC.Types.Id
@@ -354,6 +355,16 @@ inferTags for_bytecode binds =
-- pprTrace "Binds" (pprGenStgTopBindings shortStgPprOpts $ binds) $
snd (mapAccumL inferTagTopBind (initEnv for_bytecode) binds)
+inferPrimAppResult :: PrimOps.PrimOp -> TagInfo
+inferPrimAppResult op =
+ case op of
+ PrimOps.ReadSmallStrictArrayOp -> TagTuple [TagProper]
+ PrimOps.ReadStrictArrayOp -> TagTuple [TagProper]
+ PrimOps.IndexSmallStrictArrayOp -> TagTuple [TagProper]
+ PrimOps.IndexStrictArrayOp -> TagTuple [TagProper]
+ _ -> TagDunno
+
+
-----------------------
inferTagTopBind :: TagEnv 'CodeGen -> GenStgTopBinding 'CodeGen
-> (TagEnv 'CodeGen, GenStgTopBinding 'InferTaggedBinders)
@@ -409,11 +420,14 @@ inferTagExpr env (StgTick tick body)
where
(info, body') = inferTagExpr env body
-inferTagExpr _ (StgOpApp op args ty)
+inferTagExpr _ (StgOpApp op args ty) =
-- Which primops guarantee to return a properly tagged value?
-- Probably none, and that is the conservative assumption anyway.
-- (And foreign calls definitely need not make promises.)
- = (TagDunno, StgOpApp op args ty)
+ case op of
+ StgPrimOp prim_op -> (inferPrimAppResult prim_op, StgOpApp op args ty)
+ StgPrimCallOp {} -> (TagDunno, StgOpApp op args ty)
+ StgFCallOp {} -> (TagDunno, StgOpApp op args ty)
inferTagExpr env (StgLet ext bind body)
= (info, StgLet ext bind' body')
=====================================
compiler/GHC/Stg/EnforceEpt/Rewrite.hs
=====================================
@@ -12,7 +12,7 @@ where
import GHC.Prelude
-import GHC.Builtin.PrimOps ( PrimOp(..) )
+import GHC.Builtin.PrimOps ( PrimOp(..), primOpCbv )
import GHC.Types.Basic ( CbvMark (..), isMarkedCbv
, TopLevelFlag(..), isTopLevel )
import GHC.Types.Id
@@ -399,8 +399,7 @@ rewriteExpr (StgTick t e) = StgTick t <$!> rewriteExpr e
rewriteExpr e@(StgConApp {}) = rewriteConApp e
rewriteExpr e@(StgApp {}) = rewriteApp e
rewriteExpr (StgLit lit) = return $! (StgLit lit)
-rewriteExpr (StgOpApp op args res_ty) = (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty
-
+rewriteExpr (StgOpApp op args res_ty) = rewriteOpApp (StgOpApp op args res_ty)
rewriteCase :: InferStgExpr -> RM TgStgExpr
rewriteCase (StgCase scrut bndr alt_type alts) =
@@ -452,6 +451,21 @@ rewriteConApp (StgConApp con cn args tys) = do
rewriteConApp _ = panic "Impossible"
+{-# INLINE eptArgs #-}
+-- Evaluate the relevant arguments, and construct an expression with the ids substituted
+-- for their evaluated parts.
+eptArgs :: [CbvMark] -> [StgArg] -> ([StgArg] -> TgStgExpr) -> RM TgStgExpr
+eptArgs relevant_marks args mkExpr = do
+ argTags <- mapM isArgTagged args
+ let argInfo = zipWith3 ((,,)) args (relevant_marks++repeat NotMarkedCbv) argTags :: [(StgArg, CbvMark, Bool)]
+
+ -- untagged cbv arguments
+ cbvArgs = map fstOf3 . filter (\x -> sndOf3 x == MarkedCbv && thdOf3 x == False) $ argInfo
+ -- We only need to force ids
+ cbvArgIds = [x | StgVarArg x <- cbvArgs] :: [Id]
+ mkSeqs args cbvArgIds mkExpr
+
+
-- Special case: Atomic binders, usually in a case context like `case f of ...`.
rewriteApp :: InferStgExpr -> RM TgStgExpr
rewriteApp (StgApp f []) = do
@@ -464,19 +478,8 @@ rewriteApp (StgApp f args)
, relevant_marks <- dropWhileEndLE (not . isMarkedCbv) marks
, any isMarkedCbv relevant_marks
= assertPpr (length relevant_marks <= length args) (ppr f $$ ppr args $$ ppr relevant_marks)
- unliftArg relevant_marks
-
- where
- -- If the function expects any argument to be call-by-value ensure the argument is already
- -- evaluated.
- unliftArg relevant_marks = do
- argTags <- mapM isArgTagged args
- let argInfo = zipWith3 ((,,)) args (relevant_marks++repeat NotMarkedCbv) argTags :: [(StgArg, CbvMark, Bool)]
-
- -- untagged cbv argument positions
- cbvArgInfo = filter (\x -> sndOf3 x == MarkedCbv && thdOf3 x == False) argInfo
- cbvArgIds = [x | StgVarArg x <- map fstOf3 cbvArgInfo] :: [Id]
- mkSeqs args cbvArgIds (\cbv_args -> StgApp f cbv_args)
+ -- Enforce relevant args are evaluated and tagged.
+ eptArgs relevant_marks args (\cbv_args -> StgApp f cbv_args)
rewriteApp (StgApp f args) = return $ StgApp f args
rewriteApp _ = panic "Impossible"
@@ -500,10 +503,14 @@ So for these we should call `rewriteArgs`.
rewriteOpApp :: InferStgExpr -> RM TgStgExpr
rewriteOpApp (StgOpApp op args res_ty) = case op of
+ -- Should we just use cbv marks for DataToTag?
op@(StgPrimOp primOp)
| primOp == DataToTagSmallOp || primOp == DataToTagLargeOp
-- see Note [Rewriting primop arguments]
-> (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty
+ | marks <- primOpCbv primOp
+ , not (null marks)
+ -> eptArgs marks args (\tagged_args -> (StgOpApp op tagged_args res_ty))
_ -> pure $! StgOpApp op args res_ty
rewriteOpApp _ = panic "Impossible"
=====================================
compiler/GHC/StgToCmm/Prim.hs
=====================================
@@ -380,17 +380,29 @@ emitPrimOp cfg primop =
ReadArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
+ ReadStrictArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
+ doReadPtrArrayOp res obj ix
IndexArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
+ IndexStrictArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
+ doReadPtrArrayOp res obj ix
WriteArrayOp -> \[obj, ix, v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
+ WriteStrictArrayOp -> \[obj, ix, v] -> opIntoRegs $ \[] ->
+ doWritePtrArrayOp obj ix v
ReadSmallArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadSmallPtrArrayOp res obj ix
+ ReadSmallStrictArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
+ doReadSmallPtrArrayOp res obj ix
IndexSmallArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadSmallPtrArrayOp res obj ix
+ IndexSmallStrictArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
+ doReadSmallPtrArrayOp res obj ix
WriteSmallArrayOp -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWriteSmallPtrArrayOp obj ix v
+ WriteSmallStrictArrayOp -> \[obj,ix,v] -> opIntoRegs $ \[] ->
+ doWriteSmallPtrArrayOp obj ix v
-- Getting the size of pointer arrays
=====================================
compiler/GHC/StgToJS/Prim.hs
=====================================
@@ -559,7 +559,9 @@ genPrim prof bound ty op = case op of
NewArrayOp -> \[r] [l,e] -> pure $ PrimInline $ r |= app hdNewArrayStr [l,e]
ReadArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
+ ReadStrictArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
WriteArrayOp -> \[] [a,i,v] -> pure $ PrimInline $ bnd_arr bound a i (a .! i |= v)
+ WriteStrictArrayOp -> \[] [a,i,v] -> pure $ PrimInline $ bnd_arr bound a i (a .! i |= v)
SizeofArrayOp -> \[r] [a] -> pure $ PrimInline $ r |= a .^ lngth
SizeofMutableArrayOp -> \[r] [a] -> pure $ PrimInline $ r |= a .^ lngth
IndexArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
@@ -623,7 +625,9 @@ genPrim prof bound ty op = case op of
NewSmallArrayOp -> \[a] [n,e] -> pure $ PrimInline $ a |= app hdNewArrayStr [n,e]
ReadSmallArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
+ ReadSmallStrictArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
WriteSmallArrayOp -> \[] [a,i,e] -> pure $ PrimInline $ bnd_arr bound a i (a .! i |= e)
+ WriteSmallStrictArrayOp -> \[] [a,i,e] -> pure $ PrimInline $ bnd_arr bound a i (a .! i |= e) -- todo check-tags?
SizeofSmallArrayOp -> \[r] [a] -> pure $ PrimInline $ r |= a .^ lngth
SizeofSmallMutableArrayOp -> \[r] [a] -> pure $ PrimInline $ r |= a .^ lngth
IndexSmallArrayOp -> \[r] [a,i] -> pure $ PrimInline $ bnd_arr bound a i (r |= a .! i)
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -513,8 +513,8 @@ isDFunId id = case Var.idDetails id of
_ -> False
isPrimOpId_maybe id = case Var.idDetails id of
- PrimOpId op _ -> Just op
- _ -> Nothing
+ PrimOpId op _ -> Just op
+ _ -> Nothing
isFCallId id = case Var.idDetails id of
FCallId _ -> True
@@ -845,7 +845,7 @@ setIdCbvMarks id marks
idCbvMarks_maybe :: Id -> Maybe [CbvMark]
idCbvMarks_maybe id = case idDetails id of
- WorkerLikeId marks -> Just marks
+ WorkerLikeId marks -> Just marks
JoinId _arity marks -> marks
_ -> Nothing
=====================================
compiler/GHC/Types/Id/Info.hs
=====================================
@@ -395,7 +395,7 @@ pprIdDetails VanillaId = empty
pprIdDetails other = brackets (pp other)
where
pp VanillaId = panic "pprIdDetails"
- pp (WorkerLikeId dmds) = text "StrictWorker" <> parens (ppr dmds)
+ pp (WorkerLikeId dmds) = text "StrictWorker" <> pp_marks dmds
pp (DataConWorkId _) = text "DataCon"
pp (DataConWrapId _) = text "DataConWrapper"
pp (ClassOpId {}) = text "ClassOp"
@@ -410,6 +410,9 @@ pprIdDetails other = brackets (pp other)
pp CoVarId = text "CoVarId"
pp (JoinId arity marks) = text "JoinId" <> parens (int arity) <> parens (ppr marks)
+ pp_marks [] = empty
+ pp_marks xs = ppr xs
+
{-
************************************************************************
* *
=====================================
compiler/Setup.hs
=====================================
@@ -47,6 +47,7 @@ primopIncls =
, ("primop-commutable.hs-incl" , "--commutable")
, ("primop-code-size.hs-incl" , "--code-size")
, ("primop-strictness.hs-incl" , "--strictness")
+ , ("primop-cbv.hs-incl" , "--cbv")
, ("primop-is-work-free.hs-incl" , "--is-work-free")
, ("primop-is-cheap.hs-incl" , "--is-cheap")
, ("primop-fixity.hs-incl" , "--fixity")
=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -92,6 +92,7 @@ compilerDependencies = do
, "primop-out-of-line.hs-incl"
, "primop-primop-info.hs-incl"
, "primop-strictness.hs-incl"
+ , "primop-cbv.hs-incl"
, "primop-is-work-free.hs-incl"
, "primop-is-cheap.hs-incl"
, "primop-tag.hs-incl"
=====================================
hadrian/src/Rules/Lint.hs
=====================================
@@ -111,6 +111,7 @@ hsIncls path = [ path </> "primop-vector-tycons.hs-incl"
, path </> "primop-tag.hs-incl"
, path </> "primop-list.hs-incl"
, path </> "primop-strictness.hs-incl"
+ , path </> "primop-cbv.hs-incl"
, path </> "primop-is-work-free.hs-incl"
, path </> "primop-is-cheap.hs-incl"
, path </> "primop-fixity.hs-incl"
=====================================
hadrian/src/Settings/Builders/GenPrimopCode.hs
=====================================
@@ -14,6 +14,7 @@ genPrimopCodeBuilderArgs = builder GenPrimopCode ? mconcat
, output "//primop-commutable.hs-incl" ? arg "--commutable"
, output "//primop-code-size.hs-incl" ? arg "--code-size"
, output "//primop-strictness.hs-incl" ? arg "--strictness"
+ , output "//primop-cbv.hs-incl" ? arg "--cbv"
, output "//primop-is-work-free.hs-incl" ? arg "--is-work-free"
, output "//primop-is-cheap.hs-incl" ? arg "--is-cheap"
, output "//primop-fixity.hs-incl" ? arg "--fixity"
=====================================
utils/genprimopcode/Lexer.x
=====================================
@@ -36,6 +36,8 @@ words :-
<0> "]" { mkT TCloseBracket }
<0> "<" { mkT TOpenAngle }
<0> ">" { mkT TCloseAngle }
+ <0> "!" { mkT TBang }
+ <0> "~" { mkT TTilde }
<0> "section" { mkT TSection }
<0> "primop" { mkT TPrimop }
<0> "pseudoop" { mkT TPseudoop }
@@ -62,6 +64,7 @@ words :-
<0> "WarnIfEffectIsCanFail" { mkT TWarnIfEffectIsCanFail }
<0> "YesWarnCanFail" { mkT TYesWarnCanFail }
<0> "vector" { mkT TVector }
+ <0> "cbv_marks" { mkT TCbv_marks }
<0> "bytearray_access_ops" { mkT TByteArrayAccessOps }
<0> "addr_access_ops" { mkT TAddrAccessOps }
<0> "thats_all_folks" { mkT TThatsAllFolks }
=====================================
utils/genprimopcode/Main.hs
=====================================
@@ -170,6 +170,11 @@ main = getArgs >>= \args ->
"strictness"
"primOpStrictness" p_o_specs)
+ "--cbv"
+ -> putStr (gen_switch_from_attribs
+ "cbv_marks"
+ "primOpCbv" p_o_specs)
+
"--fixity"
-> putStr (gen_switch_from_attribs
"fixity"
@@ -228,6 +233,7 @@ known_args
"--is-work-free",
"--is-cheap",
"--strictness",
+ "--cbv",
"--fixity",
"--primop-effects",
"--primop-primop-info",
@@ -318,6 +324,7 @@ gen_hs_source (Info defaults entries) =
opt (OptionInteger n v) = n ++ " = " ++ show v
opt (OptionVector _) = ""
opt (OptionFixity mf) = "fixity = " ++ show mf
+ opt (OptionCbvMarks marks) = "cbv_marks = " ++ show marks
opt (OptionEffect eff) = "effect = " ++ show eff
opt (OptionDefinedBits bc) = "defined_bits = " ++ show bc
opt (OptionCanFailWarnFlag wf) = "can_fail_warning = " ++ show wf
@@ -645,6 +652,11 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries)
getAltRhs (OptionString _ s) = s
getAltRhs (OptionVector _) = "True"
getAltRhs (OptionFixity mf) = show mf
+ getAltRhs (OptionCbvMarks marks) =
+ "[" ++ concat (intersperse "," (map showMark marks)) ++ "]"
+ where
+ showMark True = "MarkedCbv"
+ showMark False = "NotMarkedCbv"
getAltRhs (OptionEffect eff) = show eff
getAltRhs (OptionDefinedBits bc) = show bc
getAltRhs (OptionCanFailWarnFlag wf) = show wf
=====================================
utils/genprimopcode/Parser.y
=====================================
@@ -30,6 +30,8 @@ import AccessOps
']' { TCloseBracket }
'<' { TOpenAngle }
'>' { TCloseAngle }
+ '!' { TBang }
+ '~' { TTilde }
section { TSection }
primop { TPrimop }
pseudoop { TPseudoop }
@@ -56,6 +58,7 @@ import AccessOps
WarnIfEffectIsCanFail { TWarnIfEffectIsCanFail }
YesWarnCanFail { TYesWarnCanFail }
vector { TVector }
+ cbv_marks { TCbv_marks }
SCALAR { TSCALAR }
VECTOR { TVECTOR }
VECTUPLE { TVECTUPLE }
@@ -87,6 +90,7 @@ pOption : lowerName '=' false { OptionFalse $1 }
| lowerName '=' pStuffBetweenBraces { OptionString $1 $3 }
| lowerName '=' integer { OptionInteger $1 $3 }
| vector '=' pVectorTemplate { OptionVector $3 }
+ | cbv_marks '=' pCbvMarks { OptionCbvMarks $3 }
| fixity '=' pInfix { OptionFixity $3 }
| effect '=' pEffect { OptionEffect $3 }
| defined_bits '=' pGoodBits { OptionDefinedBits $3 }
@@ -175,6 +179,18 @@ pInside :: { String }
pInside : '{' pInsides '}' { "{" ++ $2 ++ "}" }
| noBraces { $1 }
+pCbvMarks :: { [Bool] }
+pCbvMarks : '[' pMarks ']' { $2 }
+
+pMarks :: { [Bool] }
+pMarks : pMark ',' pMarks { [$1] ++ $3 }
+ | pMark { [$1] }
+ | {- empty -} { [] }
+
+pMark :: { Bool }
+pMark : '!' { True }
+ | '~' { False }
+
pVectorTemplate :: { [(String, String, Int)] }
pVectorTemplate : '[' pVectors ']' { $2 }
=====================================
utils/genprimopcode/ParserM.hs
=====================================
@@ -75,6 +75,8 @@ init_state = St {
data Token = TEOF
| TArrow
+ | TBang
+ | TTilde
| TDArrow
| TEquals
| TComma
@@ -122,6 +124,7 @@ data Token = TEOF
| TWarnIfEffectIsCanFail
| TYesWarnCanFail
| TVector
+ | TCbv_marks
| TSCALAR
| TVECTOR
| TVECTUPLE
=====================================
utils/genprimopcode/Syntax.hs
=====================================
@@ -83,6 +83,7 @@ data Option
| OptionEffect PrimOpEffect -- effect = NoEffect | DoNotSpeculate | CanFail | ThrowsException | ReadWriteEffect | FallibleReadWriteEffect
| OptionCanFailWarnFlag PrimOpCanFailWarnFlag -- can_fail_warning = DoNotWarnCanFail | WarnIfEffectIsCanFail | YesWarnCanFail
| OptionDefinedBits (Maybe Word) -- defined_bits = Just 16 | Nothing
+ | OptionCbvMarks [Bool] -- defined_bits = Just 16 | Nothing
deriving Show
-- categorises primops
@@ -200,6 +201,7 @@ get_attrib_name (OptionTrue nm) = nm
get_attrib_name (OptionString nm _) = nm
get_attrib_name (OptionInteger nm _) = nm
get_attrib_name (OptionVector _) = "vector"
+get_attrib_name (OptionCbvMarks _) = "cbv_marks"
get_attrib_name (OptionFixity _) = "fixity"
get_attrib_name (OptionEffect _) = "effect"
get_attrib_name (OptionCanFailWarnFlag _) = "can_fail_warning"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/471d9a01934c6b40fcb2ffa6b3df5b1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/471d9a01934c6b40fcb2ffa6b3df5b1…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
09 Nov '25
Andreas Klebinger pushed new branch wip/andreask/cbv_array at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/cbv_array
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/rewriteOpApp] EnforceEpt: Don't perform pointless rewrites on primop arguments
by Andreas Klebinger (@AndreasK) 09 Nov '25
by Andreas Klebinger (@AndreasK) 09 Nov '25
09 Nov '25
Andreas Klebinger pushed to branch wip/andreask/rewriteOpApp at Glasgow Haskell Compiler / GHC
Commits:
cb836d33 by Andreas Klebinger at 2025-11-09T15:29:38+01:00
EnforceEpt: Don't perform pointless rewrites on primop arguments
- - - - -
1 changed file:
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
Changes:
=====================================
compiler/GHC/Stg/EnforceEpt/Rewrite.hs
=====================================
@@ -399,7 +399,7 @@ rewriteExpr (StgTick t e) = StgTick t <$!> rewriteExpr e
rewriteExpr e@(StgConApp {}) = rewriteConApp e
rewriteExpr e@(StgApp {}) = rewriteApp e
rewriteExpr (StgLit lit) = return $! (StgLit lit)
-rewriteExpr (StgOpApp op args res_ty) = (StgOpApp op) <$!> rewriteArgs args <*> pure res_ty
+rewriteExpr e@(StgOpApp op args res_ty) = rewriteOpApp e
rewriteCase :: InferStgExpr -> RM TgStgExpr
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb836d334f785ba7538d6917eef6dfd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb836d334f785ba7538d6917eef6dfd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/andreask/rewriteOpApp
by Andreas Klebinger (@AndreasK) 09 Nov '25
by Andreas Klebinger (@AndreasK) 09 Nov '25
09 Nov '25
Andreas Klebinger pushed new branch wip/andreask/rewriteOpApp at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/rewriteOpApp
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/24279] Make TYPE and CONSTRAINT apart again
by Simon Peyton Jones (@simonpj) 09 Nov '25
by Simon Peyton Jones (@simonpj) 09 Nov '25
09 Nov '25
Simon Peyton Jones pushed to branch wip/24279 at Glasgow Haskell Compiler / GHC
Commits:
0b211ff8 by Simon Peyton Jones at 2025-11-08T23:19:08+00:00
Make TYPE and CONSTRAINT apart again
- - - - -
13 changed files:
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Tc/Instance/Class.hs
- testsuite/tests/indexed-types/should_fail/T21092.hs
- − testsuite/tests/indexed-types/should_fail/T21092.stderr
- testsuite/tests/indexed-types/should_fail/all.T
- testsuite/tests/typecheck/should_fail/T24279.hs
- − testsuite/tests/typecheck/should_fail/T24279.stderr
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
compiler/GHC/Builtin/Types/Prim.hs
=====================================
@@ -752,8 +752,9 @@ Specifically (a ~# b) :: CONSTRAINT (TupleRep [])
Wrinkles
-(W1) Type and Constraint are considered distinct throughout GHC. But they
- are not /apart/: see Note [Type and Constraint are not apart]
+(W1) Type and Constraint are considered distinct throughout GHC.
+ That wasn't always the case:
+ see Historical Note [Type and Constraint are not apart]
(W2) We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and
aBSENT_CONSTRAINT_ERROR_ID for types of kind Constraint.
@@ -768,8 +769,24 @@ Wrinkles
of type TYPE rr. See (CPR2) in Note [Which types are unboxed?] in
GHC.Core.Opt.WorkWrap.Utils.
-Note [Type and Constraint are not apart]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------------------------------------------
+Historical Note [Type and Constraint are not apart]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Nov 2025:
+ In the past, Type and Constraint were carefully coonsiderd to be
+ not /apart/. But the necessity for that vanished with unary classes
+ (see Note [Unary class magic]), done in
+
+ commit 9bd7fcc518111a1549c98720c222cdbabd32ed46
+ Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
+ Date: Tue Apr 15 17:43:46 2025 +0100
+ Implement unary classes
+
+ So now Type and Constraint are simply distinct type constructors, just as
+ much as Int and Bool.
+
+ The rest of this Note is preserved for historical interest.
+
Type and Constraint are not equal (eqType) but they are not /apart/
either. Reason (c.f. #7451):
@@ -841,6 +858,9 @@ Wrinkles
So in GHC.Tc.Instance.Class.matchTypeable, Type and Constraint are
treated as separate TyCons; i.e. given no special treatment.
+End of Historical Note
+-------------------------------------------------------------
+
Note [RuntimeRep polymorphism]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generally speaking, you can't be polymorphic in `RuntimeRep`. E.g
=====================================
compiler/GHC/Core/Coercion.hs
=====================================
@@ -641,11 +641,6 @@ eqTyConRole tc
-- | Given a coercion `co :: (t1 :: TYPE r1) ~ (t2 :: TYPE r2)`
-- produce a coercion `rep_co :: r1 ~ r2`
--- But actually it is possible that
--- co :: (t1 :: CONSTRAINT r1) ~ (t2 :: CONSTRAINT r2)
--- or co :: (t1 :: TYPE r1) ~ (t2 :: CONSTRAINT r2)
--- or co :: (t1 :: CONSTRAINT r1) ~ (t2 :: TYPE r2)
--- See Note [mkRuntimeRepCo]
mkRuntimeRepCo :: HasDebugCallStack => Coercion -> Coercion
mkRuntimeRepCo co
= assert (isTYPEorCONSTRAINT k1 && isTYPEorCONSTRAINT k2) $
@@ -654,26 +649,6 @@ mkRuntimeRepCo co
kind_co = mkKindCo co -- kind_co :: TYPE r1 ~ TYPE r2
Pair k1 k2 = coercionKind kind_co
-{- Note [mkRuntimeRepCo]
-~~~~~~~~~~~~~~~~~~~~~~~~
-Given
- class C a where { op :: Maybe a }
-we will get an axiom
- axC a :: (C a :: CONSTRAINT r1) ~ (Maybe a :: TYPE r2)
-(See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim.)
-
-Then we may call mkRuntimeRepCo on (axC ty), and that will return
- mkSelCo (SelTyCon 0 Nominal) (Kind (axC ty)) :: r1 ~ r2
-
-So mkSelCo needs to be happy with decomposing a coercion of kind
- CONSTRAINT r1 ~ TYPE r2
-
-Hence the use of `tyConIsTYPEorCONSTRAINT` in the assertion `good_call`
-in `mkSelCo`. See #23018 for a concrete example. (In this context it's
-important that TYPE and CONSTRAINT have the same arity and kind, not
-merely that they are not-apart; otherwise SelCo would not make sense.)
--}
-
isReflCoVar_maybe :: Var -> Maybe Coercion
-- If cv :: t~t then isReflCoVar_maybe cv = Just (Refl t)
-- Works on all kinds of Vars, not just CoVars
@@ -1305,8 +1280,7 @@ mkSelCo_maybe cs co
, Just (tc2, tys2) <- splitTyConApp_maybe ty2
, let { len1 = length tys1
; len2 = length tys2 }
- = (tc1 == tc2 || (tyConIsTYPEorCONSTRAINT tc1 && tyConIsTYPEorCONSTRAINT tc2))
- -- tyConIsTYPEorCONSTRAINT: see Note [mkRuntimeRepCo]
+ = tc1 == tc2
&& len1 == len2
&& n < len1
&& r == tyConRole (coercionRole co) tc1 n
=====================================
compiler/GHC/Core/Lint.hs
=====================================
@@ -2891,6 +2891,8 @@ lint_branch ax_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs
hang (text "Inhomogeneous axiom")
2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$
text "rhs:" <+> ppr rhs <+> dcolon <+> ppr rhs_kind) }
+ -- ToDo: I don't understand this comment; and in any case, Type
+ -- and Constraint now are apart
-- Type and Constraint are not Apart, so this test allows
-- the newtype axiom for a single-method class. Indeed the
-- whole reason Type and Constraint are not Apart is to allow
=====================================
compiler/GHC/Core/RoughMap.hs
=====================================
@@ -36,7 +36,6 @@ import GHC.Core.Type
import GHC.Utils.Outputable
import GHC.Types.Name
import GHC.Types.Name.Env
-import GHC.Builtin.Types.Prim( cONSTRAINTTyConName, tYPETyConName )
import Control.Monad (join)
import Data.Data (Data)
@@ -347,16 +346,7 @@ typeToRoughMatchTc ty
roughMatchTyConName :: TyCon -> Name
roughMatchTyConName tc
- | tc_name == cONSTRAINTTyConName
- = tYPETyConName -- TYPE and CONSTRAINT are not apart, so they must use
- -- the same rough-map key. We arbitrarily use TYPE.
- -- See Note [Type and Constraint are not apart]
- -- wrinkle (W1) in GHC.Builtin.Types.Prim
- | otherwise
- = assertPpr (isGenerativeTyCon tc Nominal) (ppr tc) tc_name
- where
- tc_name = tyConName tc
-
+ = assertPpr (isGenerativeTyCon tc Nominal) (ppr tc) (tyConName tc)
-- | Trie of @[RoughMatchTc]@
--
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -1421,8 +1421,6 @@ piResultTy ty arg = case piResultTy_maybe ty arg of
Nothing -> pprPanic "piResultTy" (ppr ty $$ ppr arg)
piResultTy_maybe :: Type -> Type -> Maybe Type
--- We don't need a 'tc' version, because
--- this function behaves the same for Type and Constraint
piResultTy_maybe ty arg = case coreFullView ty of
FunTy { ft_res = res } -> Just res
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -27,7 +27,6 @@ import GHC.Prelude
import GHC.Types.Var
import GHC.Types.Var.Env
import GHC.Types.Var.Set
-import GHC.Builtin.Names( tYPETyConKey, cONSTRAINTTyConKey )
import GHC.Core.Type hiding ( getTvSubstEnv )
import GHC.Core.Coercion hiding ( getCvSubstEnv )
import GHC.Core.Predicate( scopedSort )
@@ -98,8 +97,6 @@ of ways. Here we summarise, but see Note [Specification of unification].
See Note [Apartness and type families]
* MARInfinite (occurs check):
See Note [Infinitary substitutions]
- * MARTypeVsConstraint:
- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim
* MARCast (obscure):
See (KCU2) in Note [Kind coercions in Unify]
@@ -997,16 +994,12 @@ data UnifyResultM a = Unifiable a -- the subst that unifies the types
-- | Why are two types 'MaybeApart'? 'MARInfinite' takes precedence:
-- This is used (only) in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv
--- As of Feb 2022, we never differentiate between MARTypeFamily and MARTypeVsConstraint;
--- it's really only MARInfinite that's interesting here.
+-- It's really only MARInfinite that's interesting here.
data MaybeApartReason
= MARTypeFamily -- ^ matching e.g. F Int ~? Bool
| MARInfinite -- ^ matching e.g. a ~? Maybe a
- | MARTypeVsConstraint -- ^ matching Type ~? Constraint or the arrow types
- -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim
-
| MARCast -- ^ Very obscure.
-- See (KCU2) in Note [Kind coercions in Unify]
@@ -1015,13 +1008,11 @@ combineMAR :: MaybeApartReason -> MaybeApartReason -> MaybeApartReason
-- See (UR1) in Note [Unification result] for why MARInfinite wins
combineMAR MARInfinite _ = MARInfinite -- MARInfinite wins
combineMAR MARTypeFamily r = r -- Otherwise it doesn't really matter
-combineMAR MARTypeVsConstraint r = r
combineMAR MARCast r = r
instance Outputable MaybeApartReason where
ppr MARTypeFamily = text "MARTypeFamily"
ppr MARInfinite = text "MARInfinite"
- ppr MARTypeVsConstraint = text "MARTypeVsConstraint"
ppr MARCast = text "MARCast"
instance Semigroup MaybeApartReason where
@@ -1729,30 +1720,6 @@ unify_ty env ty1 ty2 kco
; unify_tc_app env tc1 tys1 tys2
}
- -- TYPE and CONSTRAINT are not Apart
- -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim
- -- NB: at this point we know that the two TyCons do not match
- | Just (tc1,_) <- mb_tc_app1, let u1 = tyConUnique tc1
- , Just (tc2,_) <- mb_tc_app2, let u2 = tyConUnique tc2
- , (u1 == tYPETyConKey && u2 == cONSTRAINTTyConKey) ||
- (u2 == tYPETyConKey && u1 == cONSTRAINTTyConKey)
- = maybeApart MARTypeVsConstraint
- -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim
- -- Note [Type and Constraint are not apart]
-
- -- The arrow types are not Apart
- -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim
- -- wrinkle (W2)
- -- NB1: at this point we know that the two TyCons do not match
- -- NB2: In the common FunTy/FunTy case you might wonder if we want to go via
- -- splitTyConApp_maybe. But yes we do: we need to look at those implied
- -- kind argument in order to satisfy (Unification Kind Invariant)
- | FunTy {} <- ty1
- , FunTy {} <- ty2
- = maybeApart MARTypeVsConstraint
- -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim
- -- Note [Type and Constraint are not apart]
-
where
mb_tc_app1 = splitTyConApp_maybe ty1
mb_tc_app2 = splitTyConApp_maybe ty2
=====================================
compiler/GHC/Tc/Instance/Class.hs
=====================================
@@ -963,11 +963,6 @@ matchTypeable clas [k,t] -- clas = Typeable
| k `eqType` naturalTy = doTyLit knownNatClassName t
| k `eqType` typeSymbolKind = doTyLit knownSymbolClassName t
| k `eqType` charTy = doTyLit knownCharClassName t
-
- -- TyCon applied to its kind args
- -- No special treatment of Type and Constraint; they get distinct TypeReps
- -- see wrinkle (W4) of Note [Type and Constraint are not apart]
- -- in GHC.Builtin.Types.Prim.
| Just (tc, ks) <- splitTyConApp_maybe t -- See Note [Typeable (T a b c)]
, onlyNamedBndrsApplied tc ks = doTyConApp clas t tc ks
=====================================
testsuite/tests/indexed-types/should_fail/T21092.hs
=====================================
@@ -7,3 +7,5 @@ type family F a
type instance F Type = Int
type instance F Constraint = Bool
+
+-- Nov 2025: Type and Constraint are now Apart (#24279)
=====================================
testsuite/tests/indexed-types/should_fail/T21092.stderr deleted
=====================================
@@ -1,5 +0,0 @@
-
-T21092.hs:8:15: error: [GHC-34447]
- Conflicting family instance declarations:
- F (*) = Int -- Defined at T21092.hs:8:15
- F Constraint = Bool -- Defined at T21092.hs:9:15
=====================================
testsuite/tests/indexed-types/should_fail/all.T
=====================================
@@ -107,7 +107,7 @@ test('T8368', normal, compile_fail, [''])
test('T8368a', normal, compile_fail, [''])
test('T8518', normal, compile_fail, [''])
test('T9036', normal, compile_fail, [''])
-test('T21092', normal, compile_fail, [''])
+test('T21092', normal, compile, ['']) # Now compiles fine
test('T9167', normal, compile_fail, [''])
test('T9171', normal, compile_fail, [''])
test('T9097', normal, compile_fail, [''])
=====================================
testsuite/tests/typecheck/should_fail/T24279.hs
=====================================
@@ -13,7 +13,7 @@ type G :: Type -> RuntimeRep -> Type
type family G a where
G (a b) = a
--- Should be rejected
+-- Now (Nov 2025) accepted
foo :: (F (G Constraint)) -> Bool
foo x = x
@@ -22,10 +22,10 @@ type family H a b where
H a a = Int
H a b = Bool
--- Should be rejected
-bar1 :: H TYPE CONSTRAINT -> Int
+-- Now (Nov 2025) accepted
+bar1 :: H TYPE CONSTRAINT -> Bool
bar1 x = x
--- Should be rejected
-bar2 :: H Type Constraint -> Int
+-- Now (Nov 2025) accepted
+bar2 :: H Type Constraint -> Bool
bar2 x = x
=====================================
testsuite/tests/typecheck/should_fail/T24279.stderr deleted
=====================================
@@ -1,19 +0,0 @@
-
-T24279.hs:18:9: error: [GHC-83865]
- • Couldn't match type ‘F CONSTRAINT’ with ‘Bool’
- Expected: Bool
- Actual: F (G Constraint)
- • In the expression: x
- In an equation for ‘foo’: foo x = x
-
-T24279.hs:27:10: error: [GHC-83865]
- • Couldn't match expected type ‘Int’
- with actual type ‘H TYPE CONSTRAINT’
- • In the expression: x
- In an equation for ‘bar1’: bar1 x = x
-
-T24279.hs:31:10: error: [GHC-83865]
- • Couldn't match expected type ‘Int’
- with actual type ‘H (*) Constraint’
- • In the expression: x
- In an equation for ‘bar2’: bar2 x = x
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -718,7 +718,7 @@ test('T24064', normal, compile_fail, [''])
test('T24090a', normal, compile_fail, [''])
test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 9.16
test('T24298', normal, compile_fail, [''])
-test('T24279', normal, compile_fail, [''])
+test('T24279', normal, compile, ['']) # Now accepted (Nov 2025)
test('T24318', normal, compile_fail, [''])
# all the various do expansion fail messages
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b211ff84d9a34fb60b51188d479b1b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b211ff84d9a34fb60b51188d479b1b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ubsan] 3 commits: hadrian: add support for building with UndefinedBehaviorSanitizer
by Cheng Shao (@TerrorJack) 08 Nov '25
by Cheng Shao (@TerrorJack) 08 Nov '25
08 Nov '25
Cheng Shao pushed to branch wip/ubsan at Glasgow Haskell Compiler / GHC
Commits:
30675d8a by Cheng Shao at 2025-11-08T19:04:34+01:00
hadrian: add support for building with UndefinedBehaviorSanitizer
This patch adds a +ubsan flavour transformer to hadrian to build all
stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is
particularly useful to catch potential undefined behavior in the RTS
codebase.
- - - - -
3c311c11 by Cheng Shao at 2025-11-08T19:21:40+01:00
configure: bump LlvmMaxVersion to 22
This commit bumps LlvmMaxVersion to 22; 21.x releases have been
available since Aug 26th, 2025 and there's no regressions with 21.x so
far. This bump is also required for updating fedora image to 43.
- - - - -
f89f309b by Cheng Shao at 2025-11-08T19:26:14+01:00
ci: add x86_64-linux-fedora43-validate+ubsan job
This patch updates fedora image to 43, and adds a
`x86_64-linux-fedora43-validate+ubsan` job that's run in
validate/nightly pipelines to catch undefined behavior in the RTS
codebase.
- - - - -
11 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- configure.ac
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- rts/rts.cabal
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -11,7 +11,7 @@ variables:
GIT_SSL_NO_VERIFY: "1"
# Commit of ghc/ci-images repository from which to pull Docker images
- DOCKER_REV: a97d5c67d803c6b3811c6cccdf33dc8e9d7eafe3
+ DOCKER_REV: 73a36525413f808b902980ce2edccd759f2ae9b8
# Sequential version number of all cached things.
# Bump to invalidate GitLab CI cache.
@@ -444,14 +444,14 @@ hadrian-ghc-in-ghci:
hadrian-multi:
stage: testing
needs:
- - job: x86_64-linux-fedora42-release
+ - job: x86_64-linux-fedora43-release
optional: true
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
optional: true
- - job: release-x86_64-linux-fedora42-release
+ - job: release-x86_64-linux-fedora43-release
optional: true
dependencies: null
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
before_script:
# workaround for docker permissions
- sudo chown ghc:ghc -R .
@@ -471,7 +471,7 @@ hadrian-multi:
- ls
- |
mkdir tmp
- tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp
+ tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp
pushd tmp/ghc-*/
./configure --prefix=$root
make install
@@ -533,17 +533,17 @@ test-cabal-reinstall-x86_64-linux-deb10:
abi-test-nightly:
stage: full-build
needs:
- - job: nightly-x86_64-linux-fedora42-release-hackage
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release-hackage
+ - job: nightly-x86_64-linux-fedora43-release
tags:
- x86_64-linux
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
dependencies: null
before_script:
- mkdir -p normal
- mkdir -p hackage
- - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C normal/
- - tar -xf ghc-x86_64-linux-fedora42-release-hackage_docs.tar.xz -C hackage/
+ - tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C normal/
+ - tar -xf ghc-x86_64-linux-fedora43-release-hackage_docs.tar.xz -C hackage/
script:
- .gitlab/ci.sh compare_interfaces_of "normal/ghc-*" "hackage/ghc-*"
artifacts:
@@ -620,9 +620,9 @@ doc-tarball:
hackage-doc-tarball:
stage: packaging
needs:
- - job: nightly-x86_64-linux-fedora42-release-hackage
+ - job: nightly-x86_64-linux-fedora43-release-hackage
optional: true
- - job: release-x86_64-linux-fedora42-release-hackage
+ - job: release-x86_64-linux-fedora43-release-hackage
optional: true
- job: source-tarball
tags:
@@ -639,7 +639,7 @@ hackage-doc-tarball:
- hackage_docs
before_script:
- tar -xf ghc-*[0-9]-src.tar.xz
- - tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C ghc*/
+ - tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C ghc*/
script:
- cd ghc*/
- mv .gitlab/rel_eng/upload_ghc_libs.py .
@@ -765,7 +765,7 @@ test-bootstrap:
# Triggering jobs in the ghc/head.hackage project requires that we have a job
# token for that repository. Furthermore the head.hackage CI job must have
# access to an unprivileged access token with the ability to query the ghc/ghc
-# project such that it can find the job ID of the fedora42 job for the current
+# project such that it can find the job ID of the fedora43 job for the current
# pipeline.
#
# hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build.
@@ -852,7 +852,7 @@ nightly-hackage-lint:
nightly-hackage-perf:
needs:
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
optional: true
artifacts: false
- job: nightly-aarch64-linux-deb12-validate
@@ -871,7 +871,7 @@ nightly-hackage-perf:
release-hackage-lint:
needs:
- - job: release-x86_64-linux-fedora42-release
+ - job: release-x86_64-linux-fedora43-release
optional: true
artifacts: false
- job: release-aarch64-linux-deb12-release+no_split_sections
@@ -957,13 +957,13 @@ perf-nofib:
allow_failure: true
stage: testing
needs:
- - job: x86_64-linux-fedora42-release
+ - job: x86_64-linux-fedora43-release
optional: true
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
optional: true
- - job: release-x86_64-linux-fedora42-release
+ - job: release-x86_64-linux-fedora43-release
optional: true
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
rules:
- when: never
- *full-ci
@@ -976,7 +976,7 @@ perf-nofib:
- root=$(pwd)/ghc
- |
mkdir tmp
- tar -xf ../ghc-x86_64-linux-fedora42-release.tar.xz -C tmp
+ tar -xf ../ghc-x86_64-linux-fedora43-release.tar.xz -C tmp
pushd tmp/ghc-*/
./configure --prefix=$root
make install
@@ -1000,14 +1000,14 @@ perf-nofib:
perf:
stage: testing
needs:
- - job: x86_64-linux-fedora42-release
+ - job: x86_64-linux-fedora43-release
optional: true
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
optional: true
- - job: release-x86_64-linux-fedora42-release
+ - job: release-x86_64-linux-fedora43-release
optional: true
dependencies: null
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
tags:
- x86_64-linux-perf
before_script:
@@ -1017,7 +1017,7 @@ perf:
- root=$(pwd)/ghc
- |
mkdir tmp
- tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp
+ tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp
pushd tmp/ghc-*/
./configure --prefix=$root
make install
@@ -1041,14 +1041,14 @@ perf:
abi-test:
stage: testing
needs:
- - job: x86_64-linux-fedora42-release
+ - job: x86_64-linux-fedora43-release
optional: true
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
optional: true
- - job: release-x86_64-linux-fedora42-release
+ - job: release-x86_64-linux-fedora43-release
optional: true
dependencies: null
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
rules:
- if: $CI_MERGE_REQUEST_ID
- if: '$CI_COMMIT_BRANCH == "master"'
@@ -1059,7 +1059,7 @@ abi-test:
- root=$(pwd)/ghc
- |
mkdir tmp
- tar -xf ghc-x86_64-linux-fedora42-release.tar.xz -C tmp
+ tar -xf ghc-x86_64-linux-fedora43-release.tar.xz -C tmp
pushd tmp/ghc-*/
./configure --prefix=$root
make install
@@ -1214,7 +1214,7 @@ ghcup-metadata-nightly:
extends: .ghcup-metadata
# Explicit needs for validate pipeline because we only need certain bindists
needs:
- - job: nightly-x86_64-linux-fedora42-release
+ - job: nightly-x86_64-linux-fedora43-release
artifacts: false
- job: nightly-x86_64-linux-ubuntu24_04-validate
artifacts: false
@@ -1265,7 +1265,7 @@ ghcup-metadata-nightly:
# Update the ghcup metadata with information about this nightly pipeline
ghcup-metadata-nightly-push:
stage: deploy
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV"
+ image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
dependencies: null
tags:
- x86_64-linux
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -82,7 +82,7 @@ The generated names for the jobs is important as there are a few downstream cons
of the jobs artifacts. Therefore some care should be taken if changing the generated
names of jobs to update these other places.
-1. fedora42 jobs are required by head.hackage
+1. fedora43 jobs are required by head.hackage
2. The fetch-gitlab release utility pulls release artifacts from the
3. The ghc-head-from script downloads release artifacts based on a pipeline change.
4. Some subsequent CI jobs have explicit dependencies (for example docs-tarball, perf, perf-nofib)
@@ -118,7 +118,7 @@ data LinuxDistro
| Debian11Js
| Debian10
| Debian9
- | Fedora42
+ | Fedora43
| Ubuntu2404LoongArch64
| Ubuntu2404
| Ubuntu2204
@@ -161,6 +161,7 @@ data BuildConfig
, hostFullyStatic :: Bool
, tablesNextToCode :: Bool
, threadSanitiser :: Bool
+ , ubsan :: Bool
, noSplitSections :: Bool
, validateNonmovingGc :: Bool
, textWithSIMDUTF :: Bool
@@ -186,6 +187,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts
[FullyStatic | fullyStatic] ++
[HostFullyStatic | hostFullyStatic] ++
[ThreadSanitiser | threadSanitiser] ++
+ [UBSan | ubsan] ++
[NoSplitSections | noSplitSections, buildFlavour == Release ] ++
[BootNonmovingGc | validateNonmovingGc ] ++
[TextWithSIMDUTF | textWithSIMDUTF]
@@ -198,6 +200,7 @@ data FlavourTrans =
| FullyStatic
| HostFullyStatic
| ThreadSanitiser
+ | UBSan
| NoSplitSections
| BootNonmovingGc
| TextWithSIMDUTF
@@ -226,6 +229,7 @@ vanilla = BuildConfig
, hostFullyStatic = False
, tablesNextToCode = True
, threadSanitiser = False
+ , ubsan = False
, noSplitSections = False
, validateNonmovingGc = False
, textWithSIMDUTF = False
@@ -279,6 +283,9 @@ llvm = vanilla { llvmBootstrap = True }
tsan :: BuildConfig
tsan = vanilla { threadSanitiser = True }
+enableUBSan :: BuildConfig
+enableUBSan = vanilla { ubsan = True }
+
noTntc :: BuildConfig
noTntc = vanilla { tablesNextToCode = False }
@@ -318,7 +325,7 @@ distroName Debian12Riscv = "deb12-riscv"
distroName Debian12Wine = "deb12-wine"
distroName Debian10 = "deb10"
distroName Debian9 = "deb9"
-distroName Fedora42 = "fedora42"
+distroName Fedora43 = "fedora43"
distroName Ubuntu2404LoongArch64 = "ubuntu24_04-loongarch"
distroName Ubuntu1804 = "ubuntu18_04"
distroName Ubuntu2004 = "ubuntu20_04"
@@ -373,6 +380,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f
flavour_string FullyStatic = "fully_static"
flavour_string HostFullyStatic = "host_fully_static"
flavour_string ThreadSanitiser = "thread_sanitizer_cmm"
+ flavour_string UBSan = "ubsan"
flavour_string NoSplitSections = "no_split_sections"
flavour_string BootNonmovingGc = "boot_nonmoving_gc"
flavour_string TextWithSIMDUTF = "text_simdutf"
@@ -1196,13 +1204,17 @@ rhel_x86 =
fedora_x86 :: [JobGroup Job]
fedora_x86 =
- [ -- Fedora42 job is always built with perf so there's one job in the normal
+ [ -- Fedora43 job is always built with perf so there's one job in the normal
-- validate pipeline which is built with perf.
- fastCI (standardBuildsWithConfig Amd64 (Linux Fedora42) releaseConfig)
+ fastCI (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig)
-- This job is only for generating head.hackage docs
- , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora42) releaseConfig))
- , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora42) dwarf)
- , disableValidate (standardBuilds Amd64 (Linux Fedora42))
+ , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig))
+ , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) dwarf)
+ , disableValidate (standardBuilds Amd64 (Linux Fedora43))
+ -- For UBSan jobs, only enable for validate/nightly pipelines.
+ -- Also disable docs since it's not the point for UBSan jobs.
+ , modifyJobs (setVariable "HADRIAN_ARGS" "--docs=none") $
+ validateBuilds Amd64 (Linux Fedora43) enableUBSan
]
where
hackage_doc_job = rename (<> "-hackage") . modifyJobs (addVariable "HADRIAN_ARGS" "--haddock-for-hackage")
@@ -1364,7 +1376,7 @@ platform_mapping = Map.map go combined_result
, "x86_64-linux-deb11-validate"
, "x86_64-linux-deb12-validate"
, "x86_64-linux-deb10-validate+debug_info"
- , "x86_64-linux-fedora42-release"
+ , "x86_64-linux-fedora43-release"
, "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate"
, "x86_64-windows-validate"
, "aarch64-linux-deb12-validate"
@@ -1379,13 +1391,13 @@ platform_mapping = Map.map go combined_result
, "nightly-aarch64-linux-deb12-wine-int_native-cross_aarch64-unknown-mingw32-validate"
, "nightly-x86_64-linux-alpine3_12-validate+fully_static"
, "nightly-x86_64-linux-deb10-validate"
- , "nightly-x86_64-linux-fedora42-release"
+ , "nightly-x86_64-linux-fedora43-release"
, "nightly-x86_64-windows-validate"
, "release-x86_64-linux-alpine3_12-release+fully_static+no_split_sections"
, "release-x86_64-linux-deb10-release"
, "release-x86_64-linux-deb11-release"
, "release-x86_64-linux-deb12-release"
- , "release-x86_64-linux-fedora42-release"
+ , "release-x86_64-linux-fedora43-release"
, "release-x86_64-windows-release"
]
=====================================
.gitlab/jobs.yaml
=====================================
@@ -2942,7 +2942,7 @@
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora42-release": {
+ "nightly-x86_64-linux-fedora43-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -2953,7 +2953,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -2963,14 +2963,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -2996,16 +2996,16 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release",
+ "TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora42-release-hackage": {
+ "nightly-x86_64-linux-fedora43-release-hackage": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3016,7 +3016,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3026,14 +3026,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -3059,17 +3059,17 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release",
+ "TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora42-validate": {
+ "nightly-x86_64-linux-fedora43-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3080,7 +3080,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-validate.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3090,14 +3090,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -3123,16 +3123,16 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
"BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-validate",
+ "TEST_ENV": "x86_64-linux-fedora43-validate",
"XZ_OPT": "-9"
}
},
- "nightly-x86_64-linux-fedora42-validate+debug_info": {
+ "nightly-x86_64-linux-fedora43-validate+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -3143,7 +3143,7 @@
"artifacts": {
"expire_in": "8 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-validate+debug_info.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -3153,14 +3153,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -3186,12 +3186,76 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate+debug_info",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
"BUILD_FLAVOUR": "validate+debug_info",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-validate+debug_info",
+ "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info",
+ "XZ_OPT": "-9"
+ }
+ },
+ "nightly-x86_64-linux-fedora43-validate+ubsan": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh save_test_output",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings.txt"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "8 weeks",
+ "paths": [
+ "ghc-x86_64-linux-fedora43-validate+ubsan.tar.xz",
+ "junit.xml",
+ "unexpected-test-output.tar.gz"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+ubsan",
+ "BUILD_FLAVOUR": "validate+ubsan",
+ "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--docs=none",
+ "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "RUNTEST_ARGS": "",
+ "TEST_ENV": "x86_64-linux-fedora43-validate+ubsan",
"XZ_OPT": "-9"
}
},
@@ -4808,7 +4872,7 @@
"XZ_OPT": "-9"
}
},
- "release-x86_64-linux-fedora42-release": {
+ "release-x86_64-linux-fedora43-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -4819,7 +4883,7 @@
"artifacts": {
"expire_in": "1 year",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -4829,14 +4893,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -4862,17 +4926,17 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release",
+ "TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
- "release-x86_64-linux-fedora42-release+debug_info": {
+ "release-x86_64-linux-fedora43-release+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -4883,7 +4947,7 @@
"artifacts": {
"expire_in": "1 year",
"paths": [
- "ghc-x86_64-linux-fedora42-release+debug_info.tar.xz",
+ "ghc-x86_64-linux-fedora43-release+debug_info.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -4893,14 +4957,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -4926,17 +4990,17 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release+debug_info",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release+debug_info",
"BUILD_FLAVOUR": "release+debug_info",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release+debug_info",
+ "TEST_ENV": "x86_64-linux-fedora43-release+debug_info",
"XZ_OPT": "-9"
}
},
- "release-x86_64-linux-fedora42-release-hackage": {
+ "release-x86_64-linux-fedora43-release-hackage": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -4947,7 +5011,7 @@
"artifacts": {
"expire_in": "1 year",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -4957,14 +5021,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -4990,14 +5054,14 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"HADRIAN_ARGS": "--haddock-for-hackage",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release",
+ "TEST_ENV": "x86_64-linux-fedora43-release",
"XZ_OPT": "-9"
}
},
@@ -7032,7 +7096,7 @@
"TEST_ENV": "x86_64-linux-deb9-validate"
}
},
- "x86_64-linux-fedora42-release": {
+ "x86_64-linux-fedora43-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7043,7 +7107,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7053,14 +7117,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -7069,7 +7133,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7086,15 +7150,15 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release"
+ "TEST_ENV": "x86_64-linux-fedora43-release"
}
},
- "x86_64-linux-fedora42-release-hackage": {
+ "x86_64-linux-fedora43-release-hackage": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7105,7 +7169,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-release.tar.xz",
+ "ghc-x86_64-linux-fedora43-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7115,14 +7179,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -7131,7 +7195,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7148,16 +7212,16 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-release",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"HADRIAN_ARGS": "--haddock-for-hackage",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-release"
+ "TEST_ENV": "x86_64-linux-fedora43-release"
}
},
- "x86_64-linux-fedora42-validate": {
+ "x86_64-linux-fedora43-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7168,7 +7232,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-validate.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7178,14 +7242,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -7194,7 +7258,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7211,15 +7275,15 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
"BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-validate"
+ "TEST_ENV": "x86_64-linux-fedora43-validate"
}
},
- "x86_64-linux-fedora42-validate+debug_info": {
+ "x86_64-linux-fedora43-validate+debug_info": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
@@ -7230,7 +7294,7 @@
"artifacts": {
"expire_in": "2 weeks",
"paths": [
- "ghc-x86_64-linux-fedora42-validate+debug_info.tar.xz",
+ "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
@@ -7240,14 +7304,14 @@
"when": "always"
},
"cache": {
- "key": "x86_64-linux-fedora42-$CACHE_REV",
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
- "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora42:$DOCKER_REV",
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
"needs": [
{
"artifacts": false,
@@ -7256,7 +7320,7 @@
],
"rules": [
{
- "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora42-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
@@ -7273,12 +7337,75 @@
],
"variables": {
"BIGNUM_BACKEND": "gmp",
- "BIN_DIST_NAME": "ghc-x86_64-linux-fedora42-validate+debug_info",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
"BUILD_FLAVOUR": "validate+debug_info",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
- "TEST_ENV": "x86_64-linux-fedora42-validate+debug_info"
+ "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info"
+ }
+ },
+ "x86_64-linux-fedora43-validate+ubsan": {
+ "after_script": [
+ ".gitlab/ci.sh save_cache",
+ ".gitlab/ci.sh save_test_output",
+ ".gitlab/ci.sh clean",
+ "cat ci_timings.txt"
+ ],
+ "allow_failure": false,
+ "artifacts": {
+ "expire_in": "2 weeks",
+ "paths": [
+ "ghc-x86_64-linux-fedora43-validate+ubsan.tar.xz",
+ "junit.xml",
+ "unexpected-test-output.tar.gz"
+ ],
+ "reports": {
+ "junit": "junit.xml"
+ },
+ "when": "always"
+ },
+ "cache": {
+ "key": "x86_64-linux-fedora43-$CACHE_REV",
+ "paths": [
+ "cabal-cache",
+ "toolchain"
+ ]
+ },
+ "dependencies": [],
+ "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV",
+ "needs": [
+ {
+ "artifacts": false,
+ "job": "hadrian-ghc-in-ghci"
+ }
+ ],
+ "rules": [
+ {
+ "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+ubsan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+ "when": "on_success"
+ }
+ ],
+ "script": [
+ "sudo chown ghc:ghc -R .",
+ ".gitlab/ci.sh setup",
+ ".gitlab/ci.sh configure",
+ ".gitlab/ci.sh build_hadrian",
+ ".gitlab/ci.sh test_hadrian"
+ ],
+ "stage": "full-build",
+ "tags": [
+ "x86_64-linux"
+ ],
+ "variables": {
+ "BIGNUM_BACKEND": "gmp",
+ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+ubsan",
+ "BUILD_FLAVOUR": "validate+ubsan",
+ "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "HADRIAN_ARGS": "--docs=none",
+ "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
+ "RUNTEST_ARGS": "",
+ "TEST_ENV": "x86_64-linux-fedora43-validate+ubsan"
}
},
"x86_64-linux-rocky8-validate": {
=====================================
.gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
=====================================
@@ -23,8 +23,8 @@ def job_triple(job_name):
'release-x86_64-linux-ubuntu22_04-release': 'x86_64-ubuntu22_04-linux',
'release-x86_64-linux-ubuntu20_04-release': 'x86_64-ubuntu20_04-linux',
'release-x86_64-linux-ubuntu18_04-release': 'x86_64-ubuntu18_04-linux',
- 'release-x86_64-linux-fedora42-release': 'x86_64-fedora42-linux',
- 'release-x86_64-linux-fedora42-release+debug_info': 'x86_64-fedora42-linux-dwarf',
+ 'release-x86_64-linux-fedora43-release': 'x86_64-fedora43-linux',
+ 'release-x86_64-linux-fedora43-release+debug_info': 'x86_64-fedora43-linux-dwarf',
'release-x86_64-linux-deb12-release': 'x86_64-deb12-linux',
'release-x86_64-linux-deb11-release': 'x86_64-deb11-linux',
'release-x86_64-linux-deb10-release+debug_info': 'x86_64-deb10-linux-dwarf',
=====================================
.gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
=====================================
@@ -200,7 +200,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map):
ubuntu2204 = mk(ubuntu("22_04"))
ubuntu2404 = mk(ubuntu("24_04"))
rocky8 = mk(rocky("8"))
- fedora42 = mk(fedora(42))
+ fedora43 = mk(fedora(43))
darwin_x86 = mk(darwin("x86_64"))
darwin_arm64 = mk(darwin("aarch64"))
windows = mk(windowsArtifact)
@@ -239,7 +239,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map):
, "unknown_versioning": ubuntu2004 }
, "Linux_CentOS" : { "( >= 8 && < 9 )" : rocky8
, "unknown_versioning" : rocky8 }
- , "Linux_Fedora" : { ">= 42": fedora42
+ , "Linux_Fedora" : { ">= 43": fedora43
, "unknown_versioning": rocky8 }
, "Linux_RedHat" : { "unknown_versioning": rocky8 }
, "Linux_UnknownLinux" : { "unknown_versioning": rocky8 }
=====================================
configure.ac
=====================================
@@ -526,7 +526,7 @@ AC_SUBST(InstallNameToolCmd)
# versions of LLVM simultaneously, but that stopped working around
# 3.5/3.6 release of LLVM.
LlvmMinVersion=13 # inclusive
-LlvmMaxVersion=21 # not inclusive
+LlvmMaxVersion=22 # not inclusive
AC_SUBST([LlvmMinVersion])
AC_SUBST([LlvmMaxVersion])
=====================================
hadrian/doc/flavours.md
=====================================
@@ -238,6 +238,10 @@ The supported transformers are listed below:
<td><code>thread_sanitizer</code></td>
<td>Build the runtime system with ThreadSanitizer support</td>
</tr>
+ <tr>
+ <td><code>ubsan</code></td>
+ <td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td>
+ </tr>
<tr>
<td><code>llvm</code></td>
<td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td>
=====================================
hadrian/src/Flavour.hs
=====================================
@@ -7,6 +7,7 @@ module Flavour
, addArgs
, splitSections
, enableThreadSanitizer
+ , enableUBSan
, enableLateCCS
, enableHashUnitIds
, enableDebugInfo, enableTickyGhc
@@ -33,6 +34,9 @@ import Data.Either
import Data.Map (Map)
import qualified Data.Map as M
import qualified Data.Set as Set
+import GHC.Platform.ArchOS
+import Oracles.Flag
+import Oracles.Setting
import Packages
import Flavour.Type
import Settings.Parser
@@ -53,6 +57,7 @@ flavourTransformers = M.fromList
, "no_split_sections" =: noSplitSections
, "thread_sanitizer" =: enableThreadSanitizer False
, "thread_sanitizer_cmm" =: enableThreadSanitizer True
+ , "ubsan" =: enableUBSan
, "llvm" =: viaLlvmBackend
, "profiled_ghc" =: enableProfiledGhc
, "no_dynamic_ghc" =: disableDynamicGhcPrograms
@@ -258,6 +263,66 @@ enableThreadSanitizer instrumentCmm = addArgs $ notStage0 ? mconcat
]
]
+-- | Whether or not -shared-libsan should be passed to clang at
+-- link-time.
+--
+-- See
+-- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.5/clang/lib/Driver/S…,
+-- clang defaults to -shared-libsan on darwin/windows and
+-- -static-libsan on linux. In general, -static-libsan is incredibly
+-- problematic when multiple copies of the sanitizer runtimes coexist
+-- in the same address space due to being linked into multiple Haskell
+-- libraries. So we should explicitly specify `-shared-libsan` if
+-- needed.
+--
+-- A small downside of -shared-libsan is the clang-specific sanitizer
+-- runtime shared library path needs to be manually specified via
+-- @export LD_LIBRARY_PATH=$(dirname $(clang -print-libgcc-file-name
+-- -rtlib=compiler-rt))@ for ld.so to find it at runtime.
+needSharedLibSAN :: Action Bool
+needSharedLibSAN = do
+ is_clang <- flag CcLlvmBackend
+ is_default_shared_libsan <- anyTargetOs [OSDarwin, OSMinGW32]
+ pure $ is_clang && not is_default_shared_libsan
+
+-- | Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer
+-- support:
+-- https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html.
+--
+-- Note that we also pass -fno-sanitize=function to clang, since
+-- "runtime call to function foo through pointer to incorrect function
+-- type" is unfortunately pretty common (e.g. evac_fn in rts) and
+-- impact the signal to noise ratio of UBSan warnings. gcc doesn't
+-- implement this instrumentation though.
+enableUBSan :: Flavour -> Flavour
+enableUBSan =
+ addArgs $
+ notStage0
+ ? mconcat
+ [ package rts
+ ? builder (Cabal Flags)
+ ? arg "+ubsan"
+ <> (needSharedLibSAN ? arg "+shared-libsan"),
+ builder (Ghc CompileHs)
+ ? arg "-optc-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Ghc CompileCWithGhc)
+ ? arg "-optc-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Ghc CompileCppWithGhc)
+ ? arg "optcxx-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optcxx-fno-sanitize=function"),
+ builder (Ghc LinkHs)
+ ? arg "-optc-fsanitize=undefined"
+ <> arg "-optl-fsanitize=undefined"
+ <> (needSharedLibSAN ? arg "-optl-shared-libsan")
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Cc CompileC)
+ ? arg "-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-fno-sanitize=function"),
+ builder Testsuite ? arg "--config=have_ubsan=True"
+ ]
+
-- | Use the LLVM backend in stages 1 and later.
viaLlvmBackend :: Flavour -> Flavour
viaLlvmBackend = addArgs $ notStage0 ? builder Ghc ? arg "-fllvm"
=====================================
rts/rts.cabal
=====================================
@@ -91,6 +91,19 @@ flag thread-sanitizer
in @rts/include/rts/TSANUtils.h@.
default: False
manual: True
+flag ubsan
+ description:
+ Link with -fsanitize=undefined, to be enabled when building with
+ UndefinedBehaviorSanitizer.
+ default: False
+ manual: True
+flag shared-libsan
+ description:
+ Link with -shared-libsan, to guarantee only one copy of the
+ sanitizer runtimes exist in the address space. See
+ needSharedLibSAN in hadrian/src/Flavour.hs.
+ default: False
+ manual: True
library
-- rts is a wired in package and
@@ -200,6 +213,12 @@ library
cc-options: -fsanitize=thread
ld-options: -fsanitize=thread
+ if flag(ubsan)
+ ld-options: -fsanitize=undefined
+
+ if flag(shared-libsan)
+ ld-options: -shared-libsan
+
if os(linux)
-- the RTS depends upon libc. while this dependency is generally
-- implicitly added by `cc`, we must explicitly add it here to ensure
=====================================
testsuite/driver/testglobals.py
=====================================
@@ -186,6 +186,9 @@ class TestConfig:
# Are we running in a ThreadSanitizer-instrumented build?
self.have_thread_sanitizer = False
+ # Are we running with UndefinedBehaviorSanitizer enabled?
+ self.have_ubsan = False
+
# Do symbols use leading underscores?
self.leading_underscore = False
=====================================
testsuite/driver/testlib.py
=====================================
@@ -1090,6 +1090,8 @@ def llvm_build ( ) -> bool:
def have_thread_sanitizer( ) -> bool:
return config.have_thread_sanitizer
+def have_ubsan( ) -> bool:
+ return config.have_ubsan
def gcc_as_cmmp() -> bool:
return config.cmm_cpp_is_gcc
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cf983a083bb8b251eff4f8a0aacf4…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cf983a083bb8b251eff4f8a0aacf4…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Remove the `CoreBindings` constructor from `LinkablePart`
by Marge Bot (@marge-bot) 08 Nov '25
by Marge Bot (@marge-bot) 08 Nov '25
08 Nov '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
b253013e by Georgios Karachalias at 2025-11-07T17:21:57-05:00
Remove the `CoreBindings` constructor from `LinkablePart`
Adjust HscRecompStatus to disallow unhydrated WholeCoreBindings
from being passed as input to getLinkDeps (which would previously
panic in this case).
Fixes #26497
- - - - -
ac7b737e by Sylvain Henry at 2025-11-07T17:22:51-05:00
Testsuite: pass ext-interp test way (#26552)
Note that some tests are still marked as broken with the ext-interp way
(see #26552 and #14335)
- - - - -
04abb6bf by Vladislav Zavialov at 2025-11-08T08:52:11-05:00
Comments only in GHC.Parser.PostProcess.Haddock
Remove outdated Note [Register keyword location], as the issue it describes
was addressed by commit 05eb50dff2fcc78d025e77b9418ddb369db49b9f.
- - - - -
dc1cb4be by ARATA Mizuki at 2025-11-08T08:52:23-05:00
Fix the order of spill/reload instructions
The AArch64 NCG could emit multiple instructions for a single spill/reload,
but their order was not consistent between the definition and a use.
Fixes #26537
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
19 changed files:
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- libraries/base/tests/all.T
- testsuite/driver/testlib.py
- + testsuite/tests/codeGen/should_run/T26537.hs
- + testsuite/tests/codeGen/should_run/T26537.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/driver/T20696/all.T
- testsuite/tests/driver/fat-iface/all.T
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/splice-imports/all.T
Changes:
=====================================
compiler/GHC/CmmToAsm/Reg/Liveness.hs
=====================================
@@ -48,6 +48,7 @@ import GHC.Cmm
import GHC.CmmToAsm.Reg.Target
import GHC.Data.Graph.Directed
+import GHC.Data.OrdList
import GHC.Utils.Monad
import GHC.Utils.Outputable
import GHC.Utils.Panic
@@ -562,30 +563,26 @@ stripLiveBlock config (BasicBlock i lis)
= BasicBlock i instrs'
where (instrs', _)
- = runState (spillNat [] lis) 0
+ = runState (spillNat nilOL lis) 0
- -- spillNat :: [instr] -> [LiveInstr instr] -> State Int [instr]
- spillNat :: Instruction instr => [instr] -> [LiveInstr instr] -> State Int [instr]
+ spillNat :: Instruction instr => OrdList instr -> [LiveInstr instr] -> State Int [instr]
spillNat acc []
- = return (reverse acc)
+ = return (fromOL acc)
- -- The SPILL/RELOAD cases do not appear to be exercised by our codegens
- --
spillNat acc (LiveInstr (SPILL reg slot) _ : instrs)
= do delta <- get
- spillNat (mkSpillInstr config reg delta slot ++ acc) instrs
+ spillNat (acc `appOL` toOL (mkSpillInstr config reg delta slot)) instrs
spillNat acc (LiveInstr (RELOAD slot reg) _ : instrs)
= do delta <- get
- spillNat (mkLoadInstr config reg delta slot ++ acc) instrs
+ spillNat (acc `appOL` toOL (mkLoadInstr config reg delta slot)) instrs
spillNat acc (LiveInstr (Instr instr) _ : instrs)
| Just i <- takeDeltaInstr instr
= do put i
spillNat acc instrs
-
- spillNat acc (LiveInstr (Instr instr) _ : instrs)
- = spillNat (instr : acc) instrs
+ | otherwise
+ = spillNat (acc `snocOL` instr) instrs
-- | Erase Delta instructions.
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -277,6 +277,7 @@ import Data.Data hiding (Fixity, TyCon)
import Data.Functor ((<&>))
import Data.List ( nub, isPrefixOf, partition )
import qualified Data.List.NonEmpty as NE
+import Data.Traversable (for)
import Control.Monad
import Data.IORef
import System.FilePath as FilePath
@@ -850,11 +851,11 @@ hscRecompStatus
if | not (backendGeneratesCode (backend lcl_dflags)) -> do
-- No need for a linkable, we're good to go
msg UpToDate
- return $ HscUpToDate checked_iface emptyHomeModInfoLinkable
+ return $ HscUpToDate checked_iface emptyRecompLinkables
| not (backendGeneratesCodeForHsBoot (backend lcl_dflags))
, IsBoot <- isBootSummary mod_summary -> do
msg UpToDate
- return $ HscUpToDate checked_iface emptyHomeModInfoLinkable
+ return $ HscUpToDate checked_iface emptyRecompLinkables
-- Always recompile with the JS backend when TH is enabled until
-- #23013 is fixed.
@@ -883,7 +884,7 @@ hscRecompStatus
let just_o = justObjects <$> obj_linkable
bytecode_or_object_code
- | gopt Opt_WriteByteCode lcl_dflags = justBytecode <$> definitely_bc
+ | gopt Opt_WriteByteCode lcl_dflags = justBytecode . Left <$> definitely_bc
| otherwise = (justBytecode <$> maybe_bc) `choose` just_o
@@ -900,13 +901,13 @@ hscRecompStatus
definitely_bc = bc_obj_linkable `prefer` bc_in_memory_linkable
-- If not -fwrite-byte-code, then we could use core bindings or object code if that's available.
- maybe_bc = bc_in_memory_linkable `choose`
- bc_obj_linkable `choose`
- bc_core_linkable
+ maybe_bc = (Left <$> bc_in_memory_linkable) `choose`
+ (Left <$> bc_obj_linkable) `choose`
+ (Right <$> bc_core_linkable)
bc_result = if gopt Opt_WriteByteCode lcl_dflags
-- If the byte-code artifact needs to be produced, then we certainly need bytecode.
- then definitely_bc
+ then Left <$> definitely_bc
else maybe_bc
trace_if (hsc_logger hsc_env)
@@ -1021,14 +1022,13 @@ checkByteCodeFromObject hsc_env mod_sum = do
-- | Attempt to load bytecode from whole core bindings in the interface if they exist.
-- This is a legacy code-path, these days it should be preferred to use the bytecode object linkable.
-checkByteCodeFromIfaceCoreBindings :: HscEnv -> ModIface -> ModSummary -> IO (MaybeValidated Linkable)
+checkByteCodeFromIfaceCoreBindings :: HscEnv -> ModIface -> ModSummary -> IO (MaybeValidated WholeCoreBindingsLinkable)
checkByteCodeFromIfaceCoreBindings _hsc_env iface mod_sum = do
let
this_mod = ms_mod mod_sum
if_date = fromJust $ ms_iface_date mod_sum
case iface_core_bindings iface (ms_location mod_sum) of
- Just fi -> do
- return (UpToDateItem (Linkable if_date this_mod (NE.singleton (CoreBindings fi))))
+ Just fi -> return $ UpToDateItem (Linkable if_date this_mod fi)
_ -> return $ outOfDateItemBecause MissingBytecode Nothing
--------------------------------------------------------------
@@ -1142,20 +1142,22 @@ initWholeCoreBindings ::
HscEnv ->
ModIface ->
ModDetails ->
- Linkable ->
- IO Linkable
-initWholeCoreBindings hsc_env iface details (Linkable utc_time this_mod uls) = do
- Linkable utc_time this_mod <$> mapM (go hsc_env) uls
+ RecompLinkables ->
+ IO HomeModLinkable
+initWholeCoreBindings hsc_env iface details (RecompLinkables bc o) = do
+ bc' <- go bc
+ pure $ HomeModLinkable bc' o
where
- go hsc_env' = \case
- CoreBindings wcb -> do
+ type_env = md_types details
+
+ go :: RecompBytecodeLinkable -> IO (Maybe Linkable)
+ go (NormalLinkable l) = pure l
+ go (WholeCoreBindingsLinkable wcbl) =
+ fmap Just $ for wcbl $ \wcb -> do
add_iface_to_hpt iface details hsc_env
bco <- unsafeInterleaveIO $
- compileWholeCoreBindings hsc_env' type_env wcb
- pure (DotGBC bco)
- l -> pure l
-
- type_env = md_types details
+ compileWholeCoreBindings hsc_env type_env wcb
+ pure $ NE.singleton (DotGBC bco)
-- | Hydrate interface Core bindings and compile them to bytecode.
--
=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -109,6 +109,7 @@ import GHC.Unit.Env
import GHC.Unit.Finder
import GHC.Unit.Module.ModSummary
import GHC.Unit.Module.ModIface
+import GHC.Unit.Module.Status
import GHC.Unit.Home.ModInfo
import GHC.Unit.Home.PackageTable
@@ -249,8 +250,8 @@ compileOne' mHscMessage
(iface, linkable) <- runPipeline (hsc_hooks plugin_hsc_env) pipeline
-- See Note [ModDetails and --make mode]
details <- initModDetails plugin_hsc_env iface
- linkable' <- traverse (initWholeCoreBindings plugin_hsc_env iface details) (homeMod_bytecode linkable)
- return $! HomeModInfo iface details (linkable { homeMod_bytecode = linkable' })
+ linkable' <- initWholeCoreBindings plugin_hsc_env iface details linkable
+ return $! HomeModInfo iface details linkable'
where lcl_dflags = ms_hspp_opts summary
location = ms_location summary
@@ -759,7 +760,7 @@ preprocessPipeline pipe_env hsc_env input_fn = do
$ phaseIfFlag hsc_env flag def action
-- | The complete compilation pipeline, from start to finish
-fullPipeline :: P m => PipeEnv -> HscEnv -> FilePath -> HscSource -> m (ModIface, HomeModLinkable)
+fullPipeline :: P m => PipeEnv -> HscEnv -> FilePath -> HscSource -> m (ModIface, RecompLinkables)
fullPipeline pipe_env hsc_env pp_fn src_flavour = do
(dflags, input_fn) <- preprocessPipeline pipe_env hsc_env pp_fn
let hsc_env' = hscSetFlags dflags hsc_env
@@ -768,7 +769,7 @@ fullPipeline pipe_env hsc_env pp_fn src_flavour = do
hscPipeline pipe_env (hsc_env_with_plugins, mod_sum, hsc_recomp_status)
-- | Everything after preprocess
-hscPipeline :: P m => PipeEnv -> ((HscEnv, ModSummary, HscRecompStatus)) -> m (ModIface, HomeModLinkable)
+hscPipeline :: P m => PipeEnv -> (HscEnv, ModSummary, HscRecompStatus) -> m (ModIface, RecompLinkables)
hscPipeline pipe_env (hsc_env_with_plugins, mod_sum, hsc_recomp_status) = do
case hsc_recomp_status of
HscUpToDate iface mb_linkable -> return (iface, mb_linkable)
@@ -777,7 +778,7 @@ hscPipeline pipe_env (hsc_env_with_plugins, mod_sum, hsc_recomp_status) = do
hscBackendAction <- use (T_HscPostTc hsc_env_with_plugins mod_sum tc_result warnings mb_old_hash )
hscBackendPipeline pipe_env hsc_env_with_plugins mod_sum hscBackendAction
-hscBackendPipeline :: P m => PipeEnv -> HscEnv -> ModSummary -> HscBackendAction -> m (ModIface, HomeModLinkable)
+hscBackendPipeline :: P m => PipeEnv -> HscEnv -> ModSummary -> HscBackendAction -> m (ModIface, RecompLinkables)
hscBackendPipeline pipe_env hsc_env mod_sum result =
if backendGeneratesCode (backend (hsc_dflags hsc_env)) then
do
@@ -796,15 +797,15 @@ hscBackendPipeline pipe_env hsc_env mod_sum result =
return res
else
case result of
- HscUpdate iface -> return (iface, emptyHomeModInfoLinkable)
- HscRecomp {} -> (,) <$> liftIO (mkFullIface hsc_env (hscs_partial_iface result) Nothing Nothing NoStubs []) <*> pure emptyHomeModInfoLinkable
+ HscUpdate iface -> return (iface, emptyRecompLinkables)
+ HscRecomp {} -> (,) <$> liftIO (mkFullIface hsc_env (hscs_partial_iface result) Nothing Nothing NoStubs []) <*> pure emptyRecompLinkables
hscGenBackendPipeline :: P m
=> PipeEnv
-> HscEnv
-> ModSummary
-> HscBackendAction
- -> m (ModIface, HomeModLinkable)
+ -> m (ModIface, RecompLinkables)
hscGenBackendPipeline pipe_env hsc_env mod_sum result = do
let mod_name = moduleName (ms_mod mod_sum)
src_flavour = (ms_hsc_src mod_sum)
@@ -812,7 +813,7 @@ hscGenBackendPipeline pipe_env hsc_env mod_sum result = do
(fos, miface, mlinkable, o_file) <- use (T_HscBackend pipe_env hsc_env mod_name src_flavour location result)
final_fp <- hscPostBackendPipeline pipe_env hsc_env (ms_hsc_src mod_sum) (backend (hsc_dflags hsc_env)) (Just location) o_file
final_linkable <-
- case final_fp of
+ safeCastHomeModLinkable <$> case final_fp of
-- No object file produced, bytecode or NoBackend
Nothing -> return mlinkable
Just o_fp -> do
@@ -936,7 +937,7 @@ pipelineStart pipe_env hsc_env input_fn mb_phase =
as :: P m => Bool -> m (Maybe FilePath)
as use_cpp = asPipeline use_cpp pipe_env hsc_env Nothing input_fn
- objFromLinkable (_, homeMod_object -> Just (Linkable _ _ (DotO lnk _ :| []))) = Just lnk
+ objFromLinkable (_, recompLinkables_object -> Just (Linkable _ _ (DotO lnk _ :| []))) = Just lnk
objFromLinkable _ = Nothing
fromPhase :: P m => Phase -> m (Maybe FilePath)
=====================================
compiler/GHC/Linker/Deps.hs
=====================================
@@ -33,7 +33,6 @@ import GHC.Utils.Error
import GHC.Unit.Env
import GHC.Unit.Finder
import GHC.Unit.Module
-import GHC.Unit.Module.WholeCoreBindings
import GHC.Unit.Home.ModInfo
import GHC.Iface.Errors.Types
@@ -206,10 +205,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
DotO file ForeignObject -> pure (DotO file ForeignObject)
DotA fp -> panic ("adjust_ul DotA " ++ show fp)
DotDLL fp -> panic ("adjust_ul DotDLL " ++ show fp)
- DotGBC {} -> pure part
- CoreBindings WholeCoreBindings {wcb_module} ->
- pprPanic "Unhydrated core bindings" (ppr wcb_module)
-
+ DotGBC {} -> pure part
{-
=====================================
compiler/GHC/Linker/Types.hs
=====================================
@@ -1,5 +1,6 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE DeriveTraversable #-}
-----------------------------------------------------------------------------
--
@@ -30,7 +31,9 @@ module GHC.Linker.Types
, PkgsLoaded
-- * Linkable
- , Linkable(..)
+ , Linkable
+ , WholeCoreBindingsLinkable
+ , LinkableWith(..)
, mkModuleByteCodeLinkable
, LinkablePart(..)
, LinkableObjectSort (..)
@@ -254,7 +257,7 @@ instance Outputable LoadedPkgInfo where
-- | Information we can use to dynamically link modules into the compiler
-data Linkable = Linkable
+data LinkableWith parts = Linkable
{ linkableTime :: !UTCTime
-- ^ Time at which this linkable was built
-- (i.e. when the bytecodes were produced,
@@ -263,9 +266,13 @@ data Linkable = Linkable
, linkableModule :: !Module
-- ^ The linkable module itself
- , linkableParts :: NonEmpty LinkablePart
+ , linkableParts :: parts
-- ^ Files and chunks of code to link.
- }
+ } deriving (Functor, Traversable, Foldable)
+
+type Linkable = LinkableWith (NonEmpty LinkablePart)
+
+type WholeCoreBindingsLinkable = LinkableWith WholeCoreBindings
type LinkableSet = ModuleEnv Linkable
@@ -282,7 +289,7 @@ unionLinkableSet = plusModuleEnv_C go
| linkableTime l1 > linkableTime l2 = l1
| otherwise = l2
-instance Outputable Linkable where
+instance Outputable a => Outputable (LinkableWith a) where
ppr (Linkable when_made mod parts)
= (text "Linkable" <+> parens (text (show when_made)) <+> ppr mod)
$$ nest 3 (ppr parts)
@@ -318,11 +325,6 @@ data LinkablePart
| DotDLL FilePath
-- ^ Dynamically linked library file (.so, .dll, .dylib)
- | CoreBindings WholeCoreBindings
- -- ^ Serialised core which we can turn into BCOs (or object files), or
- -- used by some other backend See Note [Interface Files with Core
- -- Definitions]
-
| DotGBC ModuleByteCode
-- ^ A byte-code object, lives only in memory.
@@ -350,7 +352,6 @@ instance Outputable LinkablePart where
ppr (DotA path) = text "DotA" <+> text path
ppr (DotDLL path) = text "DotDLL" <+> text path
ppr (DotGBC bco) = text "DotGBC" <+> ppr bco
- ppr (CoreBindings {}) = text "CoreBindings"
-- | Return true if the linkable only consists of native code (no BCO)
linkableIsNativeCodeOnly :: Linkable -> Bool
@@ -391,7 +392,6 @@ isNativeCode = \case
DotA {} -> True
DotDLL {} -> True
DotGBC {} -> False
- CoreBindings {} -> False
-- | Is the part a native library? (.so/.dll)
isNativeLib :: LinkablePart -> Bool
@@ -400,7 +400,6 @@ isNativeLib = \case
DotA {} -> True
DotDLL {} -> True
DotGBC {} -> False
- CoreBindings {} -> False
-- | Get the FilePath of linkable part (if applicable)
linkablePartPath :: LinkablePart -> Maybe FilePath
@@ -408,7 +407,6 @@ linkablePartPath = \case
DotO fn _ -> Just fn
DotA fn -> Just fn
DotDLL fn -> Just fn
- CoreBindings {} -> Nothing
DotGBC {} -> Nothing
-- | Return the paths of all object code files (.o, .a, .so) contained in this
@@ -418,7 +416,6 @@ linkablePartNativePaths = \case
DotO fn _ -> [fn]
DotA fn -> [fn]
DotDLL fn -> [fn]
- CoreBindings {} -> []
DotGBC {} -> []
-- | Return the paths of all object files (.o) contained in this 'LinkablePart'.
@@ -427,7 +424,6 @@ linkablePartObjectPaths = \case
DotO fn _ -> [fn]
DotA _ -> []
DotDLL _ -> []
- CoreBindings {} -> []
DotGBC bco -> gbc_foreign_files bco
-- | Retrieve the compiled byte-code from the linkable part.
@@ -444,12 +440,11 @@ linkableFilter f linkable = do
Just linkable {linkableParts = new}
linkablePartNative :: LinkablePart -> [LinkablePart]
-linkablePartNative = \case
- u@DotO {} -> [u]
- u@DotA {} -> [u]
- u@DotDLL {} -> [u]
+linkablePartNative u = case u of
+ DotO {} -> [u]
+ DotA {} -> [u]
+ DotDLL {} -> [u]
DotGBC bco -> [DotO f ForeignObject | f <- gbc_foreign_files bco]
- _ -> []
linkablePartByteCode :: LinkablePart -> [LinkablePart]
linkablePartByteCode = \case
=====================================
compiler/GHC/Parser/PostProcess/Haddock.hs
=====================================
@@ -1115,7 +1115,6 @@ runHdkA (HdkA _ m) = unHdkM m mempty
-- To take it into account, we must register its location using registerLocHdkA
-- or registerHdkA.
--
--- See Note [Register keyword location].
-- See Note [Adding Haddock comments to the syntax tree].
registerLocHdkA :: SrcSpan -> HdkA ()
registerLocHdkA l = HdkA (getBufSpan l) (pure ())
@@ -1544,18 +1543,3 @@ that GHC could parse successfully:
This declaration was accepted by ghc but rejected by ghc -haddock.
-}
-
-{- Note [Register keyword location]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-At the moment, 'addHaddock' erroneously associates some comments with
-constructs that are separated by a keyword. For example:
-
- data Foo -- | Comment for MkFoo
- where MkFoo :: Foo
-
-We could use EPA (exactprint annotations) to fix this, but not without
-modification. For example, EpaLocation contains RealSrcSpan but not BufSpan.
-Also, the fix would be more straightforward after #19623.
-
-For examples, see tests/haddock/should_compile_flag_haddock/T17544_kw.hs
--}
=====================================
compiler/GHC/Unit/Home/ModInfo.hs
=====================================
@@ -3,13 +3,10 @@
module GHC.Unit.Home.ModInfo
(
HomeModInfo (..)
- , HomeModLinkable(..)
+ , HomeModLinkable (..)
, homeModInfoObject
, homeModInfoByteCode
, emptyHomeModInfoLinkable
- , justBytecode
- , justObjects
- , bytecodeAndObjects
)
where
@@ -18,11 +15,9 @@ import GHC.Prelude
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.ModDetails
-import GHC.Linker.Types ( Linkable(..), linkableIsNativeCodeOnly )
+import GHC.Linker.Types ( Linkable )
import GHC.Utils.Outputable
-import GHC.Utils.Panic
-
-- | Information about modules in the package being compiled
data HomeModInfo = HomeModInfo
@@ -68,22 +63,6 @@ data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable)
instance Outputable HomeModLinkable where
ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2
-justBytecode :: Linkable -> HomeModLinkable
-justBytecode lm =
- assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm)
- $ emptyHomeModInfoLinkable { homeMod_bytecode = Just lm }
-
-justObjects :: Linkable -> HomeModLinkable
-justObjects lm =
- assertPpr (linkableIsNativeCodeOnly lm) (ppr lm)
- $ emptyHomeModInfoLinkable { homeMod_object = Just lm }
-
-bytecodeAndObjects :: Linkable -> Linkable -> HomeModLinkable
-bytecodeAndObjects bc o =
- assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o)
- (HomeModLinkable (Just bc) (Just o))
-
-
{-
Note [Home module build products]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Unit/Module/Status.hs
=====================================
@@ -1,22 +1,35 @@
+{-# LANGUAGE LambdaCase #-}
+
module GHC.Unit.Module.Status
- ( HscBackendAction(..), HscRecompStatus (..)
+ ( HscBackendAction(..)
+ , HscRecompStatus (..)
+ , RecompLinkables (..)
+ , RecompBytecodeLinkable (..)
+ , emptyRecompLinkables
+ , justBytecode
+ , justObjects
+ , bytecodeAndObjects
+ , safeCastHomeModLinkable
)
where
import GHC.Prelude
import GHC.Unit
+import GHC.Unit.Home.ModInfo
import GHC.Unit.Module.ModGuts
import GHC.Unit.Module.ModIface
+import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly )
+
import GHC.Utils.Fingerprint
import GHC.Utils.Outputable
-import GHC.Unit.Home.ModInfo
+import GHC.Utils.Panic
-- | Status of a module in incremental compilation
data HscRecompStatus
-- | Nothing to do because code already exists.
- = HscUpToDate ModIface HomeModLinkable
+ = HscUpToDate ModIface RecompLinkables
-- | Recompilation of module, or update of interface is required. Optionally
-- pass the old interface hash to avoid updating the existing interface when
-- it has not changed.
@@ -41,6 +54,16 @@ data HscBackendAction
-- changed.
}
+-- | Linkables produced by @hscRecompStatus@. Might contain serialized core
+-- which can be turned into BCOs (or object files), or used by some other
+-- backend. See Note [Interface Files with Core Definitions].
+data RecompLinkables = RecompLinkables { recompLinkables_bytecode :: !RecompBytecodeLinkable
+ , recompLinkables_object :: !(Maybe Linkable) }
+
+data RecompBytecodeLinkable
+ = NormalLinkable !(Maybe Linkable)
+ | WholeCoreBindingsLinkable !WholeCoreBindingsLinkable
+
instance Outputable HscRecompStatus where
ppr HscUpToDate{} = text "HscUpToDate"
ppr HscRecompNeeded{} = text "HscRecompNeeded"
@@ -48,3 +71,37 @@ instance Outputable HscRecompStatus where
instance Outputable HscBackendAction where
ppr (HscUpdate mi) = text "Update:" <+> (ppr (mi_module mi))
ppr (HscRecomp _ ml _mi _mf) = text "Recomp:" <+> ppr ml
+
+instance Outputable RecompLinkables where
+ ppr (RecompLinkables l1 l2) = ppr l1 $$ ppr l2
+
+instance Outputable RecompBytecodeLinkable where
+ ppr (NormalLinkable lm) = text "NormalLinkable:" <+> ppr lm
+ ppr (WholeCoreBindingsLinkable lm) = text "WholeCoreBindingsLinkable:" <+> ppr lm
+
+emptyRecompLinkables :: RecompLinkables
+emptyRecompLinkables = RecompLinkables (NormalLinkable Nothing) Nothing
+
+safeCastHomeModLinkable :: HomeModLinkable -> RecompLinkables
+safeCastHomeModLinkable (HomeModLinkable bc o) = RecompLinkables (NormalLinkable bc) o
+
+justBytecode :: Either Linkable WholeCoreBindingsLinkable -> RecompLinkables
+justBytecode = \case
+ Left lm ->
+ assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm)
+ $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just lm) }
+ Right lm -> emptyRecompLinkables { recompLinkables_bytecode = WholeCoreBindingsLinkable lm }
+
+justObjects :: Linkable -> RecompLinkables
+justObjects lm =
+ assertPpr (linkableIsNativeCodeOnly lm) (ppr lm)
+ $ emptyRecompLinkables { recompLinkables_object = Just lm }
+
+bytecodeAndObjects :: Either Linkable WholeCoreBindingsLinkable -> Linkable -> RecompLinkables
+bytecodeAndObjects either_bc o = case either_bc of
+ Left bc ->
+ assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o)
+ $ RecompLinkables (NormalLinkable (Just bc)) (Just o)
+ Right bc ->
+ assertPpr (linkableIsNativeCodeOnly o) (ppr o)
+ $ RecompLinkables (WholeCoreBindingsLinkable bc) (Just o)
=====================================
compiler/GHC/Unit/Module/WholeCoreBindings.hs
=====================================
@@ -130,6 +130,9 @@ data WholeCoreBindings = WholeCoreBindings
, wcb_foreign :: IfaceForeign
}
+instance Outputable WholeCoreBindings where
+ ppr (WholeCoreBindings {}) = text "WholeCoreBindings"
+
{-
Note [Foreign stubs and TH bytecode linking]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
libraries/base/tests/all.T
=====================================
@@ -80,7 +80,7 @@ test('length001',
# excessive amounts of stack space. So we specifically set a low
# stack limit and mark it as failing under a few conditions.
[extra_run_opts('+RTS -K8m -RTS'),
- expect_fail_for(['normal', 'threaded1', 'llvm', 'nonmoving', 'nonmoving_thr', 'nonmoving_thr_ghc']),
+ expect_fail_for(['normal', 'threaded1', 'llvm', 'nonmoving', 'nonmoving_thr', 'nonmoving_thr_ghc', 'ext-interp']),
# JS doesn't support stack limit so the test sometimes passes just fine. Therefore the test is
# marked as fragile.
when(js_arch(), fragile(22921))],
=====================================
testsuite/driver/testlib.py
=====================================
@@ -352,6 +352,9 @@ def req_plugins( name, opts ):
"""
req_interp(name, opts)
+ # Plugins aren't supported with the external interpreter (#14335)
+ expect_broken_for(14335,['ext-interp'])(name,opts)
+
if config.cross:
opts.skip = True
=====================================
testsuite/tests/codeGen/should_run/T26537.hs
=====================================
@@ -0,0 +1,72 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+import GHC.Exts
+
+type D8 = (# Double#, Double#, Double#, Double#, Double#, Double#, Double#, Double# #)
+type D64 = (# D8, D8, D8, D8, D8, D8, D8, D8 #)
+type D512 = (# D64, D64, D64, D64, D64, D64, D64, D64 #)
+
+unD# :: Double -> Double#
+unD# (D# x) = x
+
+mkD8 :: Double -> D8
+mkD8 x = (# unD# x, unD# (x + 1), unD# (x + 2), unD# (x + 3), unD# (x + 4), unD# (x + 5), unD# (x + 6), unD# (x + 7) #)
+{-# NOINLINE mkD8 #-}
+
+mkD64 :: Double -> D64
+mkD64 x = (# mkD8 x, mkD8 (x + 8), mkD8 (x + 16), mkD8 (x + 24), mkD8 (x + 32), mkD8 (x + 40), mkD8 (x + 48), mkD8 (x + 56) #)
+{-# NOINLINE mkD64 #-}
+
+mkD512 :: Double -> D512
+mkD512 x = (# mkD64 x, mkD64 (x + 64), mkD64 (x + 128), mkD64 (x + 192), mkD64 (x + 256), mkD64 (x + 320), mkD64 (x + 384), mkD64 (x + 448) #)
+{-# NOINLINE mkD512 #-}
+
+addD8 :: D8 -> D8 -> D8
+addD8 (# x0, x1, x2, x3, x4, x5, x6, x7 #) (# y0, y1, y2, y3, y4, y5, y6, y7 #) = (# x0 +## y0, x1 +## y1, x2 +## y2, x3 +## y3, x4 +## y4, x5 +## y5, x6 +## y6, x7 +## y7 #)
+{-# NOINLINE addD8 #-}
+
+addD64 :: D64 -> D64 -> D64
+addD64 (# x0, x1, x2, x3, x4, x5, x6, x7 #) (# y0, y1, y2, y3, y4, y5, y6, y7 #) = (# addD8 x0 y0, addD8 x1 y1, addD8 x2 y2, addD8 x3 y3, addD8 x4 y4, addD8 x5 y5, addD8 x6 y6, addD8 x7 y7 #)
+{-# NOINLINE addD64 #-}
+
+addD512 :: D512 -> D512 -> D512
+addD512 (# x0, x1, x2, x3, x4, x5, x6, x7 #) (# y0, y1, y2, y3, y4, y5, y6, y7 #) = (# addD64 x0 y0, addD64 x1 y1, addD64 x2 y2, addD64 x3 y3, addD64 x4 y4, addD64 x5 y5, addD64 x6 y6, addD64 x7 y7 #)
+{-# NOINLINE addD512 #-}
+
+toListD8 :: D8 -> [Double]
+toListD8 (# x0, x1, x2, x3, x4, x5, x6, x7 #) = [D# x0, D# x1, D# x2, D# x3, D# x4, D# x5, D# x6, D# x7]
+{-# NOINLINE toListD8 #-}
+
+toListD64 :: D64 -> [Double]
+toListD64 (# x0, x1, x2, x3, x4, x5, x6, x7 #) = concat [toListD8 x0, toListD8 x1, toListD8 x2, toListD8 x3, toListD8 x4, toListD8 x5, toListD8 x6, toListD8 x7]
+{-# NOINLINE toListD64 #-}
+
+toListD512 :: D512 -> [Double]
+toListD512 (# x0, x1, x2, x3, x4, x5, x6, x7 #) = concat [toListD64 x0, toListD64 x1, toListD64 x2, toListD64 x3, toListD64 x4, toListD64 x5, toListD64 x6, toListD64 x7]
+{-# NOINLINE toListD512 #-}
+
+data T = MkT D512 D64
+
+mkT :: Double -> T
+mkT x = MkT (mkD512 x) (mkD64 (x + 512))
+{-# NOINLINE mkT #-}
+
+addT :: T -> T -> T
+addT (MkT x0 x1) (MkT y0 y1) = MkT (addD512 x0 y0) (addD64 x1 y1)
+{-# NOINLINE addT #-}
+
+toListT :: T -> [Double]
+toListT (MkT x0 x1) = toListD512 x0 ++ toListD64 x1
+{-# NOINLINE toListT #-}
+
+main :: IO ()
+main = do
+ let n = 512 + 64
+ let !x = mkT 0
+ !y = mkT n
+ print $ toListT x
+ print $ toListT y
+ print $ toListT (addT x y)
+ print $ toListT x == [0..n-1]
+ print $ toListT y == [n..2*n-1]
+ print $ toListT (addT x y) == zipWith (+) [0..n-1] [n..2*n-1]
=====================================
testsuite/tests/codeGen/should_run/T26537.stdout
=====================================
@@ -0,0 +1,6 @@
+[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0,50.0,51.0,52.0,53.0,54.0,55.0,56.0,57.0,58.0,59.0,60.0,61.0,62.0,63.0,64.0,65.0,66.0,67.0,68.0,69.0,70.0,71.0,72.0,73.0,74.0,75.0,76.0,77.0,78.0,79.0,80.0,81.0,82.0,83.0,84.0,85.0,86.0,87.0,88.0,89.0,90.0,91.0,92.0,93.0,94.0,95.0,96.0,97.0,98.0,99.0,100.0,101.0,102.0,103.0,104.0,105.0,106.0,107.0,108.0,109.0,110.0,111.0,112.0,113.0,114.0,115.0,116.0,117.0,118.0,119.0,120.0,121.0,122.0,123.0,124.0,125.0,126.0,127.0,128.0,129.0,130.0,131.0,132.0,133.0,134.0,135.0,136.0,137.0,138.0,139.0,140.0,141.0,142.0,143.0,144.0,145.0,146.0,147.0,148.0,149.0,150.0,151.0,152.0,153.0,154.0,155.0,156.0,157.0,158.0,159.0,160.0,161.0,162.0,163.0,164.0,165.0,166.0,167.0,168.0,169.0,170.0,171.0,172.0,173.0,174.0,175.0,176.0,177.0,178.0,179.0,180.0,181.0,182.0,183.0,184.0,185.0,186.0,187.0,188.0,189.0,190.0,191.0,192.0,193.0,194.0,195.0,196.0,197.0,198.0,199.0,200.0,201.0,202.0,203.0,204.0,205.0,206.0,207.0,208.0,209.0,210.0,211.0,212.0,213.0,214.0,215.0,216.0,217.0,218.0,219.0,220.0,221.0,222.0,223.0,224.0,225.0,226.0,227.0,228.0,229.0,230.0,231.0,232.0,233.0,234.0,235.0,236.0,237.0,238.0,239.0,240.0,241.0,242.0,243.0,244.0,245.0,246.0,247.0,248.0,249.0,250.0,251.0,252.0,253.0,254.0,255.0,256.0,257.0,258.0,259.0,260.0,261.0,262.0,263.0,264.0,265.0,266.0,267.0,268.0,269.0,270.0,271.0,272.0,273.0,274.0,275.0,276.0,277.0,278.0,279.0,280.0,281.0,282.0,283.0,284.0,285.0,286.0,287.0,288.0,289.0,290.0,291.0,292.0,293.0,294.0,295.0,296.0,297.0,298.0,299.0,300.0,301.0,302.0,303.0,304.0,305.0,306.0,307.0,308.0,309.0,310.0,311.0,312.0,313.0,314.0,315.0,316.0,317.0,318.0,319.0,320.0,321.0,322.0,323.0,324.0,325.0,326.0,327.0,328.0,329.0,330.0,331.0,332.0,333.0,334.0,335.0,336.0,337.0,338.0,339.0,340.0,341.0,342.0,343.0,344.0,345.0,346.0,347.0,348.0,349.0,350.0,351.0,352.0,353.0,354.0,355.0,356.0,357.0,358.0,359.0,360.0,361.0,362.0,363.0,364.0,365.0,366.0,367.0,368.0,369.0,370.0,371.0,372.0,373.0,374.0,375.0,376.0,377.0,378.0,379.0,380.0,381.0,382.0,383.0,384.0,385.0,386.0,387.0,388.0,389.0,390.0,391.0,392.0,393.0,394.0,395.0,396.0,397.0,398.0,399.0,400.0,401.0,402.0,403.0,404.0,405.0,406.0,407.0,408.0,409.0,410.0,411.0,412.0,413.0,414.0,415.0,416.0,417.0,418.0,419.0,420.0,421.0,422.0,423.0,424.0,425.0,426.0,427.0,428.0,429.0,430.0,431.0,432.0,433.0,434.0,435.0,436.0,437.0,438.0,439.0,440.0,441.0,442.0,443.0,444.0,445.0,446.0,447.0,448.0,449.0,450.0,451.0,452.0,453.0,454.0,455.0,456.0,457.0,458.0,459.0,460.0,461.0,462.0,463.0,464.0,465.0,466.0,467.0,468.0,469.0,470.0,471.0,472.0,473.0,474.0,475.0,476.0,477.0,478.0,479.0,480.0,481.0,482.0,483.0,484.0,485.0,486.0,487.0,488.0,489.0,490.0,491.0,492.0,493.0,494.0,495.0,496.0,497.0,498.0,499.0,500.0,501.0,502.0,503.0,504.0,505.0,506.0,507.0,508.0,509.0,510.0,511.0,512.0,513.0,514.0,515.0,516.0,517.0,518.0,519.0,520.0,521.0,522.0,523.0,524.0,525.0,526.0,527.0,528.0,529.0,530.0,531.0,532.0,533.0,534.0,535.0,536.0,537.0,538.0,539.0,540.0,541.0,542.0,543.0,544.0,545.0,546.0,547.0,548.0,549.0,550.0,551.0,552.0,553.0,554.0,555.0,556.0,557.0,558.0,559.0,560.0,561.0,562.0,563.0,564.0,565.0,566.0,567.0,568.0,569.0,570.0,571.0,572.0,573.0,574.0,575.0]
+[576.0,577.0,578.0,579.0,580.0,581.0,582.0,583.0,584.0,585.0,586.0,587.0,588.0,589.0,590.0,591.0,592.0,593.0,594.0,595.0,596.0,597.0,598.0,599.0,600.0,601.0,602.0,603.0,604.0,605.0,606.0,607.0,608.0,609.0,610.0,611.0,612.0,613.0,614.0,615.0,616.0,617.0,618.0,619.0,620.0,621.0,622.0,623.0,624.0,625.0,626.0,627.0,628.0,629.0,630.0,631.0,632.0,633.0,634.0,635.0,636.0,637.0,638.0,639.0,640.0,641.0,642.0,643.0,644.0,645.0,646.0,647.0,648.0,649.0,650.0,651.0,652.0,653.0,654.0,655.0,656.0,657.0,658.0,659.0,660.0,661.0,662.0,663.0,664.0,665.0,666.0,667.0,668.0,669.0,670.0,671.0,672.0,673.0,674.0,675.0,676.0,677.0,678.0,679.0,680.0,681.0,682.0,683.0,684.0,685.0,686.0,687.0,688.0,689.0,690.0,691.0,692.0,693.0,694.0,695.0,696.0,697.0,698.0,699.0,700.0,701.0,702.0,703.0,704.0,705.0,706.0,707.0,708.0,709.0,710.0,711.0,712.0,713.0,714.0,715.0,716.0,717.0,718.0,719.0,720.0,721.0,722.0,723.0,724.0,725.0,726.0,727.0,728.0,729.0,730.0,731.0,732.0,733.0,734.0,735.0,736.0,737.0,738.0,739.0,740.0,741.0,742.0,743.0,744.0,745.0,746.0,747.0,748.0,749.0,750.0,751.0,752.0,753.0,754.0,755.0,756.0,757.0,758.0,759.0,760.0,761.0,762.0,763.0,764.0,765.0,766.0,767.0,768.0,769.0,770.0,771.0,772.0,773.0,774.0,775.0,776.0,777.0,778.0,779.0,780.0,781.0,782.0,783.0,784.0,785.0,786.0,787.0,788.0,789.0,790.0,791.0,792.0,793.0,794.0,795.0,796.0,797.0,798.0,799.0,800.0,801.0,802.0,803.0,804.0,805.0,806.0,807.0,808.0,809.0,810.0,811.0,812.0,813.0,814.0,815.0,816.0,817.0,818.0,819.0,820.0,821.0,822.0,823.0,824.0,825.0,826.0,827.0,828.0,829.0,830.0,831.0,832.0,833.0,834.0,835.0,836.0,837.0,838.0,839.0,840.0,841.0,842.0,843.0,844.0,845.0,846.0,847.0,848.0,849.0,850.0,851.0,852.0,853.0,854.0,855.0,856.0,857.0,858.0,859.0,860.0,861.0,862.0,863.0,864.0,865.0,866.0,867.0,868.0,869.0,870.0,871.0,872.0,873.0,874.0,875.0,876.0,877.0,878.0,879.0,880.0,881.0,882.0,883.0,884.0,885.0,886.0,887.0,888.0,889.0,890.0,891.0,892.0,893.0,894.0,895.0,896.0,897.0,898.0,899.0,900.0,901.0,902.0,903.0,904.0,905.0,906.0,907.0,908.0,909.0,910.0,911.0,912.0,913.0,914.0,915.0,916.0,917.0,918.0,919.0,920.0,921.0,922.0,923.0,924.0,925.0,926.0,927.0,928.0,929.0,930.0,931.0,932.0,933.0,934.0,935.0,936.0,937.0,938.0,939.0,940.0,941.0,942.0,943.0,944.0,945.0,946.0,947.0,948.0,949.0,950.0,951.0,952.0,953.0,954.0,955.0,956.0,957.0,958.0,959.0,960.0,961.0,962.0,963.0,964.0,965.0,966.0,967.0,968.0,969.0,970.0,971.0,972.0,973.0,974.0,975.0,976.0,977.0,978.0,979.0,980.0,981.0,982.0,983.0,984.0,985.0,986.0,987.0,988.0,989.0,990.0,991.0,992.0,993.0,994.0,995.0,996.0,997.0,998.0,999.0,1000.0,1001.0,1002.0,1003.0,1004.0,1005.0,1006.0,1007.0,1008.0,1009.0,1010.0,1011.0,1012.0,1013.0,1014.0,1015.0,1016.0,1017.0,1018.0,1019.0,1020.0,1021.0,1022.0,1023.0,1024.0,1025.0,1026.0,1027.0,1028.0,1029.0,1030.0,1031.0,1032.0,1033.0,1034.0,1035.0,1036.0,1037.0,1038.0,1039.0,1040.0,1041.0,1042.0,1043.0,1044.0,1045.0,1046.0,1047.0,1048.0,1049.0,1050.0,1051.0,1052.0,1053.0,1054.0,1055.0,1056.0,1057.0,1058.0,1059.0,1060.0,1061.0,1062.0,1063.0,1064.0,1065.0,1066.0,1067.0,1068.0,1069.0,1070.0,1071.0,1072.0,1073.0,1074.0,1075.0,1076.0,1077.0,1078.0,1079.0,1080.0,1081.0,1082.0,1083.0,1084.0,1085.0,1086.0,1087.0,1088.0,1089.0,1090.0,1091.0,1092.0,1093.0,1094.0,1095.0,1096.0,1097.0,1098.0,1099.0,1100.0,1101.0,1102.0,1103.0,1104.0,1105.0,1106.0,1107.0,1108.0,1109.0,1110.0,1111.0,1112.0,1113.0,1114.0,1115.0,1116.0,1117.0,1118.0,1119.0,1120.0,1121.0,1122.0,1123.0,1124.0,1125.0,1126.0,1127.0,1128.0,1129.0,1130.0,1131.0,1132.0,1133.0,1134.0,1135.0,1136.0,1137.0,1138.0,1139.0,1140.0,1141.0,1142.0,1143.0,1144.0,1145.0,1146.0,1147.0,1148.0,1149.0,1150.0,1151.0]
+[576.0,578.0,580.0,582.0,584.0,586.0,588.0,590.0,592.0,594.0,596.0,598.0,600.0,602.0,604.0,606.0,608.0,610.0,612.0,614.0,616.0,618.0,620.0,622.0,624.0,626.0,628.0,630.0,632.0,634.0,636.0,638.0,640.0,642.0,644.0,646.0,648.0,650.0,652.0,654.0,656.0,658.0,660.0,662.0,664.0,666.0,668.0,670.0,672.0,674.0,676.0,678.0,680.0,682.0,684.0,686.0,688.0,690.0,692.0,694.0,696.0,698.0,700.0,702.0,704.0,706.0,708.0,710.0,712.0,714.0,716.0,718.0,720.0,722.0,724.0,726.0,728.0,730.0,732.0,734.0,736.0,738.0,740.0,742.0,744.0,746.0,748.0,750.0,752.0,754.0,756.0,758.0,760.0,762.0,764.0,766.0,768.0,770.0,772.0,774.0,776.0,778.0,780.0,782.0,784.0,786.0,788.0,790.0,792.0,794.0,796.0,798.0,800.0,802.0,804.0,806.0,808.0,810.0,812.0,814.0,816.0,818.0,820.0,822.0,824.0,826.0,828.0,830.0,832.0,834.0,836.0,838.0,840.0,842.0,844.0,846.0,848.0,850.0,852.0,854.0,856.0,858.0,860.0,862.0,864.0,866.0,868.0,870.0,872.0,874.0,876.0,878.0,880.0,882.0,884.0,886.0,888.0,890.0,892.0,894.0,896.0,898.0,900.0,902.0,904.0,906.0,908.0,910.0,912.0,914.0,916.0,918.0,920.0,922.0,924.0,926.0,928.0,930.0,932.0,934.0,936.0,938.0,940.0,942.0,944.0,946.0,948.0,950.0,952.0,954.0,956.0,958.0,960.0,962.0,964.0,966.0,968.0,970.0,972.0,974.0,976.0,978.0,980.0,982.0,984.0,986.0,988.0,990.0,992.0,994.0,996.0,998.0,1000.0,1002.0,1004.0,1006.0,1008.0,1010.0,1012.0,1014.0,1016.0,1018.0,1020.0,1022.0,1024.0,1026.0,1028.0,1030.0,1032.0,1034.0,1036.0,1038.0,1040.0,1042.0,1044.0,1046.0,1048.0,1050.0,1052.0,1054.0,1056.0,1058.0,1060.0,1062.0,1064.0,1066.0,1068.0,1070.0,1072.0,1074.0,1076.0,1078.0,1080.0,1082.0,1084.0,1086.0,1088.0,1090.0,1092.0,1094.0,1096.0,1098.0,1100.0,1102.0,1104.0,1106.0,1108.0,1110.0,1112.0,1114.0,1116.0,1118.0,1120.0,1122.0,1124.0,1126.0,1128.0,1130.0,1132.0,1134.0,1136.0,1138.0,1140.0,1142.0,1144.0,1146.0,1148.0,1150.0,1152.0,1154.0,1156.0,1158.0,1160.0,1162.0,1164.0,1166.0,1168.0,1170.0,1172.0,1174.0,1176.0,1178.0,1180.0,1182.0,1184.0,1186.0,1188.0,1190.0,1192.0,1194.0,1196.0,1198.0,1200.0,1202.0,1204.0,1206.0,1208.0,1210.0,1212.0,1214.0,1216.0,1218.0,1220.0,1222.0,1224.0,1226.0,1228.0,1230.0,1232.0,1234.0,1236.0,1238.0,1240.0,1242.0,1244.0,1246.0,1248.0,1250.0,1252.0,1254.0,1256.0,1258.0,1260.0,1262.0,1264.0,1266.0,1268.0,1270.0,1272.0,1274.0,1276.0,1278.0,1280.0,1282.0,1284.0,1286.0,1288.0,1290.0,1292.0,1294.0,1296.0,1298.0,1300.0,1302.0,1304.0,1306.0,1308.0,1310.0,1312.0,1314.0,1316.0,1318.0,1320.0,1322.0,1324.0,1326.0,1328.0,1330.0,1332.0,1334.0,1336.0,1338.0,1340.0,1342.0,1344.0,1346.0,1348.0,1350.0,1352.0,1354.0,1356.0,1358.0,1360.0,1362.0,1364.0,1366.0,1368.0,1370.0,1372.0,1374.0,1376.0,1378.0,1380.0,1382.0,1384.0,1386.0,1388.0,1390.0,1392.0,1394.0,1396.0,1398.0,1400.0,1402.0,1404.0,1406.0,1408.0,1410.0,1412.0,1414.0,1416.0,1418.0,1420.0,1422.0,1424.0,1426.0,1428.0,1430.0,1432.0,1434.0,1436.0,1438.0,1440.0,1442.0,1444.0,1446.0,1448.0,1450.0,1452.0,1454.0,1456.0,1458.0,1460.0,1462.0,1464.0,1466.0,1468.0,1470.0,1472.0,1474.0,1476.0,1478.0,1480.0,1482.0,1484.0,1486.0,1488.0,1490.0,1492.0,1494.0,1496.0,1498.0,1500.0,1502.0,1504.0,1506.0,1508.0,1510.0,1512.0,1514.0,1516.0,1518.0,1520.0,1522.0,1524.0,1526.0,1528.0,1530.0,1532.0,1534.0,1536.0,1538.0,1540.0,1542.0,1544.0,1546.0,1548.0,1550.0,1552.0,1554.0,1556.0,1558.0,1560.0,1562.0,1564.0,1566.0,1568.0,1570.0,1572.0,1574.0,1576.0,1578.0,1580.0,1582.0,1584.0,1586.0,1588.0,1590.0,1592.0,1594.0,1596.0,1598.0,1600.0,1602.0,1604.0,1606.0,1608.0,1610.0,1612.0,1614.0,1616.0,1618.0,1620.0,1622.0,1624.0,1626.0,1628.0,1630.0,1632.0,1634.0,1636.0,1638.0,1640.0,1642.0,1644.0,1646.0,1648.0,1650.0,1652.0,1654.0,1656.0,1658.0,1660.0,1662.0,1664.0,1666.0,1668.0,1670.0,1672.0,1674.0,1676.0,1678.0,1680.0,1682.0,1684.0,1686.0,1688.0,1690.0,1692.0,1694.0,1696.0,1698.0,1700.0,1702.0,1704.0,1706.0,1708.0,1710.0,1712.0,1714.0,1716.0,1718.0,1720.0,1722.0,1724.0,1726.0]
+True
+True
+True
=====================================
testsuite/tests/codeGen/should_run/all.T
=====================================
@@ -256,3 +256,4 @@ test('T24893', normal, compile_and_run, ['-O'])
test('CCallConv', [req_c], compile_and_run, ['CCallConv_c.c'])
test('T25364', normal, compile_and_run, [''])
test('T26061', normal, compile_and_run, [''])
+test('T26537', normal, compile_and_run, ['-O2 -fregs-graph'])
=====================================
testsuite/tests/driver/T20696/all.T
=====================================
@@ -1,4 +1,5 @@
test('T20696', [extra_files(['A.hs', 'B.hs', 'C.hs'])
+ , expect_broken_for(26552, ['ext-interp'])
, unless(ghc_dynamic(), skip)], multimod_compile, ['A', ''])
test('T20696-static', [extra_files(['A.hs', 'B.hs', 'C.hs'])
, when(ghc_dynamic(), skip)], multimod_compile, ['A', ''])
=====================================
testsuite/tests/driver/fat-iface/all.T
=====================================
@@ -9,12 +9,12 @@ test('fat010', [req_th,extra_files(['THA.hs', 'THB.hs', 'THC.hs']), copy_files],
# Check linking works when using -fbyte-code-and-object-code
test('fat011', [req_th, extra_files(['FatMain.hs', 'FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatMain', '-fbyte-code-and-object-code -fprefer-byte-code'])
# Check that we use interpreter rather than enable dynamic-too if needed for TH
-test('fat012', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code'])
+test('fat012', [req_th, expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code'])
# Check that no objects are generated if using -fno-code and -fprefer-byte-code
test('fat013', [req_th, req_bco, extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fno-code -fprefer-byte-code'])
# When using interpreter should not produce objects
test('fat014', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs']), extra_run_opts('-fno-code')], ghci_script, ['fat014.script'])
-test('fat015', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface'])
+test('fat015', [req_th, expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface'])
test('T22807', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807A.hs', 'T22807B.hs'])]
, makefile_test, ['T22807'])
test('T22807_ghci', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807_ghci.hs'])]
=====================================
testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
=====================================
@@ -2,8 +2,6 @@
{-# OPTIONS -haddock -ddump-parsed-ast #-}
-- Haddock comments in this test case are all rejected.
---
--- See Note [Register keyword location] in GHC.Parser.PostProcess.Haddock
module
-- | Bad comment for the module
=====================================
testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
=====================================
@@ -10,15 +10,15 @@
(AnnsModule
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:8:1-6 }))
+ (EpaSpan { T17544_kw.hs:6:1-6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:12-16 }))
+ (EpaSpan { T17544_kw.hs:11:12-16 }))
[]
[]
(Just
((,)
- { T17544_kw.hs:25:1 }
- { T17544_kw.hs:24:18 })))
+ { T17544_kw.hs:23:1 }
+ { T17544_kw.hs:22:18 })))
(EpaCommentsBalanced
[]
[]))
@@ -29,7 +29,7 @@
(Just
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:10:3-11 })
+ (EpaSpan { T17544_kw.hs:8:3-11 })
(AnnListItem
[])
(EpaComments
@@ -38,14 +38,14 @@
(Just
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(10,13)-(13,10) })
+ (EpaSpan { T17544_kw.hs:(8,13)-(11,10) })
(AnnList
(Nothing)
(ListParens
(EpTok
- (EpaSpan { T17544_kw.hs:10:13 }))
+ (EpaSpan { T17544_kw.hs:8:13 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:10 })))
+ (EpaSpan { T17544_kw.hs:11:10 })))
[]
((,)
(NoEpTok)
@@ -55,11 +55,11 @@
[]))
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-9 })
+ (EpaSpan { T17544_kw.hs:9:3-9 })
(AnnListItem
[(AddCommaAnn
(EpTok
- (EpaSpan { T17544_kw.hs:11:10 })))])
+ (EpaSpan { T17544_kw.hs:9:10 })))])
(EpaComments
[]))
(IEThingAll
@@ -67,14 +67,14 @@
(Nothing)
((,,)
(EpTok
- (EpaSpan { T17544_kw.hs:11:6 }))
+ (EpaSpan { T17544_kw.hs:9:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:11:7-8 }))
+ (EpaSpan { T17544_kw.hs:9:7-8 }))
(EpTok
- (EpaSpan { T17544_kw.hs:11:9 }))))
+ (EpaSpan { T17544_kw.hs:9:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-5 })
+ (EpaSpan { T17544_kw.hs:9:3-5 })
(AnnListItem
[])
(EpaComments
@@ -83,7 +83,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-5 })
+ (EpaSpan { T17544_kw.hs:9:3-5 })
(NameAnnTrailing
[])
(EpaComments
@@ -93,11 +93,11 @@
(Nothing)))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-9 })
+ (EpaSpan { T17544_kw.hs:10:3-9 })
(AnnListItem
[(AddCommaAnn
(EpTok
- (EpaSpan { T17544_kw.hs:12:10 })))])
+ (EpaSpan { T17544_kw.hs:10:10 })))])
(EpaComments
[]))
(IEThingAll
@@ -105,14 +105,14 @@
(Nothing)
((,,)
(EpTok
- (EpaSpan { T17544_kw.hs:12:6 }))
+ (EpaSpan { T17544_kw.hs:10:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:12:7-8 }))
+ (EpaSpan { T17544_kw.hs:10:7-8 }))
(EpTok
- (EpaSpan { T17544_kw.hs:12:9 }))))
+ (EpaSpan { T17544_kw.hs:10:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-5 })
+ (EpaSpan { T17544_kw.hs:10:3-5 })
(AnnListItem
[])
(EpaComments
@@ -121,7 +121,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-5 })
+ (EpaSpan { T17544_kw.hs:10:3-5 })
(NameAnnTrailing
[])
(EpaComments
@@ -131,7 +131,7 @@
(Nothing)))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-9 })
+ (EpaSpan { T17544_kw.hs:11:3-9 })
(AnnListItem
[])
(EpaComments
@@ -141,14 +141,14 @@
(Nothing)
((,,)
(EpTok
- (EpaSpan { T17544_kw.hs:13:6 }))
+ (EpaSpan { T17544_kw.hs:11:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:7-8 }))
+ (EpaSpan { T17544_kw.hs:11:7-8 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:9 }))))
+ (EpaSpan { T17544_kw.hs:11:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-5 })
+ (EpaSpan { T17544_kw.hs:11:3-5 })
(AnnListItem
[])
(EpaComments
@@ -157,7 +157,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-5 })
+ (EpaSpan { T17544_kw.hs:11:3-5 })
(NameAnnTrailing
[])
(EpaComments
@@ -168,7 +168,7 @@
[]
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(15,1)-(16,20) })
+ (EpaSpan { T17544_kw.hs:(13,1)-(14,20) })
(AnnListItem
[])
(EpaComments
@@ -179,7 +179,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:15:6-8 })
+ (EpaSpan { T17544_kw.hs:13:6-8 })
(NameAnnTrailing
[])
(EpaComments
@@ -197,11 +197,11 @@
(NoEpTok)
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:15:1-4 }))
+ (EpaSpan { T17544_kw.hs:13:1-4 }))
(NoEpTok)
(NoEpUniTok)
(EpTok
- (EpaSpan { T17544_kw.hs:16:3-7 }))
+ (EpaSpan { T17544_kw.hs:14:3-7 }))
(NoEpTok)
(NoEpTok)
(NoEpTok))
@@ -212,7 +212,7 @@
(False)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:9-20 })
+ (EpaSpan { T17544_kw.hs:14:9-20 })
(AnnListItem
[])
(EpaComments
@@ -222,12 +222,12 @@
[]
[]
(EpUniTok
- (EpaSpan { T17544_kw.hs:16:15-16 })
+ (EpaSpan { T17544_kw.hs:14:15-16 })
(NormalSyntax)))
(:|
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:9-13 })
+ (EpaSpan { T17544_kw.hs:14:9-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -237,7 +237,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(AnnListItem
[])
(EpaComments
@@ -251,7 +251,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(AnnListItem
[])
(EpaComments
@@ -261,7 +261,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(NameAnnTrailing
[])
(EpaComments
@@ -272,7 +272,7 @@
[]))))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(18,1)-(19,26) })
+ (EpaSpan { T17544_kw.hs:(16,1)-(17,26) })
(AnnListItem
[])
(EpaComments
@@ -283,7 +283,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:18:9-11 })
+ (EpaSpan { T17544_kw.hs:16:9-11 })
(NameAnnTrailing
[])
(EpaComments
@@ -300,12 +300,12 @@
[]
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:18:1-7 }))
+ (EpaSpan { T17544_kw.hs:16:1-7 }))
(NoEpTok)
(NoEpTok)
(NoEpUniTok)
(EpTok
- (EpaSpan { T17544_kw.hs:19:3-7 }))
+ (EpaSpan { T17544_kw.hs:17:3-7 }))
(NoEpTok)
(NoEpTok)
(NoEpTok))
@@ -315,7 +315,7 @@
(NewTypeCon
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:9-26 })
+ (EpaSpan { T17544_kw.hs:17:9-26 })
(AnnListItem
[])
(EpaComments
@@ -325,12 +325,12 @@
[]
[]
(EpUniTok
- (EpaSpan { T17544_kw.hs:19:15-16 })
+ (EpaSpan { T17544_kw.hs:17:15-16 })
(NormalSyntax)))
(:|
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:9-13 })
+ (EpaSpan { T17544_kw.hs:17:9-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -340,7 +340,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:18-26 })
+ (EpaSpan { T17544_kw.hs:17:18-26 })
(AnnListItem
[])
(EpaComments
@@ -363,11 +363,11 @@
(HsUnannotated
(EpArrow
(EpUniTok
- (EpaSpan { T17544_kw.hs:19:21-22 })
+ (EpaSpan { T17544_kw.hs:17:21-22 })
(NormalSyntax))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:18-19 })
+ (EpaSpan { T17544_kw.hs:17:18-19 })
(AnnListItem
[])
(EpaComments
@@ -375,15 +375,15 @@
(HsTupleTy
(AnnParens
(EpTok
- (EpaSpan { T17544_kw.hs:19:18 }))
+ (EpaSpan { T17544_kw.hs:17:18 }))
(EpTok
- (EpaSpan { T17544_kw.hs:19:19 })))
+ (EpaSpan { T17544_kw.hs:17:19 })))
(HsBoxedOrConstraintTuple)
[]))
(Nothing))])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:24-26 })
+ (EpaSpan { T17544_kw.hs:17:24-26 })
(AnnListItem
[])
(EpaComments
@@ -393,7 +393,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:24-26 })
+ (EpaSpan { T17544_kw.hs:17:24-26 })
(NameAnnTrailing
[])
(EpaComments
@@ -404,7 +404,7 @@
[]))))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(21,1)-(24,18) })
+ (EpaSpan { T17544_kw.hs:(19,1)-(22,18) })
(AnnListItem
[])
(EpaComments
@@ -415,12 +415,12 @@
((,,)
(AnnClassDecl
(EpTok
- (EpaSpan { T17544_kw.hs:21:1-5 }))
+ (EpaSpan { T17544_kw.hs:19:1-5 }))
[]
[]
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:23:3-7 }))
+ (EpaSpan { T17544_kw.hs:21:3-7 }))
(NoEpTok)
(NoEpTok)
[])
@@ -430,7 +430,7 @@
(Nothing)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:7-9 })
+ (EpaSpan { T17544_kw.hs:19:7-9 })
(NameAnnTrailing
[])
(EpaComments
@@ -441,7 +441,7 @@
(NoExtField)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:11 })
+ (EpaSpan { T17544_kw.hs:19:11 })
(AnnListItem
[])
(EpaComments
@@ -458,7 +458,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:11 })
+ (EpaSpan { T17544_kw.hs:19:11 })
(NameAnnTrailing
[])
(EpaComments
@@ -471,7 +471,7 @@
[]
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:5-18 })
+ (EpaSpan { T17544_kw.hs:22:5-18 })
(AnnListItem
[])
(EpaComments
@@ -479,14 +479,14 @@
(ClassOpSig
(AnnSig
(EpUniTok
- (EpaSpan { T17544_kw.hs:24:15-16 })
+ (EpaSpan { T17544_kw.hs:22:15-16 })
(NormalSyntax))
(Nothing)
(Nothing))
(False)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:5-13 })
+ (EpaSpan { T17544_kw.hs:22:5-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -495,7 +495,7 @@
{OccName: clsmethod}))]
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(AnnListItem
[])
(EpaComments
@@ -506,7 +506,7 @@
(NoExtField))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(AnnListItem
[])
(EpaComments
@@ -516,7 +516,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(NameAnnTrailing
[])
(EpaComments
@@ -529,15 +529,15 @@
[])))]))
-T17544_kw.hs:9:3: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:7:3: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:15:10: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:13:10: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:18:13: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:16:13: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:22:5: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:20:5: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
=====================================
testsuite/tests/splice-imports/all.T
=====================================
@@ -9,7 +9,7 @@ test('SI03', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI03', '-v0']
test('SI04', [extra_files(["SI01A.hs"])], multimod_compile, ['SI04', '-v0'])
test('SI05', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI05', '-v0'])
test('SI06', [extra_files(["SI01A.hs"])], multimod_compile, ['SI06', '-v0'])
-test('SI07', [unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code'])
+test('SI07', [expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code'])
# Instance tests
test('SI08', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile_fail, ['SI08', '-v0'])
test('SI09', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile, ['SI09', '-v0'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19a1f0d904824c31ab52d9ef239771…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19a1f0d904824c31ab52d9ef239771…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ubsan] hadrian: add support for building with UndefinedBehaviorSanitizer
by Cheng Shao (@TerrorJack) 08 Nov '25
by Cheng Shao (@TerrorJack) 08 Nov '25
08 Nov '25
Cheng Shao pushed to branch wip/ubsan at Glasgow Haskell Compiler / GHC
Commits:
2cf983a0 by Cheng Shao at 2025-11-08T13:28:25+01:00
hadrian: add support for building with UndefinedBehaviorSanitizer
This patch adds a +ubsan flavour transformer to hadrian to build all
stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is
particularly useful to catch potential undefined behavior in the RTS
codebase.
- - - - -
5 changed files:
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- rts/rts.cabal
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
Changes:
=====================================
hadrian/doc/flavours.md
=====================================
@@ -238,6 +238,10 @@ The supported transformers are listed below:
<td><code>thread_sanitizer</code></td>
<td>Build the runtime system with ThreadSanitizer support</td>
</tr>
+ <tr>
+ <td><code>ubsan</code></td>
+ <td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td>
+ </tr>
<tr>
<td><code>llvm</code></td>
<td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td>
=====================================
hadrian/src/Flavour.hs
=====================================
@@ -7,6 +7,7 @@ module Flavour
, addArgs
, splitSections
, enableThreadSanitizer
+ , enableUBSan
, enableLateCCS
, enableHashUnitIds
, enableDebugInfo, enableTickyGhc
@@ -33,6 +34,9 @@ import Data.Either
import Data.Map (Map)
import qualified Data.Map as M
import qualified Data.Set as Set
+import GHC.Platform.ArchOS
+import Oracles.Flag
+import Oracles.Setting
import Packages
import Flavour.Type
import Settings.Parser
@@ -53,6 +57,7 @@ flavourTransformers = M.fromList
, "no_split_sections" =: noSplitSections
, "thread_sanitizer" =: enableThreadSanitizer False
, "thread_sanitizer_cmm" =: enableThreadSanitizer True
+ , "ubsan" =: enableUBSan
, "llvm" =: viaLlvmBackend
, "profiled_ghc" =: enableProfiledGhc
, "no_dynamic_ghc" =: disableDynamicGhcPrograms
@@ -258,6 +263,66 @@ enableThreadSanitizer instrumentCmm = addArgs $ notStage0 ? mconcat
]
]
+-- | Whether or not -shared-libsan should be passed to clang at
+-- link-time.
+--
+-- See
+-- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.5/clang/lib/Driver/S…,
+-- clang defaults to -shared-libsan on darwin/windows and
+-- -static-libsan on linux. In general, -static-libsan is incredibly
+-- problematic when multiple copies of the sanitizer runtimes coexist
+-- in the same address space due to being linked into multiple Haskell
+-- libraries. So we should explicitly specify `-shared-libsan` if
+-- needed.
+--
+-- A small downside of -shared-libsan is the clang-specific sanitizer
+-- runtime shared library path needs to be manually specified via
+-- @export LD_LIBRARY_PATH=$(dirname $(clang -print-libgcc-file-name
+-- -rtlib=compiler-rt))@ for ld.so to find it at runtime.
+needSharedLibSAN :: Action Bool
+needSharedLibSAN = do
+ is_clang <- flag CcLlvmBackend
+ is_default_shared_libsan <- anyTargetOs [OSDarwin, OSMinGW32]
+ pure $ is_clang && not is_default_shared_libsan
+
+-- | Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer
+-- support:
+-- https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html.
+--
+-- Note that we also pass -fno-sanitize=function to clang, since
+-- "runtime call to function foo through pointer to incorrect function
+-- type" is unfortunately pretty common (e.g. evac_fn in rts) and
+-- impact the signal to noise ratio of UBSAN warnings. gcc doesn't
+-- implement this instrumentation though.
+enableUBSan :: Flavour -> Flavour
+enableUBSan =
+ addArgs $
+ notStage0
+ ? mconcat
+ [ package rts
+ ? builder (Cabal Flags)
+ ? arg "+ubsan"
+ <> (needSharedLibSAN ? arg "+shared-libsan"),
+ builder (Ghc CompileHs)
+ ? arg "-optc-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Ghc CompileCWithGhc)
+ ? arg "-optc-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Ghc CompileCppWithGhc)
+ ? arg "optcxx-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-optcxx-fno-sanitize=function"),
+ builder (Ghc LinkHs)
+ ? arg "-optc-fsanitize=undefined"
+ <> arg "-optl-fsanitize=undefined"
+ <> (needSharedLibSAN ? arg "-optl-shared-libsan")
+ <> (flag CcLlvmBackend ? arg "-optc-fno-sanitize=function"),
+ builder (Cc CompileC)
+ ? arg "-fsanitize=undefined"
+ <> (flag CcLlvmBackend ? arg "-fno-sanitize=function"),
+ builder Testsuite ? arg "--config=have_ubsan=True"
+ ]
+
-- | Use the LLVM backend in stages 1 and later.
viaLlvmBackend :: Flavour -> Flavour
viaLlvmBackend = addArgs $ notStage0 ? builder Ghc ? arg "-fllvm"
=====================================
rts/rts.cabal
=====================================
@@ -91,6 +91,19 @@ flag thread-sanitizer
in @rts/include/rts/TSANUtils.h@.
default: False
manual: True
+flag ubsan
+ description:
+ Link with -fsanitize=undefined, to be enabled when building with
+ UndefinedBehaviorSanitizer.
+ default: False
+ manual: True
+flag shared-libsan
+ description:
+ Link with -shared-libsan, to guarantee only one copy of the
+ sanitizer runtimes exist in the address space. See
+ needSharedLibSAN in hadrian/src/Flavour.hs.
+ default: False
+ manual: True
library
-- rts is a wired in package and
@@ -200,6 +213,12 @@ library
cc-options: -fsanitize=thread
ld-options: -fsanitize=thread
+ if flag(ubsan)
+ ld-options: -fsanitize=undefined
+
+ if flag(shared-libsan)
+ ld-options: -shared-libsan
+
if os(linux)
-- the RTS depends upon libc. while this dependency is generally
-- implicitly added by `cc`, we must explicitly add it here to ensure
=====================================
testsuite/driver/testglobals.py
=====================================
@@ -186,6 +186,9 @@ class TestConfig:
# Are we running in a ThreadSanitizer-instrumented build?
self.have_thread_sanitizer = False
+ # Are we running with UndefinedBehaviorSanitizer enabled?
+ self.have_ubsan = False
+
# Do symbols use leading underscores?
self.leading_underscore = False
=====================================
testsuite/driver/testlib.py
=====================================
@@ -1090,6 +1090,8 @@ def llvm_build ( ) -> bool:
def have_thread_sanitizer( ) -> bool:
return config.have_thread_sanitizer
+def have_ubsan( ) -> bool:
+ return config.have_ubsan
def gcc_as_cmmp() -> bool:
return config.cmm_cpp_is_gcc
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2cf983a083bb8b251eff4f8a0aacf40…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2cf983a083bb8b251eff4f8a0aacf40…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ubsan] 11 commits: compiler: Exclude units with no exposed modules from unused package check
by Cheng Shao (@TerrorJack) 08 Nov '25
by Cheng Shao (@TerrorJack) 08 Nov '25
08 Nov '25
Cheng Shao pushed to branch wip/ubsan at Glasgow Haskell Compiler / GHC
Commits:
5cdcfaed by Ben Gamari at 2025-11-06T09:01:36-05:00
compiler: Exclude units with no exposed modules from unused package check
Such packages cannot be "used" in the Haskell sense of the word yet
are nevertheless necessary as they may provide, e.g., C object code or
link flags.
Fixes #24120.
- - - - -
74b8397a by Brandon Chinn at 2025-11-06T09:02:19-05:00
Replace deprecated argparse.FileType
- - - - -
36ddf988 by Ben Gamari at 2025-11-06T09:03:01-05:00
Bump unix submodule to 2.8.8.0
Closes #26474.
- - - - -
c32b3a29 by fendor at 2025-11-06T09:03:43-05:00
Fix assertion in `postStringLen` to account for \0 byte
We fix the assertion to handle trailing \0 bytes in `postStringLen`.
Before this change, the assertion looked like this:
ASSERT(eb->begin + eb->size > eb->pos + len + 1);
Let's assume some values to see why this is actually off by one:
eb->begin = 0
eb->size = 1
eb->pos = 0
len = 1
then the assertion would trigger correctly:
0 + 1 > 0 + 1 + 1 => 1 > 2 => false
as there is not enough space for the \0 byte (which is the trailing +1).
However, if we change `eb->size = 2`, then we do have enough space for a
string of length 1, but the assertion still fails:
0 + 2 > 0 + 1 + 1 => 2 > 2 => false
Which causes the assertion to fail if there is exactly enough space for
the string with a trailing \0 byte.
Clearly, the assertion should be `>=`!
If we switch around the operand, it should become more obvious that `<=`
is the correct comparison:
ASSERT(eb->pos + len + 1 <= eb->begin + eb->size);
This is expresses more naturally that the current position plus the
length of the string (and the null byte) must be smaller or equal to the
overall size of the buffer.
This change also is in line with the implementation in
`hasRoomForEvent` and `hasRoomForVariableEvent`:
```
StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum)
{
uint32_t size = ...;
if (eb->pos + size > eb->begin + eb->size)
...
```
the check `eb->pos + size > eb->begin + eb->size` is identical to
`eb->pos + size <= eb->begin + eb->size` plus a negation.
- - - - -
3034a6f2 by Ben Gamari at 2025-11-06T09:04:24-05:00
Bump os-string submodule to 2.0.8
- - - - -
39567e85 by Cheng Shao at 2025-11-06T09:05:06-05:00
rts: use computed goto for instruction dispatch in the bytecode interpreter
This patch uses computed goto for instruction dispatch in the bytecode
interpreter. Previously instruction dispatch is done by a classic
switch loop, so executing the next instruction requires two jumps: one
to the start of the switch loop and another to the case block based on
the instruction tag. By using computed goto, we can build a jump table
consisted of code addresses indexed by the instruction tags
themselves, so executing the next instruction requires only one jump,
to the destination directly fetched from the jump table.
Closes #12953.
- - - - -
93fc7265 by sheaf at 2025-11-06T21:33:24-05:00
Correct hasFixedRuntimeRep in matchExpectedFunTys
This commit fixes a bug in the representation-polymormorphism check in
GHC.Tc.Utils.Unify.matchExpectedFunTys. The problem was that we put
the coercion resulting from hasFixedRuntimeRep in the wrong place,
leading to the Core Lint error reported in #26528.
The change is that we have to be careful when using 'mkWpFun': it
expects **both** the expected and actual argument types to have a
syntactically fixed RuntimeRep, as explained in Note [WpFun-FRR-INVARIANT]
in GHC.Tc.Types.Evidence.
On the way, this patch improves some of the commentary relating to
other usages of 'mkWpFun' in the compiler, in particular in the view
pattern case of 'tc_pat'. No functional changes, but some stylistic
changes to make the code more readable, and make it easier to understand
how we are upholding the WpFun-FRR-INVARIANT.
Fixes #26528
- - - - -
c052c724 by Simon Peyton Jones at 2025-11-06T21:34:06-05:00
Fix a horrible shadowing bug in implicit parameters
Fixes #26451. The change is in GHC.Tc.Solver.Monad.updInertDicts
where we now do /not/ delete /Wanted/ implicit-parameeter constraints.
This bug has been in GHC since 9.8! But it's quite hard to provoke;
I contructed a tests in T26451, but it was hard to do so.
- - - - -
b253013e by Georgios Karachalias at 2025-11-07T17:21:57-05:00
Remove the `CoreBindings` constructor from `LinkablePart`
Adjust HscRecompStatus to disallow unhydrated WholeCoreBindings
from being passed as input to getLinkDeps (which would previously
panic in this case).
Fixes #26497
- - - - -
ac7b737e by Sylvain Henry at 2025-11-07T17:22:51-05:00
Testsuite: pass ext-interp test way (#26552)
Note that some tests are still marked as broken with the ext-interp way
(see #26552 and #14335)
- - - - -
b10a1105 by Cheng Shao at 2025-11-08T13:11:06+01:00
hadrian: add support for building with UndefinedBehaviorSanitizer
This patch adds a +ubsan flavour transformer to hadrian to build all
stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is
particularly useful to catch potential undefined behavior in the RTS
codebase.
- - - - -
37 changed files:
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- docs/users_guide/compare-flags.py
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- libraries/base/tests/all.T
- libraries/os-string
- libraries/unix
- rts/Interpreter.c
- rts/eventlog/EventLog.c
- rts/gen_event_types.py
- rts/include/rts/Bytecodes.h
- rts/rts.cabal
- testsuite/driver/runtests.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/T20696/all.T
- + testsuite/tests/driver/T24120.hs
- testsuite/tests/driver/all.T
- testsuite/tests/driver/fat-iface/all.T
- + testsuite/tests/rep-poly/T26528.hs
- testsuite/tests/rep-poly/all.T
- testsuite/tests/splice-imports/all.T
- + testsuite/tests/typecheck/should_compile/T26451.hs
- testsuite/tests/typecheck/should_compile/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3a9c6d36f0e420a1191f92f1687f6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3a9c6d36f0e420a1191f92f1687f6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Cheng Shao deleted branch wip/ubsan-gcc at Glasgow Haskell Compiler / GHC
--
You're receiving this email because of your account on gitlab.haskell.org.
1
0