Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
7567f51e
by Simon Peyton Jones at 2025-09-10T05:31:01-04:00
-
f531718e
by sheaf at 2025-09-10T05:31:08-04:00
-
500aaa99
by Andreas Klebinger at 2025-09-10T05:31:10-04:00
-
2eb2b028
by sheaf at 2025-09-10T05:31:15-04:00
-
0a5813dc
by sheaf at 2025-09-10T05:31:19-04:00
-
d055be16
by Ben Gamari at 2025-09-10T05:31:20-04:00
-
b4af59b5
by Moritz Angermann at 2025-09-10T05:31:21-04:00
-
b7f81cd7
by Moritz Angermann at 2025-09-10T05:31:22-04:00
-
88c3a7ad
by Moritz Angermann at 2025-09-10T05:31:23-04:00
-
48485986
by Moritz Angermann at 2025-09-10T05:31:24-04:00
-
68c5cd01
by Moritz Angermann at 2025-09-10T05:31:25-04:00
-
96474e13
by Zubin Duggal at 2025-09-10T05:31:25-04:00
18 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Tc/Utils/Unify.hs
- docs/users_guide/flags.py
- hadrian/src/Oracles/TestSettings.hs
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- linters/lint-codes/LintCodes/Coverage.hs
- rts/linker/MachO.c
- testsuite/ghc-config/ghc-config.hs
- testsuite/tests/driver/all.T
- + testsuite/tests/linear/should_compile/T26332.hs
- testsuite/tests/linear/should_compile/all.T
- + testsuite/tests/profiling/should_compile/T26056.hs
- testsuite/tests/profiling/should_compile/all.T
- testsuite/tests/rts/exec_signals_child.c
- testsuite/tests/rts/linker/T11223/all.T
Changes:
| ... | ... | @@ -1235,7 +1235,7 @@ darwin = |
| 1235 | 1235 | |
| 1236 | 1236 | freebsd_jobs :: [JobGroup Job]
|
| 1237 | 1237 | freebsd_jobs =
|
| 1238 | - [ addValidateRule FreeBSDLabel (standardBuilds Amd64 FreeBSD14)
|
|
| 1238 | + [ addValidateRule FreeBSDLabel (standardBuildsWithConfig Amd64 FreeBSD14 (splitSectionsBroken vanilla))
|
|
| 1239 | 1239 | ]
|
| 1240 | 1240 | |
| 1241 | 1241 | alpine_x86 :: [JobGroup Job]
|
| ... | ... | @@ -4296,7 +4296,7 @@ |
| 4296 | 4296 | "ac_cv_func_utimensat": "no"
|
| 4297 | 4297 | }
|
| 4298 | 4298 | },
|
| 4299 | - "release-x86_64-freebsd14-release": {
|
|
| 4299 | + "release-x86_64-freebsd14-release+no_split_sections": {
|
|
| 4300 | 4300 | "after_script": [
|
| 4301 | 4301 | ".gitlab/ci.sh save_cache",
|
| 4302 | 4302 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -4307,7 +4307,7 @@ |
| 4307 | 4307 | "artifacts": {
|
| 4308 | 4308 | "expire_in": "1 year",
|
| 4309 | 4309 | "paths": [
|
| 4310 | - "ghc-x86_64-freebsd14-release.tar.xz",
|
|
| 4310 | + "ghc-x86_64-freebsd14-release+no_split_sections.tar.xz",
|
|
| 4311 | 4311 | "junit.xml",
|
| 4312 | 4312 | "unexpected-test-output.tar.gz"
|
| 4313 | 4313 | ],
|
| ... | ... | @@ -4349,8 +4349,8 @@ |
| 4349 | 4349 | ],
|
| 4350 | 4350 | "variables": {
|
| 4351 | 4351 | "BIGNUM_BACKEND": "gmp",
|
| 4352 | - "BIN_DIST_NAME": "ghc-x86_64-freebsd14-release",
|
|
| 4353 | - "BUILD_FLAVOUR": "release",
|
|
| 4352 | + "BIN_DIST_NAME": "ghc-x86_64-freebsd14-release+no_split_sections",
|
|
| 4353 | + "BUILD_FLAVOUR": "release+no_split_sections",
|
|
| 4354 | 4354 | "CABAL_INSTALL_VERSION": "3.10.3.0",
|
| 4355 | 4355 | "CC": "cc",
|
| 4356 | 4356 | "CONFIGURE_ARGS": "--with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib --with-system-libffi --with-ffi-includes=/usr/local/include --with-ffi-libraries=/usr/local/lib --with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --enable-strict-ghc-toolchain-check",
|
| ... | ... | @@ -4359,7 +4359,7 @@ |
| 4359 | 4359 | "IGNORE_PERF_FAILURES": "all",
|
| 4360 | 4360 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 4361 | 4361 | "RUNTEST_ARGS": "",
|
| 4362 | - "TEST_ENV": "x86_64-freebsd14-release",
|
|
| 4362 | + "TEST_ENV": "x86_64-freebsd14-release+no_split_sections",
|
|
| 4363 | 4363 | "XZ_OPT": "-9"
|
| 4364 | 4364 | }
|
| 4365 | 4365 | },
|
| ... | ... | @@ -1205,14 +1205,21 @@ specExpr env (Tick tickish body) |
| 1205 | 1205 | ---------------- Applications might generate a call instance --------------------
|
| 1206 | 1206 | specExpr env expr@(App {})
|
| 1207 | 1207 | = do { let (fun_in, args_in) = collectArgs expr
|
| 1208 | + ; (fun_out, uds_fun) <- specExpr env fun_in
|
|
| 1208 | 1209 | ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in
|
| 1209 | - ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args
|
|
| 1210 | - -- Some dicts may have floated out of args_in;
|
|
| 1211 | - -- they should be in scope for fireRewriteRules (#21689)
|
|
| 1212 | - (fun_in', args_out') = fireRewriteRules env_args fun_in args_out
|
|
| 1213 | - ; (fun_out', uds_fun) <- specExpr env fun_in'
|
|
| 1210 | + ; let uds_app = uds_fun `thenUDs` uds_args
|
|
| 1211 | + env_args = zapSubst env `bringFloatedDictsIntoScope` ud_binds uds_app
|
|
| 1212 | + -- zapSubst: we have now fully applied the substitution
|
|
| 1213 | + -- bringFloatedDictsIntoScope: some dicts may have floated out of
|
|
| 1214 | + -- args_in; they should be in scope for fireRewriteRules (#21689)
|
|
| 1215 | + |
|
| 1216 | + -- Try firing rewrite rules
|
|
| 1217 | + -- See Note [Fire rules in the specialiser]
|
|
| 1218 | + ; let (fun_out', args_out') = fireRewriteRules env_args fun_out args_out
|
|
| 1219 | + |
|
| 1220 | + -- Make a call record, and return
|
|
| 1214 | 1221 | ; let uds_call = mkCallUDs env fun_out' args_out'
|
| 1215 | - ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) }
|
|
| 1222 | + ; return (fun_out' `mkApps` args_out', uds_app `thenUDs` uds_call) }
|
|
| 1216 | 1223 | |
| 1217 | 1224 | ---------------- Lambda/case require dumping of usage details --------------------
|
| 1218 | 1225 | specExpr env e@(Lam {})
|
| ... | ... | @@ -1246,17 +1253,18 @@ specExpr env (Let bind body) |
| 1246 | 1253 | -- See Note [Specialisation modulo dictionary selectors]
|
| 1247 | 1254 | -- Note [ClassOp/DFun selection]
|
| 1248 | 1255 | -- Note [Fire rules in the specialiser]
|
| 1249 | -fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr])
|
|
| 1256 | +fireRewriteRules :: SpecEnv -- Substitution is already zapped
|
|
| 1257 | + -> OutExpr -> [OutExpr] -> (OutExpr, [OutExpr])
|
|
| 1250 | 1258 | fireRewriteRules env (Var f) args
|
| 1251 | 1259 | | let rules = getRules (se_rules env) f
|
| 1252 | 1260 | , Just (rule, expr) <- specLookupRule env f args activeInInitialPhase rules
|
| 1253 | 1261 | , let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target]
|
| 1254 | - zapped_subst = Core.zapSubst (se_subst env)
|
|
| 1255 | - expr' = simpleOptExprWith defaultSimpleOpts zapped_subst expr
|
|
| 1262 | + zapped_subst = se_subst env -- Just needed for the InScopeSet
|
|
| 1263 | + expr' = simpleOptExprWith defaultSimpleOpts zapped_subst (mkApps expr rest_args)
|
|
| 1256 | 1264 | -- simplOptExpr needed because lookupRule returns
|
| 1257 | 1265 | -- (\x y. rhs) arg1 arg2
|
| 1258 | 1266 | , (fun', args') <- collectArgs expr'
|
| 1259 | - = fireRewriteRules env fun' (args'++rest_args)
|
|
| 1267 | + = fireRewriteRules env fun' args'
|
|
| 1260 | 1268 | fireRewriteRules _ fun args = (fun, args)
|
| 1261 | 1269 | |
| 1262 | 1270 | --------------
|
| ... | ... | @@ -1669,10 +1677,19 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1669 | 1677 | ; let all_rule_bndrs = poly_qvars ++ rule_bndrs
|
| 1670 | 1678 | env' = env { se_subst = subst'' }
|
| 1671 | 1679 | |
| 1672 | -{-
|
|
| 1673 | - ; pprTrace "spec_call" (vcat
|
|
| 1680 | + -- Check for (a) usefulness and (b) not already covered
|
|
| 1681 | + -- See (SC1) in Note [Specialisations already covered]
|
|
| 1682 | + ; let all_rules = rules_acc ++ existing_rules
|
|
| 1683 | + -- all_rules: we look both in the rules_acc (generated by this invocation
|
|
| 1684 | + -- of specCalls), and in existing_rules (passed in to specCalls)
|
|
| 1685 | + already_covered = alreadyCovered env' all_rule_bndrs fn
|
|
| 1686 | + rule_lhs_args is_active all_rules
|
|
| 1687 | + |
|
| 1688 | +{- ; pprTrace "spec_call" (vcat
|
|
| 1674 | 1689 | [ text "fun: " <+> ppr fn
|
| 1675 | 1690 | , text "call info: " <+> ppr _ci
|
| 1691 | + , text "useful: " <+> ppr useful
|
|
| 1692 | + , text "already_covered:" <+> ppr already_covered
|
|
| 1676 | 1693 | , text "poly_qvars: " <+> ppr poly_qvars
|
| 1677 | 1694 | , text "useful: " <+> ppr useful
|
| 1678 | 1695 | , text "all_rule_bndrs:" <+> ppr all_rule_bndrs
|
| ... | ... | @@ -1681,17 +1698,13 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1681 | 1698 | , text "dx_binds:" <+> ppr dx_binds
|
| 1682 | 1699 | , text "spec_args: " <+> ppr spec_args
|
| 1683 | 1700 | , text "rhs_bndrs" <+> ppr rhs_bndrs
|
| 1684 | - , text "rhs_body" <+> ppr rhs_body ]) $
|
|
| 1701 | + , text "rhs_body" <+> ppr rhs_body
|
|
| 1702 | + , text "subst''" <+> ppr subst'' ]) $
|
|
| 1685 | 1703 | return ()
|
| 1686 | 1704 | -}
|
| 1687 | 1705 | |
| 1688 | - -- Check for (a) usefulness and (b) not already covered
|
|
| 1689 | - -- See (SC1) in Note [Specialisations already covered]
|
|
| 1690 | - ; let all_rules = rules_acc ++ existing_rules
|
|
| 1691 | - -- all_rules: we look both in the rules_acc (generated by this invocation
|
|
| 1692 | - -- of specCalls), and in existing_rules (passed in to specCalls)
|
|
| 1693 | - ; if not useful -- No useful specialisation
|
|
| 1694 | - || alreadyCovered env' all_rule_bndrs fn rule_lhs_args is_active all_rules
|
|
| 1706 | + ; if not useful -- No useful specialisation
|
|
| 1707 | + || already_covered -- Useful, but done already
|
|
| 1695 | 1708 | then return spec_acc
|
| 1696 | 1709 | else
|
| 1697 | 1710 | |
| ... | ... | @@ -1702,6 +1715,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1702 | 1715 | -- Run the specialiser on the specialised RHS
|
| 1703 | 1716 | ; (rhs_body', rhs_uds) <- specExpr env'' rhs_body
|
| 1704 | 1717 | |
| 1718 | +{- ; pprTrace "spec_call2" (vcat
|
|
| 1719 | + [ text "fun:" <+> ppr fn
|
|
| 1720 | + , text "rhs_body':" <+> ppr rhs_body' ]) $
|
|
| 1721 | + return ()
|
|
| 1722 | +-}
|
|
| 1723 | + |
|
| 1705 | 1724 | -- Make the RHS of the specialised function
|
| 1706 | 1725 | ; let spec_rhs_bndrs = spec_bndrs ++ inner_rhs_bndrs'
|
| 1707 | 1726 | (rhs_uds1, inner_dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds
|
| ... | ... | @@ -1853,8 +1853,8 @@ where we eta-expanded that (:). But now foldr expects an argument |
| 1853 | 1853 | with ->{Many} and gets an argument with ->{m1} or ->{m2}, and Lint
|
| 1854 | 1854 | complains.
|
| 1855 | 1855 | |
| 1856 | -The easiest solution was to use tcEqMult in tc_sub_type_deep, and
|
|
| 1857 | -insist on equality. This is only in the DeepSubsumption code anyway.
|
|
| 1856 | +The easiest solution was to unify the multiplicities in tc_sub_type_deep,
|
|
| 1857 | +insisting on equality. This is only in the DeepSubsumption code anyway.
|
|
| 1858 | 1858 | |
| 1859 | 1859 | Note [FunTy vs non-FunTy case in tc_sub_type_deep]
|
| 1860 | 1860 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2047,10 +2047,7 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected |
| 2047 | 2047 | -- GenSigCtxt: See Note [Setting the argument context]
|
| 2048 | 2048 | ; res_wrap <- tc_sub_type_deep (Result pos) unify inst_orig ctxt act_res exp_res
|
| 2049 | 2049 | |
| 2050 | - -- See Note [Multiplicity in deep subsumption]
|
|
| 2051 | - ; tcEqMult inst_orig act_mult exp_mult
|
|
| 2052 | - |
|
| 2053 | - ; mkWpFun_FRR pos
|
|
| 2050 | + ; mkWpFun_FRR unify pos
|
|
| 2054 | 2051 | act_af act_mult act_arg act_res
|
| 2055 | 2052 | exp_af exp_mult exp_arg exp_res
|
| 2056 | 2053 | arg_wrap res_wrap
|
| ... | ... | @@ -2058,20 +2055,32 @@ tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected |
| 2058 | 2055 | where
|
| 2059 | 2056 | given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
|
| 2060 | 2057 | |
| 2061 | --- | Like 'mkWpFun', except that it performs representation-polymorphism
|
|
| 2062 | --- checks on the argument type.
|
|
| 2058 | +-- | Like 'mkWpFun', except that it performs the necessary
|
|
| 2059 | +-- representation-polymorphism checks on the argument type in the case that
|
|
| 2060 | +-- we introduce a lambda abstraction.
|
|
| 2063 | 2061 | mkWpFun_FRR
|
| 2064 | - :: Position p
|
|
| 2062 | + :: (TcType -> TcType -> TcM TcCoercionN) -- ^ how to unify
|
|
| 2063 | + -> Position p
|
|
| 2065 | 2064 | -> FunTyFlag -> Type -> TcType -> Type -- actual FunTy
|
| 2066 | 2065 | -> FunTyFlag -> Type -> TcType -> Type -- expected FunTy
|
| 2067 | 2066 | -> HsWrapper -- ^ exp_arg ~> act_arg
|
| 2068 | 2067 | -> HsWrapper -- ^ act_res ~> exp_res
|
| 2069 | 2068 | -> TcM HsWrapper -- ^ act_funTy ~> exp_funTy
|
| 2070 | -mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
|
|
| 2071 | - | needs_eta
|
|
| 2072 | - -- See Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 2073 | - = do { (exp_arg_co, exp_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption True pos) exp_arg
|
|
| 2074 | - ; (act_arg_co, _act_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption False pos) act_arg
|
|
| 2069 | +mkWpFun_FRR unify pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
|
|
| 2070 | + = do { ((exp_arg_co, exp_arg_frr), (act_arg_co, _act_arg_frr)) <-
|
|
| 2071 | + if needs_frr_checks
|
|
| 2072 | + -- See Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 2073 | + then do { exp_frr_wrap <- hasFixedRuntimeRep (frr_ctxt True ) exp_arg
|
|
| 2074 | + ; act_frr_wrap <- hasFixedRuntimeRep (frr_ctxt False) act_arg
|
|
| 2075 | + ; return (exp_frr_wrap, act_frr_wrap) }
|
|
| 2076 | + else return ((mkNomReflCo exp_arg, exp_arg), (mkNomReflCo act_arg, act_arg))
|
|
| 2077 | + |
|
| 2078 | + -- Enforce equality of multiplicities (not the more natural sub-multiplicity).
|
|
| 2079 | + -- See Note [Multiplicity in deep subsumption]
|
|
| 2080 | + ; act_arg_mult_co <- unify act_mult exp_mult
|
|
| 2081 | + -- NB: don't use tcEqMult: that would require the evidence for
|
|
| 2082 | + -- equality to be Refl, but it might well not be (#26332).
|
|
| 2083 | + |
|
| 2075 | 2084 | ; let
|
| 2076 | 2085 | exp_arg_fun_co =
|
| 2077 | 2086 | mkFunCo Nominal exp_af
|
| ... | ... | @@ -2080,7 +2089,7 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res |
| 2080 | 2089 | (mkReflCo Nominal exp_res)
|
| 2081 | 2090 | act_arg_fun_co =
|
| 2082 | 2091 | mkFunCo Nominal act_af
|
| 2083 | - (mkReflCo Nominal act_mult)
|
|
| 2092 | + act_arg_mult_co
|
|
| 2084 | 2093 | act_arg_co
|
| 2085 | 2094 | (mkReflCo Nominal act_res)
|
| 2086 | 2095 | arg_wrap_frr =
|
| ... | ... | @@ -2090,24 +2099,16 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res |
| 2090 | 2099 | -- arg_wrap :: exp_arg ~> act_arg
|
| 2091 | 2100 | -- arg_wrap_frr :: exp_arg_frr ~> act_arg_frr
|
| 2092 | 2101 | |
| 2093 | - -- NB: because of the needs_eta guard, we know that mkWpFun will
|
|
| 2094 | - -- return (WpFun ...); so we might as well just use the WpFun constructor.
|
|
| 2095 | 2102 | ; return $
|
| 2096 | 2103 | mkWpCastN exp_arg_fun_co
|
| 2097 | 2104 | <.>
|
| 2098 | - WpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr)
|
|
| 2105 | + mkWpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr) exp_res
|
|
| 2099 | 2106 | <.>
|
| 2100 | - mkWpCastN act_arg_fun_co }
|
|
| 2101 | - | otherwise
|
|
| 2102 | - = return $
|
|
| 2103 | - mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res
|
|
| 2104 | - -- NB: because of 'needs_eta', this will never actually be a WpFun.
|
|
| 2105 | - -- mkWpFun will turn it into a WpHole or WpCast, which is why
|
|
| 2106 | - -- we can skip the hasFixedRuntimeRep checks in this case.
|
|
| 2107 | - -- See Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 2107 | + mkWpCastN act_arg_fun_co
|
|
| 2108 | + }
|
|
| 2108 | 2109 | where
|
| 2109 | - needs_eta :: Bool
|
|
| 2110 | - needs_eta =
|
|
| 2110 | + needs_frr_checks :: Bool
|
|
| 2111 | + needs_frr_checks =
|
|
| 2111 | 2112 | not (hole_or_cast arg_wrap)
|
| 2112 | 2113 | ||
|
| 2113 | 2114 | not (hole_or_cast res_wrap)
|
| ... | ... | @@ -2115,6 +2116,12 @@ mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res |
| 2115 | 2116 | hole_or_cast WpHole = True
|
| 2116 | 2117 | hole_or_cast (WpCast {}) = True
|
| 2117 | 2118 | hole_or_cast _ = False
|
| 2119 | + frr_ctxt :: Bool -> FixedRuntimeRepContext
|
|
| 2120 | + frr_ctxt is_exp_ty =
|
|
| 2121 | + FRRDeepSubsumption
|
|
| 2122 | + { frrDSExpected = is_exp_ty
|
|
| 2123 | + , frrDSPosition = pos
|
|
| 2124 | + }
|
|
| 2118 | 2125 | |
| 2119 | 2126 | -----------------------
|
| 2120 | 2127 | deeplySkolemise :: SkolemInfo -> TcSigmaType
|
| ... | ... | @@ -236,8 +236,10 @@ class Flag(GenericFlag): |
| 236 | 236 | reverse = self.options.get('reverse')
|
| 237 | 237 | if reverse is not None and reverse != '':
|
| 238 | 238 | # Make this also addressable via the reverse flag
|
| 239 | + # Strip leading hyphen to avoid double hyphen in anchor ID
|
|
| 240 | + clean_name = name[1:] if name.startswith('-') else name
|
|
| 239 | 241 | self.env.domaindata['std']['objects']['ghc-flag', reverse] = \
|
| 240 | - self.env.docname, 'ghc-flag-%s' % name
|
|
| 242 | + self.env.docname, 'ghc-flag-%s' % clean_name
|
|
| 241 | 243 | |
| 242 | 244 | # This class inherits from Sphinx's internal GenericObject, which drives
|
| 243 | 245 | # the add_object_type() utility function. We want to keep that tooling,
|
| ... | ... | @@ -73,7 +73,7 @@ testSetting key = do |
| 73 | 73 | TestLLC -> "LLC"
|
| 74 | 74 | TestTEST_CC -> "TEST_CC"
|
| 75 | 75 | TestTEST_CC_OPTS -> "TEST_CC_OPTS"
|
| 76 | - TestLeadingUnderscore -> "LeadingUnderscore"
|
|
| 76 | + TestLeadingUnderscore -> "GhcLeadingUnderscore"
|
|
| 77 | 77 | TestGhcPackageDb -> "GhcGlobalPackageDb"
|
| 78 | 78 | TestGhcLibDir -> "GhcLibdir"
|
| 79 | 79 |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | * Remove deprecated, unstable heap representation details from `GHC.Exts` ([CLC proposal #212](https://github.com/haskell/core-libraries-committee/issues/212))
|
| 5 | 5 | * Add `Data.List.NonEmpty.mapMaybe`. ([CLC proposal #337](https://github.com/haskell/core-libraries-committee/issues/337))
|
| 6 | 6 | * Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
|
| 7 | + * Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356))
|
|
| 7 | 8 | * Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
|
| 8 | 9 | * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
|
| 9 | 10 | * Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
|
| ... | ... | @@ -466,8 +466,8 @@ instance Fractional Float where |
| 466 | 466 | recip x = 1.0 / x
|
| 467 | 467 | |
| 468 | 468 | rationalToFloat :: Integer -> Integer -> Float
|
| 469 | -{-# NOINLINE [0] rationalToFloat #-}
|
|
| 470 | --- Re NOINLINE pragma, see Note [realToFrac natural-to-float]
|
|
| 469 | +{-# INLINE [0] rationalToFloat #-}
|
|
| 470 | +-- Re INLINE pragma, see Note [realToFrac natural-to-float]
|
|
| 471 | 471 | rationalToFloat n 0
|
| 472 | 472 | | n == 0 = 0/0
|
| 473 | 473 | | n < 0 = (-1)/0
|
| ... | ... | @@ -718,8 +718,8 @@ instance Fractional Double where |
| 718 | 718 | recip x = 1.0 / x
|
| 719 | 719 | |
| 720 | 720 | rationalToDouble :: Integer -> Integer -> Double
|
| 721 | -{-# NOINLINE [0] rationalToDouble #-}
|
|
| 722 | --- Re NOINLINE pragma, see Note [realToFrac natural-to-float]
|
|
| 721 | +{-# INLINE [0] rationalToDouble #-}
|
|
| 722 | +-- Re INLINE pragma, see Note [realToFrac natural-to-float]
|
|
| 723 | 723 | rationalToDouble n 0
|
| 724 | 724 | | n == 0 = 0/0
|
| 725 | 725 | | n < 0 = (-1)/0
|
| ... | ... | @@ -1673,7 +1673,11 @@ Now we'd have a BUILTIN constant folding rule for rationalToFloat; but |
| 1673 | 1673 | to allow that rule to fire reliably we should delay inlining rationalToFloat
|
| 1674 | 1674 | until stage 0. (It may get an inlining from CPR analysis.)
|
| 1675 | 1675 | |
| 1676 | -Hence the NOINLINE[0] rationalToFloat, and similarly rationalToDouble.
|
|
| 1676 | +Hence the INLINE[0] rationalToFloat, and similarly for rationalToDouble.
|
|
| 1677 | +This activation means:
|
|
| 1678 | + |
|
| 1679 | + - we don't inline until phase 0 (solving the above)
|
|
| 1680 | + - we do inline starting at phase 0 (because we do want it inlining in the end)
|
|
| 1677 | 1681 | -}
|
| 1678 | 1682 | |
| 1679 | 1683 | -- Utils
|
| ... | ... | @@ -10,11 +10,13 @@ module LintCodes.Coverage |
| 10 | 10 | |
| 11 | 11 | -- base
|
| 12 | 12 | import Data.Char
|
| 13 | - ( isAlphaNum, isDigit, isSpace )
|
|
| 13 | + ( isAlphaNum, isDigit, isSpace, toUpper )
|
|
| 14 | 14 | import Data.Maybe
|
| 15 | 15 | ( mapMaybe )
|
| 16 | 16 | import Data.List
|
| 17 | 17 | ( dropWhileEnd )
|
| 18 | +import System.Info
|
|
| 19 | + ( os )
|
|
| 18 | 20 | |
| 19 | 21 | -- bytestring
|
| 20 | 22 | import qualified Data.ByteString as ByteString
|
| ... | ... | @@ -28,7 +30,7 @@ import qualified Data.Set as Set |
| 28 | 30 | |
| 29 | 31 | -- directory
|
| 30 | 32 | import System.Directory
|
| 31 | - ( doesDirectoryExist, listDirectory )
|
|
| 33 | + ( doesDirectoryExist, listDirectory, makeAbsolute )
|
|
| 32 | 34 | |
| 33 | 35 | -- filepath
|
| 34 | 36 | import System.FilePath
|
| ... | ... | @@ -63,7 +65,12 @@ getCoveredCodes = |
| 63 | 65 | do { top <- dropWhileEnd isSpace
|
| 64 | 66 | <$> readProcess "git" ["rev-parse", "--show-toplevel"] ""
|
| 65 | 67 | -- TODO: would be better to avoid using git entirely.
|
| 66 | - ; let testRoot = top </> "testsuite" </> "tests"
|
|
| 68 | + |
|
| 69 | + -- When run inside an MSYS shell, git may return a Unix-style path
|
|
| 70 | + -- like /c/Blah. System.Directory doesn't like that, so we make sure
|
|
| 71 | + -- to turn that into C:/Blah. See #25178.
|
|
| 72 | + ; top' <- fixupMsysDrive top
|
|
| 73 | + ; let testRoot = top' </> "testsuite" </> "tests"
|
|
| 67 | 74 | ; traverseFilesFrom includeFile diagnosticCodesIn testRoot
|
| 68 | 75 | }
|
| 69 | 76 | |
| ... | ... | @@ -158,3 +165,14 @@ traverseFilesFrom include_file parse_contents = go |
| 158 | 165 | { Left _ -> mempty
|
| 159 | 166 | ; Right txt -> parse_contents txt
|
| 160 | 167 | } } } }
|
| 168 | + |
|
| 169 | +-- | On Windows, change MSYS-style @/c/Blah@ to @C:/Blah@. See #25178.
|
|
| 170 | +fixupMsysDrive :: FilePath -> IO FilePath
|
|
| 171 | +fixupMsysDrive fp = do
|
|
| 172 | + fixedUp <-
|
|
| 173 | + if | os == "mingw32" || os == "win32"
|
|
| 174 | + , ('/':drv:'/':rest) <- fp
|
|
| 175 | + -> return $ toUpper drv : ':':'/':rest
|
|
| 176 | + | otherwise
|
|
| 177 | + -> return fp
|
|
| 178 | + makeAbsolute fixedUp |
| ... | ... | @@ -64,7 +64,7 @@ static bool fitsBits(size_t bits, int64_t value); |
| 64 | 64 | static int64_t decodeAddend(ObjectCode * oc, Section * section,
|
| 65 | 65 | MachORelocationInfo * ri);
|
| 66 | 66 | static void encodeAddend(ObjectCode * oc, Section * section,
|
| 67 | - MachORelocationInfo * ri, int64_t addend);
|
|
| 67 | + MachORelocationInfo * ri, int64_t addend, MachOSymbol * symbol);
|
|
| 68 | 68 | |
| 69 | 69 | /* Global Offset Table logic */
|
| 70 | 70 | static bool isGotLoad(MachORelocationInfo * ri);
|
| ... | ... | @@ -361,15 +361,21 @@ fitsBits(size_t bits, int64_t value) { |
| 361 | 361 | |
| 362 | 362 | static void
|
| 363 | 363 | encodeAddend(ObjectCode * oc, Section * section,
|
| 364 | - MachORelocationInfo * ri, int64_t addend) {
|
|
| 364 | + MachORelocationInfo * ri, int64_t addend, MachOSymbol * symbol) {
|
|
| 365 | 365 | uint32_t * p = (uint32_t*)((uint8_t*)section->start + ri->r_address);
|
| 366 | 366 | |
| 367 | 367 | checkProddableBlock(&oc->proddables, (void*)p, 1 << ri->r_length);
|
| 368 | 368 | |
| 369 | + const char *symbol_name = symbol && symbol->name ? (char*)symbol->name : "<unknown>";
|
|
| 370 | + const char *file_name = oc->fileName ? (char*)oc->fileName : "<unknown>";
|
|
| 371 | + |
|
| 369 | 372 | switch (ri->r_type) {
|
| 370 | 373 | case ARM64_RELOC_UNSIGNED: {
|
| 371 | - if(!fitsBits(8 << ri->r_length, addend))
|
|
| 372 | - barf("Relocation out of range for UNSIGNED");
|
|
| 374 | + if(!fitsBits(8 << ri->r_length, addend)) {
|
|
| 375 | + const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
| 376 | + barf("Relocation out of range for UNSIGNED in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
| 377 | + file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
| 378 | + }
|
|
| 373 | 379 | switch (ri->r_length) {
|
| 374 | 380 | case 0: *(uint8_t*)p = (uint8_t)addend; break;
|
| 375 | 381 | case 1: *(uint16_t*)p = (uint16_t)addend; break;
|
| ... | ... | @@ -382,8 +388,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
| 382 | 388 | return;
|
| 383 | 389 | }
|
| 384 | 390 | case ARM64_RELOC_SUBTRACTOR: {
|
| 385 | - if(!fitsBits(8 << ri->r_length, addend))
|
|
| 386 | - barf("Relocation out of range for SUBTRACTOR");
|
|
| 391 | + if(!fitsBits(8 << ri->r_length, addend)) {
|
|
| 392 | + const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
| 393 | + barf("Relocation out of range for SUBTRACTOR in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
| 394 | + file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
| 395 | + }
|
|
| 387 | 396 | switch (ri->r_length) {
|
| 388 | 397 | case 0: *(uint8_t*)p = (uint8_t)addend; break;
|
| 389 | 398 | case 1: *(uint16_t*)p = (uint16_t)addend; break;
|
| ... | ... | @@ -400,8 +409,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
| 400 | 409 | * do not need the last two bits of the value. If the value >> 2
|
| 401 | 410 | * still exceeds 26bits, we won't be able to reach it.
|
| 402 | 411 | */
|
| 403 | - if(!fitsBits(26, addend >> 2))
|
|
| 404 | - barf("Relocation target for BRACH26 out of range.");
|
|
| 412 | + if(!fitsBits(26, addend >> 2)) {
|
|
| 413 | + const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
| 414 | + barf("Relocation target for BRANCH26 out of range in %s: symbol '%s', addend 0x%llx (0x%llx >> 2), address 0x%llx, library: %s",
|
|
| 415 | + file_name, symbol_name, (long long)addend, (long long)(addend >> 2), (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
| 416 | + }
|
|
| 405 | 417 | *p = (*p & 0xFC000000) | ((uint32_t)(addend >> 2) & 0x03FFFFFF);
|
| 406 | 418 | return;
|
| 407 | 419 | }
|
| ... | ... | @@ -412,8 +424,12 @@ encodeAddend(ObjectCode * oc, Section * section, |
| 412 | 424 | * with the PAGEOFF12 relocation allows to address a relative range
|
| 413 | 425 | * of +-4GB.
|
| 414 | 426 | */
|
| 415 | - if(!fitsBits(21, addend >> 12))
|
|
| 416 | - barf("Relocation target for PAGE21 out of range.");
|
|
| 427 | + if(!fitsBits(21, addend >> 12)) {
|
|
| 428 | + const char *reloc_type = (ri->r_type == ARM64_RELOC_PAGE21) ? "PAGE21" : "GOT_LOAD_PAGE21";
|
|
| 429 | + const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
| 430 | + barf("Relocation target for %s out of range in %s: symbol '%s', addend 0x%llx (0x%llx >> 12), address 0x%llx, library: %s",
|
|
| 431 | + reloc_type, file_name, symbol_name, (long long)addend, (long long)(addend >> 12), (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
| 432 | + }
|
|
| 417 | 433 | *p = (*p & 0x9F00001F) | (uint32_t)((addend << 17) & 0x60000000)
|
| 418 | 434 | | (uint32_t)((addend >> 9) & 0x00FFFFE0);
|
| 419 | 435 | return;
|
| ... | ... | @@ -423,8 +439,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
| 423 | 439 | /* Store an offset into a page (4k). Depending on the instruction
|
| 424 | 440 | * the bits are stored at slightly different positions.
|
| 425 | 441 | */
|
| 426 | - if(!fitsBits(12, addend))
|
|
| 427 | - barf("Relocation target for PAGEOFF12 out or range.");
|
|
| 442 | + if(!fitsBits(12, addend)) {
|
|
| 443 | + const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
| 444 | + barf("Relocation target for PAGEOFF12 out of range in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
| 445 | + file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
| 446 | + }
|
|
| 428 | 447 | |
| 429 | 448 | int shift = 0;
|
| 430 | 449 | if(isLoadStore(p)) {
|
| ... | ... | @@ -589,7 +608,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
| 589 | 608 | MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
|
| 590 | 609 | int64_t addend = decodeAddend(oc, section, ri);
|
| 591 | 610 | uint64_t value = symbol_value(oc, symbol);
|
| 592 | - encodeAddend(oc, section, ri, value + addend);
|
|
| 611 | + encodeAddend(oc, section, ri, value + addend, symbol);
|
|
| 593 | 612 | break;
|
| 594 | 613 | }
|
| 595 | 614 | case ARM64_RELOC_SUBTRACTOR:
|
| ... | ... | @@ -623,7 +642,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
| 623 | 642 | |
| 624 | 643 | // combine with addend and store
|
| 625 | 644 | int64_t addend = decodeAddend(oc, section, ri);
|
| 626 | - encodeAddend(oc, section, ri, addend - sub_value + add_value);
|
|
| 645 | + encodeAddend(oc, section, ri, addend - sub_value + add_value, symbol1);
|
|
| 627 | 646 | |
| 628 | 647 | // skip next relocation: we've already handled it
|
| 629 | 648 | i += 1;
|
| ... | ... | @@ -664,7 +683,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
| 664 | 683 | }
|
| 665 | 684 | }
|
| 666 | 685 | }
|
| 667 | - encodeAddend(oc, section, ri, value - pc + addend);
|
|
| 686 | + encodeAddend(oc, section, ri, value - pc + addend, symbol);
|
|
| 668 | 687 | break;
|
| 669 | 688 | }
|
| 670 | 689 | case ARM64_RELOC_PAGE21:
|
| ... | ... | @@ -676,7 +695,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
| 676 | 695 | uint64_t pc = (uint64_t)section->start + ri->r_address;
|
| 677 | 696 | uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
|
| 678 | 697 | ASSERT(!isGotLoad(ri) || (symbol->got_addr != 0));
|
| 679 | - encodeAddend(oc, section, ri, ((value + addend + explicit_addend) & (-4096)) - (pc & (-4096)));
|
|
| 698 | + encodeAddend(oc, section, ri, ((value + addend + explicit_addend) & (-4096)) - (pc & (-4096)), symbol);
|
|
| 680 | 699 | |
| 681 | 700 | // reset, just in case.
|
| 682 | 701 | explicit_addend = 0;
|
| ... | ... | @@ -690,7 +709,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
| 690 | 709 | barf("explicit_addend and addend can't be set at the same time.");
|
| 691 | 710 | uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
|
| 692 | 711 | ASSERT(!isGotLoad(ri) || (symbol->got_addr != 0));
|
| 693 | - encodeAddend(oc, section, ri, 0xFFF & (value + addend + explicit_addend));
|
|
| 712 | + encodeAddend(oc, section, ri, 0xFFF & (value + addend + explicit_addend), symbol);
|
|
| 694 | 713 | |
| 695 | 714 | // reset, just in case.
|
| 696 | 715 | explicit_addend = 0;
|
| ... | ... | @@ -43,7 +43,7 @@ main = do |
| 43 | 43 | getGhcFieldOrDefault fields "TargetRTSLinkerOnlySupportsSharedLibs" "target RTS linker only supports shared libraries" "NO"
|
| 44 | 44 | getGhcFieldOrDefault fields "GhcDynamic" "GHC Dynamic" "NO"
|
| 45 | 45 | getGhcFieldOrDefault fields "GhcProfiled" "GHC Profiled" "NO"
|
| 46 | - getGhcFieldOrDefault fields "LeadingUnderscore" "Leading underscore" "NO"
|
|
| 46 | + getGhcFieldOrDefault fields "GhcLeadingUnderscore" "Leading underscore" "NO"
|
|
| 47 | 47 | getGhcFieldOrDefault fields "GhcTablesNextToCode" "Tables next to code" "NO"
|
| 48 | 48 | getGhcFieldProgWithDefault fields "AR" "ar command" "ar"
|
| 49 | 49 | getGhcFieldProgWithDefault fields "LLC" "LLVM llc command" "llc"
|
| ... | ... | @@ -179,24 +179,23 @@ test('T7060', [], makefile_test, []) |
| 179 | 179 | test('T7130', normal, compile_fail, ['-fflul-laziness'])
|
| 180 | 180 | test('T7563', when(unregisterised(), skip), makefile_test, [])
|
| 181 | 181 | test('T6037',
|
| 182 | - # The testsuite doesn't know how to set a non-Unicode locale on Windows or MacOS < Sonoma.
|
|
| 183 | - # Because in previous version of MacOS the test is still broken, we mark it as fragile.
|
|
| 182 | + # Requires forcing a 7-bit/ASCII-only locale.
|
|
| 183 | + # - On Windows (mingw32) the testsuite can't reliably set a non-Unicode C locale -> expect_fail.
|
|
| 184 | + # - On modern Darwin there are no pure ASCII locales available -> skip.
|
|
| 184 | 185 | [when(opsys('mingw32'), expect_fail),
|
| 185 | - when(opsys('darwin'), fragile(24161))
|
|
| 186 | + when(opsys('darwin'), skip)
|
|
| 186 | 187 | ],
|
| 187 | 188 | makefile_test, [])
|
| 188 | 189 | test('T2507',
|
| 189 | - # The testsuite doesn't know how to set a non-Unicode locale on Windows or MacOS < Sonoma
|
|
| 190 | - # Because in previous version of MacOS the test is still broken, we mark it as fragile.
|
|
| 190 | + # Same locale assumptions as T6037 (ASCII-only needed, unavailable on Darwin; untestable on Windows).
|
|
| 191 | 191 | [when(opsys('mingw32'), expect_fail),
|
| 192 | - when(opsys('darwin'), fragile(24161))
|
|
| 192 | + when(opsys('darwin'), skip)
|
|
| 193 | 193 | ],
|
| 194 | 194 | makefile_test, [])
|
| 195 | 195 | test('T8959a',
|
| 196 | - # The testsuite doesn't know how to set a non-Unicode locale on Windows or MacOS < Sonoma
|
|
| 197 | - # Because in previous version of MacOS the test is still broken, we mark it as fragile.
|
|
| 196 | + # Same locale assumptions as T6037 (ASCII-only needed, unavailable on Darwin; untestable on Windows).
|
|
| 198 | 197 | [when(opsys('mingw32'), expect_fail),
|
| 199 | - when(opsys('darwin'), fragile(24161))
|
|
| 198 | + when(opsys('darwin'), skip)
|
|
| 200 | 199 | ],
|
| 201 | 200 | makefile_test, [])
|
| 202 | 201 |
| 1 | +{-# LANGUAGE DeepSubsumption #-}
|
|
| 2 | +{-# LANGUAGE LinearTypes #-}
|
|
| 3 | + |
|
| 4 | +module T26332 where
|
|
| 5 | + |
|
| 6 | +import Unsafe.Coerce
|
|
| 7 | + |
|
| 8 | +toLinear
|
|
| 9 | + :: forall a b p q.
|
|
| 10 | + (a %p-> b) %1-> (a %q-> b)
|
|
| 11 | +toLinear f = case unsafeEqualityProof @p @q of
|
|
| 12 | + UnsafeRefl -> f |
| ... | ... | @@ -41,6 +41,7 @@ test('T19400', unless(compiler_debugged(), skip), compile, ['']) |
| 41 | 41 | test('T20023', normal, compile, [''])
|
| 42 | 42 | test('T22546', normal, compile, [''])
|
| 43 | 43 | test('T23025', normal, compile, ['-dlinear-core-lint'])
|
| 44 | +test('T26332', normal, compile, ['-O -dlinear-core-lint'])
|
|
| 44 | 45 | test('LinearRecUpd', normal, compile, [''])
|
| 45 | 46 | test('T23814', normal, compile, [''])
|
| 46 | 47 | test('LinearLet', normal, compile, [''])
|
| 1 | +module M where
|
|
| 2 | + |
|
| 3 | +import GHC.Exts ( Any )
|
|
| 4 | +import Unsafe.Coerce ( unsafeCoerce )
|
|
| 5 | + |
|
| 6 | +data Sigma = MkT Any
|
|
| 7 | + |
|
| 8 | +testSubList :: Maybe Bool -> Sigma -> Sigma
|
|
| 9 | +testSubList (Just x) final = {-# SCC "y" #-} (
|
|
| 10 | + let x' = seq x ()
|
|
| 11 | + in case testSubList Nothing final of
|
|
| 12 | + MkT w -> {-# SCC "x" #-}
|
|
| 13 | + (unsafeCoerce MkT (konst x' myHead (unsafeCoerce w))))
|
|
| 14 | +testSubList Nothing final = final
|
|
| 15 | + |
|
| 16 | +myHead :: [a] -> a
|
|
| 17 | +myHead (x:_) = x
|
|
| 18 | + |
|
| 19 | +konst :: () -> ([a] -> a) -> [a] -> a
|
|
| 20 | +konst _ x = x
|
|
| 21 | +{-# OPAQUE konst #-} |
| ... | ... | @@ -20,3 +20,4 @@ test('T14931', [test_opts, unless(have_dynamic(), skip)], |
| 20 | 20 | test('T15108', [test_opts], compile, ['-O -prof -fprof-auto'])
|
| 21 | 21 | test('T19894', [test_opts, extra_files(['T19894'])], multimod_compile, ['Main', '-v0 -O2 -prof -fprof-auto -iT19894'])
|
| 22 | 22 | test('T20938', [test_opts], compile, ['-O -prof'])
|
| 23 | +test('T26056', [test_opts], compile, ['-O -prof']) |
| ... | ... | @@ -2,8 +2,11 @@ |
| 2 | 2 | #include <stdio.h>
|
| 3 | 3 | #include <errno.h>
|
| 4 | 4 | |
| 5 | -// Prints the state of the signal handlers to stdout
|
|
| 6 | -int main()
|
|
| 5 | +// Prints the state of the signal handlers to stdout.
|
|
| 6 | +// NOTE: We intentionally start at signal 1 (not 0). Signal number 0 is not a
|
|
| 7 | +// real signal; passing 0 to sigismember/sigaction is undefined behaviour and
|
|
| 8 | +// on Darwin was observed to yield memory corruption / junk bytes in output.
|
|
| 9 | +int main(void)
|
|
| 7 | 10 | {
|
| 8 | 11 | int open = 0, i;
|
| 9 | 12 | sigset_t blockedsigs;
|
| ... | ... | @@ -11,7 +14,7 @@ int main() |
| 11 | 14 | printf("ChildInfo { masked = [");
|
| 12 | 15 | |
| 13 | 16 | sigprocmask(SIG_BLOCK, NULL, &blockedsigs);
|
| 14 | - for(i = 0; i < NSIG; ++i)
|
|
| 17 | + for(i = 1; i < NSIG; ++i)
|
|
| 15 | 18 | {
|
| 16 | 19 | int ret = sigismember(&blockedsigs, i);
|
| 17 | 20 | if(ret >= 0)
|
| ... | ... | @@ -26,7 +29,7 @@ int main() |
| 26 | 29 | printf("], handlers = [");
|
| 27 | 30 | |
| 28 | 31 | open = 0;
|
| 29 | - for(i = 0; i < NSIG; ++i)
|
|
| 32 | + for(i = 1; i < NSIG; ++i)
|
|
| 30 | 33 | {
|
| 31 | 34 | struct sigaction old;
|
| 32 | 35 | if(sigaction(i, NULL, &old) >= 0)
|
| ... | ... | @@ -33,7 +33,12 @@ test('T11223_simple_duplicate', |
| 33 | 33 | |
| 34 | 34 | test('T11223_simple_duplicate_lib',
|
| 35 | 35 | [extra_files(['bar.c', 'foo.c', 'foo.hs']),
|
| 36 | - when(ghc_dynamic(), skip), normalise_errmsg_fun(normalise_duplicate_errmsg),
|
|
| 36 | + when(ghc_dynamic(), skip),
|
|
| 37 | + # Darwin/Mach-O reports external C symbols with a leading underscore (e.g. _a, _c)
|
|
| 38 | + # which our expected stderr (shared with ELF platforms) does not account for.
|
|
| 39 | + # Rather than broaden normalisation here, skip on darwin for now.
|
|
| 40 | + when(opsys('darwin'), skip),
|
|
| 41 | + normalise_errmsg_fun(normalise_duplicate_errmsg),
|
|
| 37 | 42 | req_c],
|
| 38 | 43 | makefile_test, ['t_11223_simple_duplicate_lib'])
|
| 39 | 44 | |
| ... | ... | @@ -57,7 +62,10 @@ test('T11223_link_order_b_a_succeed', |
| 57 | 62 | |
| 58 | 63 | test('T11223_link_order_a_b_2_fail',
|
| 59 | 64 | [extra_files(['bar.c', 'foo.c', 'foo3.hs']),
|
| 60 | - when(ghc_dynamic(), skip), normalise_errmsg_fun(normalise_duplicate_errmsg),
|
|
| 65 | + when(ghc_dynamic(), skip),
|
|
| 66 | + # See note above about Mach-O leading underscores; skip on darwin.
|
|
| 67 | + when(opsys('darwin'), skip),
|
|
| 68 | + normalise_errmsg_fun(normalise_duplicate_errmsg),
|
|
| 61 | 69 | req_c],
|
| 62 | 70 | makefile_test, ['t_11223_link_order_a_b_2_fail'])
|
| 63 | 71 |