[commit: ghc] master: Check for empty entity string in "prim" foreign imports (6c73932)
git at git.haskell.org
git at git.haskell.org
Fri Oct 14 17:27:46 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/6c7393261e723af3651f47bcee9af8db6bb6cf17/ghc
>---------------------------------------------------------------
commit 6c7393261e723af3651f47bcee9af8db6bb6cf17
Author: Sylvain HENRY <hsyl20 at gmail.com>
Date: Fri Oct 14 10:43:30 2016 -0400
Check for empty entity string in "prim" foreign imports
Foreign imports with "prim" convention require a valid symbol identifier
(see linked issue). We check this.
Fix line too long
Test Plan: Validate
Reviewers: austin, bgamari
Reviewed By: bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2563
GHC Trac Issues: #12355
>---------------------------------------------------------------
6c7393261e723af3651f47bcee9af8db6bb6cf17
compiler/parser/RdrHsSyn.hs | 58 +++++++++++++++++----------
testsuite/tests/codeGen/should_compile/all.T | 2 +-
testsuite/tests/ffi/should_fail/T10461.stderr | 2 +-
3 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 4fc1c9c..3c1792b 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -1301,28 +1301,42 @@ mkImport :: Located CCallConv
-> Located Safety
-> (Located StringLiteral, Located RdrName, LHsSigType RdrName)
-> P (HsDecl RdrName)
-mkImport (L lc cconv) (L ls safety) (L loc (StringLiteral esrc entity), v, ty)
- | cconv == PrimCallConv = do
- let funcTarget = CFunction (StaticTarget esrc entity Nothing True)
- importSpec = CImport (L lc PrimCallConv) (L ls safety) Nothing funcTarget
- (L loc esrc)
- return (ForD (ForeignImport { fd_name = v, fd_sig_ty = ty
- , fd_co = noForeignImportCoercionYet
- , fd_fi = importSpec }))
- | cconv == JavaScriptCallConv = do
- let funcTarget = CFunction (StaticTarget esrc entity Nothing True)
- importSpec = CImport (L lc JavaScriptCallConv) (L ls safety) Nothing
- funcTarget (L loc (unpackFS entity))
- return (ForD (ForeignImport { fd_name = v, fd_sig_ty = ty
- , fd_co = noForeignImportCoercionYet
- , fd_fi = importSpec }))
- | otherwise = do
- case parseCImport (L lc cconv) (L ls safety) (mkExtName (unLoc v))
- (unpackFS entity) (L loc (unpackFS entity)) of
- Nothing -> parseErrorSDoc loc (text "Malformed entity string")
- Just importSpec -> return (ForD (ForeignImport { fd_name = v, fd_sig_ty = ty
- , fd_co = noForeignImportCoercionYet
- , fd_fi = importSpec }))
+mkImport cconv safety (L loc (StringLiteral esrc entity), v, ty) =
+ case cconv of
+ L _ CCallConv -> mkCImport
+ L _ CApiConv -> mkCImport
+ L _ StdCallConv -> mkCImport
+ L _ PrimCallConv -> mkOtherImport
+ L _ JavaScriptCallConv -> mkOtherImport
+ where
+ -- Parse a C-like entity string of the following form:
+ -- "[static] [chname] [&] [cid]" | "dynamic" | "wrapper"
+ -- If 'cid' is missing, the function name 'v' is used instead as symbol
+ -- name (cf section 8.5.1 in Haskell 2010 report).
+ mkCImport = do
+ let e = unpackFS entity
+ case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc e) of
+ Nothing -> parseErrorSDoc loc (text "Malformed entity string")
+ Just importSpec -> returnSpec importSpec
+
+ -- currently, all the other import conventions only support a symbol name in
+ -- the entity string. If it is missing, we use the function name instead.
+ mkOtherImport = returnSpec importSpec
+ where
+ entity' = if nullFS entity
+ then mkExtName (unLoc v)
+ else entity
+ funcTarget = CFunction (StaticTarget esrc entity' Nothing True)
+ importSpec = CImport cconv safety Nothing funcTarget (L loc esrc)
+
+ returnSpec spec = return $ ForD $ ForeignImport
+ { fd_name = v
+ , fd_sig_ty = ty
+ , fd_co = noForeignImportCoercionYet
+ , fd_fi = spec
+ }
+
+
-- the string "foo" is ambiguous: either a header or a C identifier. The
-- C identifier case comes first in the alternatives below, so we pick
diff --git a/testsuite/tests/codeGen/should_compile/all.T b/testsuite/tests/codeGen/should_compile/all.T
index dad755e..e3fad18 100644
--- a/testsuite/tests/codeGen/should_compile/all.T
+++ b/testsuite/tests/codeGen/should_compile/all.T
@@ -37,4 +37,4 @@ test('T10667', [ when((arch('powerpc64') or arch('powerpc64le')),
expect_broken(11261))],
compile, ['-g'])
test('T12115', normal, compile, [''])
-test('T12355', when(not opsys('darwin'), expect_broken(12355)), compile, [''])
+test('T12355', normal, compile, [''])
diff --git a/testsuite/tests/ffi/should_fail/T10461.stderr b/testsuite/tests/ffi/should_fail/T10461.stderr
index 7962582..fae0f50 100644
--- a/testsuite/tests/ffi/should_fail/T10461.stderr
+++ b/testsuite/tests/ffi/should_fail/T10461.stderr
@@ -4,4 +4,4 @@ T10461.hs:6:1: error:
‘Word#’ cannot be marshalled in a foreign call
To marshal unlifted types, use UnliftedFFITypes
When checking declaration:
- foreign import prim safe "static " cheneycopy :: Any -> Word#
+ foreign import prim safe "static cheneycopy" cheneycopy :: Any -> Word#
More information about the ghc-commits
mailing list