Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,870
    • Issues 4,870
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 453
    • Merge requests 453
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #21396
Closed
Open
Created Apr 15, 2022 by Andreas Klebinger@AndreasKDeveloper

Silly shadowing issue in StgUnarise.

Unarise walks the AST and splits certain arguments into multiple arguments (unboxed tuples) while turning other into void args. In order to do so we keep a map of in scope variables and their post-unarise representation.

However, this is excessive for the common case, that is variables representing a single runtime value. So instead of adding these to the map, we just omit them from the map and when we rewrite occurrences and there is no entry for a variable we assume it can be used as is.

Disaster strikes if shadowing comes into play:

f = \(Eta_B0 :: VoidType) x1 x2 ->
   ... let foo = \(Eta_B0 :: LiftedType) -> g x y Eta_B0 
       in ...

What goes wrong?

  • We first start process f see it has a void argument Eta_B0 and add that to the environment and process it's rhs.
  • In the RHS of 'f' we start processing foo. We see foo has a single-rep argument Eta_B0. Since it's single rep we don't bother adding it to the environment.
  • We proceed to look at the rhs of foo. See an occurrence of Eta_B0 and check if we need to replace it. To do so we check if Eta_B0 has an entry in the environment. And it has! We find the entry that is "left over" from fs arguments. Assume it's an void argument and pass no argument at runtime.
  • This means when compiling foo we simply don't pass the third argument to g. And g uses whatever garbage it has in the argument register and most likely eventually segfaults.

The fix is then rather simple. Whenever a new variable comes into scope either purge the environment of any mention for it if it is single rep, or if not overwrite the entry in the env (the later we already do).

Besides the fix stg lint should be able to catch things like these. Maybe I will add a check there too.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking