From 4e3e27d8f6f8e16c90863322f6ed6109e77df574 Mon Sep 17 00:00:00 2001 From: Paul Backus Date: Fri, 22 May 2020 11:55:33 -0400 Subject: [PATCH] Add deprecation message for extern functions with default safety This message is needed to avoid silently introducing safety violations to existing code when the default is changed from @system to @safe. It should become an error when @safe is made the default. --- src/dmd/dsymbolsem.d | 12 ++++++++++++ test/compilable/compile1.d | 2 +- test/compilable/test16031.d | 2 +- test/fail_compilation/dep_extern_safety.d | 9 +++++++++ test/fail_compilation/fail20771.d | 2 +- test/fail_compilation/fail20772.d | 2 +- test/fail_compilation/fail20775.d | 2 +- 7 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 test/fail_compilation/dep_extern_safety.d diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index 67fb1d79bbdd..9016b25eff6c 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -4049,6 +4049,18 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (funcdecl.canInferAttributes(sc)) funcdecl.initInferAttributes(); + /* Warn about external function declarations that may become incorrect + * when @safe is made the default. + */ + if (!funcdecl.fbody + && funcdecl.storage_class == STC.extern_ + && funcdecl.type.toTypeFunction().trust == TRUST.default_) + { + deprecation(funcdecl.loc, + "`extern` function `%s` should be marked explicitly as `@safe`, `@system`, or `@trusted`", + funcdecl.toPrettyChars); + } + Module.dprogress++; funcdecl.semanticRun = PASS.semanticdone; diff --git a/test/compilable/compile1.d b/test/compilable/compile1.d index 1b6d1f4eb036..9c41274738c5 100644 --- a/test/compilable/compile1.d +++ b/test/compilable/compile1.d @@ -476,7 +476,7 @@ template test8163(T...) } enum N = 2; // N>=2 triggers the bug - extern Point[N] bar(); + @system extern Point[N] bar(); void foo() { diff --git a/test/compilable/test16031.d b/test/compilable/test16031.d index 7239522e1072..3cc18561112d 100644 --- a/test/compilable/test16031.d +++ b/test/compilable/test16031.d @@ -1,7 +1,7 @@ // REQUIRED_ARGS: -fPIC -lib // PERMUTE_ARGS: // DISABLED: win32 win64 -extern void throwing(); +@system extern void throwing(); void foo() { diff --git a/test/fail_compilation/dep_extern_safety.d b/test/fail_compilation/dep_extern_safety.d new file mode 100644 index 000000000000..83830d2b5856 --- /dev/null +++ b/test/fail_compilation/dep_extern_safety.d @@ -0,0 +1,9 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/dep_extern_safety.d(9): Deprecation: `extern` function `dep_extern_safety.fun` should be marked explicitly as `@safe`, `@system`, or `@trusted` +--- +*/ + +extern extern(C) void fun(); diff --git a/test/fail_compilation/fail20771.d b/test/fail_compilation/fail20771.d index 18e1c87980da..28d94c2cc0fd 100644 --- a/test/fail_compilation/fail20771.d +++ b/test/fail_compilation/fail20771.d @@ -5,7 +5,7 @@ fail_compilation/fail20771.d(19): Error: cannot pass types with postblits or cop fail_compilation/fail20771.d(20): Error: cannot pass types with postblits or copy constructors as variadic arguments --- */ -extern void variadic(...); +@system extern void variadic(...); struct S20771 { diff --git a/test/fail_compilation/fail20772.d b/test/fail_compilation/fail20772.d index a2fdac687987..632561810876 100644 --- a/test/fail_compilation/fail20772.d +++ b/test/fail_compilation/fail20772.d @@ -5,7 +5,7 @@ fail_compilation/fail20772.d(20): Error: cannot pass types with postblits or cop fail_compilation/fail20772.d(21): Error: cannot pass types with postblits or copy constructors as variadic arguments --- */ -extern void variadic(...); +@system extern void variadic(...); struct S20772 { diff --git a/test/fail_compilation/fail20775.d b/test/fail_compilation/fail20775.d index 3e050960a186..f3ab7467ecd7 100644 --- a/test/fail_compilation/fail20775.d +++ b/test/fail_compilation/fail20775.d @@ -5,7 +5,7 @@ fail_compilation/fail20775.d(19): Error: cannot pass types that need destruction fail_compilation/fail20775.d(20): Error: cannot pass types that need destruction as variadic arguments --- */ -extern void variadic(...); +@system extern void variadic(...); struct S20775 {