[GHC] #9122: Make Lint check for bad uses of `unsafeCoerce`

#9122: Make Lint check for bad uses of `unsafeCoerce` ------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- I think it would be a great idea for Core Lint to check for uses of `unsafeCoerce` that don't obey the rules. It won't catch all cases, of course, but it would have caught #9035. Specficially, look for: * Coercions between lifted and unboxed types * Coercion between unboxed types of different sizes * Coercion between unboxed ints and floats. Would anyone like to make a patch for this? Anything that can be checked by Core Lint, should be checked! I'm afraid I don't know where to look for the reason for the int/float difficulty. I'd write a tiny function that exhibits the unsafe conversion and look the code it generates. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by goldfire): What are "the rules"? Where are they written? And, what if someone ''wants'' to do one of the things mentioned? I can imagine wanting to coerce between lifted and unboxed types or between ints and floats. (Unboxed types of different sizes, I tend to agree, wouldn't want to get coerced.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): The rules are documented with `unsafeCoerce`, [http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.3.1.0 /GHC-Prim.html#v:unsafeCoerce-35- here]. It's pretty much guaranteed that coercing from, say `Int#` to `Int` will give rise to serious problems. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by goldfire): I was thinking of someone who wanted the raw pointer associated with a value of a lifted type. Coercing `Int` to `Int#` would seemingly get that pointer value. It's conceivable to me to imagine scenarios where this behavior is desired, such as debugging against some sort of memory dump. Going the other way might also be desirable, if Haskell code has to operate against some pre-loaded memory image. Maybe these sorts of things never happen in Haskell, but I've done them (when debugging kernels / device drivers) in other languages. Or, is the idea that all such shenanigans are subsumed by `Foreign.Ptr` and friends? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): Right after you get the pointer in your hand, garbage collection may happen, which moves the object. This way lies madness. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by goldfire): Fair enough -- such users can always simply avoid `-dcore-lint` anyway. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: | Blocked By: None/Unknown | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by goldfire): * keywords: => newcomer Comment: I'm happy to advise a newcomer if they want to take this one on. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by qnikst): * owner: => qnikst -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by goldfire): I'm helping qnikst out with this, but I have a question. Say someone writes {{{ unsafeCoerce# (3 :: Int) :: Int# }}} According to the original feature request, this should be a Core Lint error. However, is it an error earlier in the GHC pipeline? In 7.8.3, this compiles just fine, though it falls over rather completely when run. (No surprise there!) If it's ''not'' an error earlier, this would seem to violate the principle that Core Lint should just be checking for GHC bugs, not user silliness. So, is it necessary to check for such silliness in the typechecker now, too? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by simonpj): I don't know how to reason about what might be "an error at some particular stage of the pipeline". ANY use of `unsafeCoerce` might make a program seg-fault. So at best these checks are going to smoke out uses that are more than usually likely to cause this behaviour. It's all very squishy. Ask a more specific question and I'll try to help. S -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:637 -------------------------------------+------------------------------------- Changes (by qnikst): * differential: => Phab:637 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

I don't know how to reason about what might be "an error at some
#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:637 -------------------------------------+------------------------------------- Comment (by qnikst): Replying to [comment:9 simonpj]: particular stage of the pipeline".
ANY use of `unsafeCoerce` might make a program seg-fault. So at best
these checks are going to smoke out uses that are more than usually likely to cause this behaviour. It's all very squishy. Ask a more specific question and I'll try to help.
S
I think that Richard means that this check may be useful also in a typechecker, as lint will help from problems introduced by ghc, but doesn't prevent from incorrect programs to be written and accepted by typechecker. So idea was also perform this check in typechecker. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D637 -------------------------------------+------------------------------------- Changes (by qnikst): * differential: Phab:637 => Phab:D637 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D637 -------------------------------------+------------------------------------- Comment (by goldfire): Should the type-checker reject `unsafeCoerce# (3 :: Int) :: Int#`? If not, the proposed change would mean that `-dcore-lint` would show an error even when GHC is not at fault. Or, another (opposite) way to ask the question: Should a program containing that chunk, but compiled ''without'' `-dcore- lint`, be accepted? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D637 -------------------------------------+------------------------------------- Comment (by qnikst): I want to clarify following questions about required semantics: 1. Coercion between unboxed types of different sizes Do we want to check _real_ (word aligned size of values) or _active_ (i.e. number of significant bytes)? (On Phab I assumed latter). But what about UnboxedTuples it seems that checking active size is not totally correct there? 2. Coercion between unboxed ints and floats. I see one usecase for such coercions, for example we have an array of floats, or unboxed tuple, and we want to calculate checksum, then we want to treat that array as an array of other base type. What should we do around unboxed tuples in this check? (On Phab I disabled check for unboxed tuples) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D637 -------------------------------------+------------------------------------- Description changed by simonpj: Old description:
I think it would be a great idea for Core Lint to check for uses of `unsafeCoerce` that don't obey the rules. It won't catch all cases, of course, but it would have caught #9035. Specficially, look for: * Coercions between lifted and unboxed types * Coercion between unboxed types of different sizes * Coercion between unboxed ints and floats.
Would anyone like to make a patch for this? Anything that can be checked by Core Lint, should be checked!
I'm afraid I don't know where to look for the reason for the int/float difficulty. I'd write a tiny function that exhibits the unsafe conversion and look the code it generates.
Simon
New description: I think it would be a great idea for Core Lint to check for uses of `unsafeCoerce` that don't obey the rules. It won't catch all cases, of course, but it would have caught #9035. Specficially, look for: * Coercions between lifted and unboxed types * Coercion between unboxed types of different sizes * Coercion between unboxed ints and floats. Would anyone like to make a patch for this? Anything that can be checked by Core Lint, should be checked! I'm afraid I don't know where to look for the reason for the int/float difficulty. I'd write a tiny function that exhibits the unsafe conversion and look the code it generates. Wiki design page [wiki:BadUnsafeCoercions] -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9122: Make Lint check for bad uses of `unsafeCoerce`
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: qnikst
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.2
Resolution: | Keywords: newcomer
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D637
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#9122: Make Lint check for bad uses of `unsafeCoerce` -------------------------------------+------------------------------------- Reporter: simonpj | Owner: qnikst Type: bug | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: newcomer Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D637 -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: new => closed * resolution: => fixed * milestone: => 7.12.1 Comment: Merged, thanks Alexander! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9122#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC