| Opt_WarnDodgyImports
| Opt_WarnOrphans
| Opt_WarnTabs
+ | Opt_WarnDodgyForeignImports
-- language opts
| Opt_OverlappingInstances
Opt_WarnOverlappingPatterns,
Opt_WarnMissingFields,
Opt_WarnMissingMethods,
- Opt_WarnDuplicateExports
+ Opt_WarnDuplicateExports,
+ Opt_WarnDodgyForeignImports
]
minusWOpts :: [DynFlag]
fFlags :: [(String, DynFlag, Bool -> Deprecated)]
fFlags = [
+ ( "warn-dodgy-foreign-imports", Opt_WarnDodgyForeignImports, const Supported ),
( "warn-dodgy-imports", Opt_WarnDodgyImports, const Supported ),
( "warn-duplicate-exports", Opt_WarnDuplicateExports, const Supported ),
( "warn-hi-shadowing", Opt_WarnHiShadows, const Supported ),
dflags <- getDOpts
checkForeignArgs (isFFIArgumentTy dflags safety) arg_tys
checkForeignRes nonIOok (isFFIImportResultTy dflags) res_ty
+ checkMissingAmpersand dflags arg_tys res_ty
return idecl
-- This makes a convenient place to check
checkCg checkCOrAsmOrDotNetOrInterp
check (isCLabelString str) (badCName str)
checkCTarget DynamicTarget = panic "checkCTarget DynamicTarget"
+
+checkMissingAmpersand :: DynFlags -> [Type] -> Type -> TcM ()
+checkMissingAmpersand dflags arg_tys res_ty
+ | null arg_tys && isFunPtrTy res_ty &&
+ dopt Opt_WarnDodgyForeignImports dflags
+ = addWarn (ptext (sLit "possible missing & in foreign import of FunPtr"))
+ | otherwise
+ = return ()
\end{code}
On an Alpha, with foreign export dynamic, due to a giant hack when
isFFIDotnetTy, -- :: DynFlags -> Type -> Bool
isFFIDotnetObjTy, -- :: Type -> Bool
isFFITy, -- :: Type -> Bool
+ isFunPtrTy, -- :: Type -> Bool
tcSplitIOType_maybe, -- :: Type -> Maybe Type
toDNType, -- :: Type -> DNType
(_, t_ty) = tcSplitForAllTys ty
check_tc tc = getName tc == objectTyConName
+isFunPtrTy :: Type -> Bool
+isFunPtrTy = checkRepTyConKey [funPtrTyConKey]
+
toDNType :: Type -> DNType
toDNType ty
| isStringTy ty = DNString
<option>-fwarn-deprecations</option>,
<option>-fwarn-deprecated-flags</option>,
<option>-fwarn-duplicate-exports</option>,
- <option>-fwarn-missing-fields</option>, and
- <option>-fwarn-missing-methods</option>. The following flags are
+ <option>-fwarn-missing-fields</option>,
+ <option>-fwarn-missing-methods</option>, and
+ <option>-fwarn-dodgy-foreign-imports</option>. The following
+ flags are
simple ways to select standard “packages” of warnings:
</para>
</varlistentry>
<varlistentry>
+ <term><option>-fwarn-dodgy-foreign-imports</option>:</term>
+ <listitem>
+ <indexterm><primary><option>-fwarn-dodgy-foreign-imports</option></primary>
+ </indexterm>
+ <para>Causes a warning to be emitted for foreign imports of
+ the following form:</para>
+<programlisting>
+foreign import "f" f :: FunPtr t
+</programlisting>
+ <para>on the grounds that it probably should be</para>
+<programlisting>
+foreign import "&f" f :: FunPtr t
+</programlisting>
+ <para>The first form declares that `f` is a (pure) C
+ function that takes no arguments and returns a pointer to a
+ C function with type `t`, whereas the second form declares
+ that `f` itself is a C function with type `t`. The first
+ declaration is usually a mistake, and one that is hard to
+ debug because it results in a crash, hence this
+ warning.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-fwarn-dodgy-imports</option>:</term>
<listitem>
<indexterm><primary><option>-fwarn-dodgy-imports</option></primary>