Skip to content

Commit f18ac3e

Browse files
authored
Allow calling trusted pragma(printf) function from system code (dlang#22785)
1 parent 23fa06c commit f18ac3e

2 files changed

Lines changed: 19 additions & 12 deletions

File tree

compiler/src/dmd/expressionsem.d

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,17 +3423,17 @@ private bool checkSafety(FuncDeclaration f, ref Loc loc, Scope* sc, Expressions*
34233423
{
34243424
if (!isFormatSafe(se.peekString()))
34253425
{
3426-
error(loc, "calling `pragma(printf)` %s `%s` with format string `%s` is not `@safe`",
3427-
f.kind(), f.toPrettyChars(), se.toChars());
3428-
.errorSupplemental(f.loc, "`%s` is declared here", f.toPrettyChars());
3426+
if (sc.setUnsafe(false, loc,
3427+
"calling `pragma(printf)` function `%s` with format string `%s`", f, se))
3428+
.errorSupplemental(f.loc, "`%s` is declared here", f.toPrettyChars());
34293429
return true;
34303430
}
34313431
}
34323432
else
34333433
{
3434-
error(loc, "calling `pragma(printf)` %s `%s` with non-literal format string is not `@safe`",
3435-
f.kind(), f.toPrettyChars());
3436-
.errorSupplemental(f.loc, "`%s` is declared here", f.toPrettyChars());
3434+
if (sc.setUnsafe(false, loc,
3435+
"calling `pragma(printf)` function `%s` with non-literal format string", f))
3436+
.errorSupplemental(f.loc, "`%s` is declared here", f.toPrettyChars());
34373437
return true;
34383438
}
34393439
}

compiler/test/fail_compilation/safeprintf.d

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
DISABLED: win32 win64 freebsd32 openbsd32 linux32 osx32
33
TEST_OUTPUT:
44
---
5-
fail_compilation/safeprintf.d(29): Error: calling `pragma(printf)` function `safeprintf.printf` with format string `"s: %s\n"` is not `@safe`
5+
fail_compilation/safeprintf.d(29): Error: calling `pragma(printf)` function `printf` with format string `"s: %s\n"` is not allowed in a `@safe` function
66
fail_compilation/safeprintf.d(21): `safeprintf.printf` is declared here
7-
fail_compilation/safeprintf.d(30): Error: calling `pragma(printf)` function `safeprintf.printf` with format string `"s: %S\n"` is not `@safe`
7+
fail_compilation/safeprintf.d(30): Error: calling `pragma(printf)` function `printf` with format string `"s: %S\n"` is not allowed in a `@safe` function
88
fail_compilation/safeprintf.d(21): `safeprintf.printf` is declared here
9-
fail_compilation/safeprintf.d(31): Error: calling `pragma(printf)` function `safeprintf.printf` with format string `"s: %Z\n"` is not `@safe`
9+
fail_compilation/safeprintf.d(31): Error: calling `pragma(printf)` function `printf` with format string `"s: %Z\n"` is not allowed in a `@safe` function
1010
fail_compilation/safeprintf.d(21): `safeprintf.printf` is declared here
1111
fail_compilation/safeprintf.d(31): Deprecation: format specifier `"%Z"` is invalid
12-
fail_compilation/safeprintf.d(32): Error: calling `pragma(printf)` function `safeprintf.printf` with non-literal format string is not `@safe`
12+
fail_compilation/safeprintf.d(32): Error: calling `pragma(printf)` function `printf` with non-literal format string is not allowed in a `@safe` function
1313
fail_compilation/safeprintf.d(21): `safeprintf.printf` is declared here
14-
fail_compilation/safeprintf.d(33): Error: calling `pragma(printf)` function `safeprintf.bar` with format string `"%s"` is not `@safe`
14+
fail_compilation/safeprintf.d(33): Error: calling `pragma(printf)` function `bar` with format string `"%s"` is not allowed in a `@safe` function
1515
fail_compilation/safeprintf.d(22): `safeprintf.bar` is declared here
1616
fail_compilation/safeprintf.d(34): Error: `@safe` function `safeprintf.func` cannot call `@system` function `safeprintf.sys_printf`
1717
fail_compilation/safeprintf.d(23): `safeprintf.sys_printf` is declared here
@@ -31,5 +31,12 @@ extern (C) @system pragma(printf) int sys_printf(const(char)* format, ...);
3131
printf("s: %Z\n", s);
3232
printf(s, i); // non-literal
3333
bar(1, "%s", s); // preceding args
34-
sys_printf("d", i);
34+
sys_printf("%d", i); // not safe
35+
}
36+
37+
// no errors
38+
@system void sys(char* s)
39+
{
40+
printf(s); // non-literal
41+
printf("%s", s);
3542
}

0 commit comments

Comments
 (0)