CoreLint check for case with no alts

Ömer Sinan Ağacan omeragacan at gmail.com
Mon Feb 29 21:42:58 UTC 2016


> So feel free to make Lint cleverer; make sure you add a Note.  But if it
> /needs/ to be cleverer, that suggests that the simplifier should be cleverer
> instead, and should simplify the code so that even a dumb Core Lint has no
> trouble.

Good point. The problem is linter is checking every intermediate Core, and
apparently not all Core passes are that smart about simplifications.

> In your example why didn't the simplifier do case-of-case?

This code is generated by floatIn (FloatInwards).


One more question. Do you think this is a safe change in coreToStgExpr that
handles empty cases:

    coreToStgExpr (Case scrut bndr ty [])
      = coreToStgExpr (Case scrut bndr ty [(DEFAULT, [], mkImpossibleExpr ty)])

When I make this change some programs are failing with this:

    Oops!  Entered absent arg w_sc1l FilePath

But that may be because of some libraries I need to recompile, although I'm not
sure why this would be the case.

The problem I'm trying to solve is my lint-safe (after the smarter lint check
about bottoming expressions) programs are failing with segfaults. Of course
that may be because I'm doing something wrong in STG level, but I'm trying to
make sure everything above STG is correct and bug-free. It'd be really great if
I could somehow generate an erroring expression in some places that are
supposed to be unreachable, just to make sure my segfaults are not related with
those.

2016-02-29 6:32 GMT-05:00 Simon Peyton Jones <simonpj at microsoft.com>:
> |  I wanted to ask: Is there a restriction on what kind empty case
> |  expressions are supported by the code generator or can I just improve
> |  the lint check and assume that the code will be handled by the code
> |  generator correctly?
>
> I believe the latter.  See CoreToStg line 364.
>
> So feel free to make Lint cleverer; make sure you add a Note.  But if it /needs/ to be cleverer, that suggests that the simplifier should be cleverer instead, and should simplify the code so that even a dumb Core Lint has no trouble.
>
> In your example why didn't the simplifier do case-of-case?
>
> I suppose that this might be after some pass and before a simplifier run.
>
> Simon
>
> |  -----Original Message-----
> |  From: ghc-devs [mailto:ghc-devs-bounces at haskell.org] On Behalf Of Ömer
> |  Sinan Agacan
> |  Sent: 29 February 2016 03:16
> |  To: ghc-devs <ghc-devs at haskell.org>
> |  Subject: CoreLint check for case with no alts
> |
> |  Hi all,
> |
> |  CoreLint has a check that, when seeing a case expression with empty
> |  list of alternatives, checks whether the scrutinee is bottom. This
> |  "bottom-ness" check is, however, very simple and returning many false
> |  negatives. For example, when it sees a case expression, all it does is:
> |
> |      go _ (Case _ _ _ alts)       = null alts
> |
> |  Which is just too simple for some cases. (it could check if all the
> |  RHSs are bottom, or if the scrutinee is bottom etc.)
> |
> |  I guess this makes sense, since it's OK to generate unreachable code,
> |  but it's not OK to not generate a code in a reachable path.
> |
> |  But in my case this is becoming problem as it's rejecting my seemingly
> |  valid program. One of the relevant parts in my code is this:
> |
> |      case ww_s4C3 of ww_X4Fb {
> |        (#_||#) ww_s4Ce ->
> |          case case ww_s4Ce of ww_s4F1 { (# ww_s4F2, ww_s4F3 #) ->
> |               lvl_s4F4 ww_s4F3 ww_s4F2
> |               }
> |          of wild_00 {
> |            -- empty
> |          };
> |
> |      lvl_s4F4 :: Int# -> String -> Var
> |      [LclId, Arity=2, Str=DmdType (args: <L,U><L,U>) (res: x)]
> |      lvl_s4F4 =
> |        \ (ww_s4F3 :: Int#) (ww_s4F2 :: String) ->
> |          lvl_s3V4 (TyVar ww_s4F2 ww_s4F3)
> |
> |      lvl_s3V4 :: Var -> Var
> |      [LclId, Arity=1, CallArity=1, Str=DmdType (args: <B,1*H>) (res: x)]
> |      lvl_s3V4 = \ (i_a1vO :: Var) -> lvl_s4EZ i_a1vO
> |
> |      lvl_s4EZ :: Var -> Var
> |      [LclId, Arity=1, Str=DmdType (args: <L,U>) (res: x)]
> |      lvl_s4EZ = \ (i_a1vO :: Var) -> error ...
> |
> |  The scrutinee part of the case expression in the alternative is clearly
> |  bottom, but this expression is rejected by the linter.
> |
> |  One easy solution is to implement a more precise test and use it in
> |  linter. But I thought maybe the current implementation is deliberately
> |  so. Maybe the code generator doesn't support that type of code etc. so
> |  I wanted to ask: Is there a restriction on what kind empty case
> |  expressions are supported by the code generator or can I just improve
> |  the lint check and assume that the code will be handled by the code
> |  generator correctly?
> |
> |  Thanks.
> |  _______________________________________________
> |  ghc-devs mailing list
> |  ghc-devs at haskell.org
> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha
> |  skell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-
> |  devs&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7ce621b9bcb2774ff8
> |  522208d340b6c5a7%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=cIiMVTgiH
> |  ibh0SNksSZGLK75bZBgb3HA13USf78ohyQ%3d


More information about the ghc-devs mailing list