Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

GHC inlining primitive string literals can affect program output
First noted in #11292, this program, when compiled with `-O1` or higher: ```hs {-# LANGUAGE MagicHash #-} module Main (main) where import GHC.Exts (Addr#, isTrue#) import GHC.Prim (eqAddr#) data A = A { runA :: Addr# } a :: A a = A "a"# main :: IO () main = print (isTrue# (eqAddr# (runA a) (runA a))) ``` will result in the following after inlining: ``` Main.main2 = case GHC.Prim.tagToEnum# @ GHC.Types.Bool (GHC.Prim.eqAddr# "a"# "a"#) of _ [Occ=Dead] { GHC.Types.False -> GHC.Show.shows26; GHC.Types.True -> GHC.Show.shows24 } ``` As a result, there are two of the same string constant with different addresses, which causes `eqAddr#` to return `False`. If compiled without optimizations, `"a"#` is not inlined, and as a result, `eqAddr#` returns `True`. Two questions: 1. Is this okay semantics-wise? Or is this a necessary risk when working with primitive string literals, and should programmers judiciously use `{-# NOINLINE #-}` with them? 1. Is this okay from a code duplication standpoint? As Reid Barton noted in #11292, `"a"#` is duplicated due to inlining. In this example, not much is duplicated, but if it were a longer string constant, that could result in a noticeable increase in the object file size. <details><summary>Trac metadata</summary> | Trac field | Value | | ---------------------- | ------------ | | Version | 7.10.3 | | Type | Bug | | TypeOfFailure | OtherFailure | | Priority | normal | | Resolution | Unresolved | | Component | Compiler | | Test case | | | Differential revisions | | | BlockedBy | | | Related | #11292 | | Blocking | | | CC | | | Operating system | | | Architecture | | </details> <!-- {"blocked_by":[],"summary":"GHC inlining primitive string literals can affect program output","status":"New","operating_system":"","component":"Compiler","related":[11292],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"First noted in #11292, this program, when compiled with `-O1` or higher:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE MagicHash #-}\r\nmodule Main (main) where\r\n\r\nimport GHC.Exts (Addr#, isTrue#)\r\nimport GHC.Prim (eqAddr#)\r\n\r\ndata A = A { runA :: Addr# }\r\n\r\na :: A\r\na = A \"a\"#\r\n\r\nmain :: IO ()\r\nmain = print (isTrue# (eqAddr# (runA a) (runA a)))\r\n}}}\r\n\r\nwill result in the following after inlining:\r\n\r\n{{{\r\nMain.main2 =\r\n case GHC.Prim.tagToEnum#\r\n @ GHC.Types.Bool (GHC.Prim.eqAddr# \"a\"# \"a\"#)\r\n of _ [Occ=Dead] {\r\n GHC.Types.False -> GHC.Show.shows26;\r\n GHC.Types.True -> GHC.Show.shows24\r\n }\r\n}}}\r\n\r\nAs a result, there are two of the same string constant with different addresses, which causes `eqAddr#` to return `False`. If compiled without optimizations, `\"a\"#` is not inlined, and as a result, `eqAddr#` returns `True`.\r\n\r\nTwo questions:\r\n\r\n1. Is this okay semantics-wise? Or is this a necessary risk when working with primitive string literals, and should programmers judiciously use `{-# NOINLINE #-}` with them?\r\n2. Is this okay from a code duplication standpoint? As Reid Barton noted in #11292, `\"a\"#` is duplicated due to inlining. In this example, not much is duplicated, but if it were a longer string constant, that could result in a noticeable increase in the object file size.","type_of_failure":"OtherFailure","blocking":[]} -->
issue