[commit: ghc] master: Do not treat prim and javascript imports as C imports in TH and QQ (4cd008b)
git at git.haskell.org
git at git.haskell.org
Mon Jul 20 15:06:17 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/4cd008b6c1751c5533ab7eac32d17c9749e4758e/ghc
>---------------------------------------------------------------
commit 4cd008b6c1751c5533ab7eac32d17c9749e4758e
Author: Luite Stegeman <stegeman at gmail.com>
Date: Mon Jul 20 17:01:06 2015 +0200
Do not treat prim and javascript imports as C imports in TH and QQ
Reviewers: austin, hvr, goldfire, bgamari
Reviewed By: bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1070
GHC Trac Issues: #10638
>---------------------------------------------------------------
4cd008b6c1751c5533ab7eac32d17c9749e4758e
compiler/deSugar/DsMeta.hs | 8 +++++---
compiler/hsSyn/Convert.hs | 17 +++++++++++++----
testsuite/tests/th/T10638.hs | 31 +++++++++++++++++++++++++++++++
testsuite/tests/th/T10638.stderr | 6 ++++++
testsuite/tests/th/all.T | 1 +
5 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index d9dc02f..d4a811f 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -489,12 +489,14 @@ repForD (L loc (ForeignImport name typ _ (CImport (L _ cc) (L _ s) mch cis _)))
conv_cimportspec (CFunction (StaticTarget _ _ _ False))
= panic "conv_cimportspec: values not supported yet"
conv_cimportspec CWrapper = return "wrapper"
+ -- these calling conventions do not support headers and the static keyword
+ raw_cconv = cc == PrimCallConv || cc == JavaScriptCallConv
static = case cis of
- CFunction (StaticTarget _ _ _ _) -> "static "
+ CFunction (StaticTarget _ _ _ _) | not raw_cconv -> "static "
_ -> ""
chStr = case mch of
- Nothing -> ""
- Just (Header _ h) -> unpackFS h ++ " "
+ Just (Header _ h) | not raw_cconv -> unpackFS h ++ " "
+ _ -> ""
repForD decl = notHandled "Foreign declaration" (ppr decl)
repCCallConv :: CCallConv -> DsM (Core TH.Callconv)
diff --git a/compiler/hsSyn/Convert.hs b/compiler/hsSyn/Convert.hs
index 7245a1d..4a0e013 100644
--- a/compiler/hsSyn/Convert.hs
+++ b/compiler/hsSyn/Convert.hs
@@ -473,16 +473,25 @@ noExistentials = []
cvtForD :: Foreign -> CvtM (ForeignDecl RdrName)
cvtForD (ImportF callconv safety from nm ty)
+ -- the prim and javascript calling conventions do not support headers
+ -- and are inserted verbatim, analogous to mkImport in RdrHsSyn
+ | callconv == TH.Prim || callconv == TH.JavaScript
+ = mk_imp (CImport (noLoc (cvt_conv callconv)) (noLoc safety') Nothing
+ (CFunction (StaticTarget from (mkFastString from) Nothing
+ True))
+ (noLoc from))
| Just impspec <- parseCImport (noLoc (cvt_conv callconv)) (noLoc safety')
(mkFastString (TH.nameBase nm))
from (noLoc from)
- = do { nm' <- vNameL nm
- ; ty' <- cvtType ty
- ; return (ForeignImport nm' ty' noForeignImportCoercionYet impspec)
- }
+ = mk_imp impspec
| otherwise
= failWith $ text (show from) <+> ptext (sLit "is not a valid ccall impent")
where
+ mk_imp impspec
+ = do { nm' <- vNameL nm
+ ; ty' <- cvtType ty
+ ; return (ForeignImport nm' ty' noForeignImportCoercionYet impspec)
+ }
safety' = case safety of
Unsafe -> PlayRisky
Safe -> PlaySafe
diff --git a/testsuite/tests/th/T10638.hs b/testsuite/tests/th/T10638.hs
new file mode 100644
index 0000000..7dd17eb
--- /dev/null
+++ b/testsuite/tests/th/T10638.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE GHCForeignImportPrim, UnliftedFFITypes, QuasiQuotes, MagicHash #-}
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax
+
+import GHC.Exts
+
+{-
+ the prim and javascript calling conventions do not support
+ headers and the static keyword.
+-}
+
+-- check that quasiquoting roundtrips succesfully and that the declaration
+-- does not include the static keyword
+test1 :: String
+test1 = $(do (ds@[ForeignD (ImportF _ _ p _ _)]) <-
+ [d| foreign import prim "test1" cmm_test1 :: Int# -> Int# |]
+ addTopDecls ds
+ case p of
+ "test1" -> return (LitE . stringL $ p)
+ _ -> error $ "unexpected value: " ++ show p
+ )
+
+-- check that constructed prim imports with the static keyword are rejected
+test2 :: String
+test2 = $(do t <- [t| Int# -> Int# |]
+ cmm_test2 <- newName "cmm_test2"
+ addTopDecls
+ [ForeignD (ImportF Prim Safe "static test2" cmm_test2 t)]
+ [| test1 |]
+ )
diff --git a/testsuite/tests/th/T10638.stderr b/testsuite/tests/th/T10638.stderr
new file mode 100644
index 0000000..3a626ce
--- /dev/null
+++ b/testsuite/tests/th/T10638.stderr
@@ -0,0 +1,6 @@
+
+T10638.hs:26:11:
+ ‘static test2’ is not a valid C identifier
+ When checking declaration:
+ foreign import prim safe "static static test2" cmm_test2
+ :: Int# -> Int#
diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T
index 55627f0..9e8f92d 100644
--- a/testsuite/tests/th/all.T
+++ b/testsuite/tests/th/all.T
@@ -346,3 +346,4 @@ test('T10279', normal, compile_fail, ['-v0'])
test('T10306', normal, compile, ['-v0'])
test('T10596', normal, compile, ['-v0'])
test('T10620', normal, compile_and_run, ['-v0'])
+test('T10638', normal, compile_fail, ['-v0'])
More information about the ghc-commits
mailing list