Skip to content

Qualify diagnostic functions as pragma(printf)#11638

Merged
dlang-bot merged 1 commit intodlang:masterfrom
nordlow:use-pragma-printf
Sep 1, 2020
Merged

Qualify diagnostic functions as pragma(printf)#11638
dlang-bot merged 1 commit intodlang:masterfrom
nordlow:use-pragma-printf

Conversation

@nordlow
Copy link
Contributor

@nordlow nordlow commented Aug 28, 2020

Will improve type-checking of parameters used in C-printf-style diagnostics formatting.

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @nordlow! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#11638"

@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Aug 28, 2020

This requires building with -ignore for older host compilers ( < 2.091.1 (?) 2.092.0).

@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Aug 28, 2020

Maybe do something like this:

diff --git a/src/build.d b/src/build.d
index 184b29313..76c6ec9f5 100755
--- a/src/build.d
+++ b/src/build.d
@@ -1007,6 +1007,11 @@ void processEnvironment()
     else
         env["HOST_DMD_KIND"] = "gdc";

+    // Determine version:
+    const verStart = hostDMDVersion.countUntil('v') + 1;
+    const versionNum = hostDMDVersion[verStart .. verStart + "X.XXX.X".length];
+    env["HOST_DMD_VERSION"] = versionNum;
+
     env["DMD_PATH"] = env["G"].buildPath("dmd").exeName;
     env.getDefault("DETAB", "detab");
     env.getDefault("TOLF", "tolf");
@@ -1023,6 +1028,10 @@ void processEnvironment()
     if (env["HOST_DMD_KIND"] != "gdc")
         dflags ~= ["-dip25"]; // gdmd doesn't support -dip25

+    // Ignore
+    if (versionNum < "2.092.0")
+        dflags ~= "-ignore";
+
     // TODO: add support for dObjc
     auto dObjc = false;
     version(OSX) version(X86_64)

EDIT: For dmd as host compiler, others don't work as well. See #11639 for an alternative solution.

@nordlow
Copy link
Contributor Author

nordlow commented Aug 29, 2020

This requires building with -ignore for older host compilers ( < 2.091.1 (?) 2.092.0).

Thanks. I'll try your patch.

@nordlow nordlow force-pushed the use-pragma-printf branch 2 times, most recently from 3480fe4 to 028681c Compare August 29, 2020 06:11
@nordlow
Copy link
Contributor Author

nordlow commented Aug 29, 2020

Does the error

src/dmd/errors.d(45): Error: pragma `printf` is missing a terminating `;`

mean that -ignore didn't have any effect in this case?

@MoonlightSentinel
Copy link
Contributor

Found that -ignore did not work for unknown pragmas with bodys until 2.089.1 (fixed by this PR).

Guess we would have to implement another workaround for older host compilers or wait until they become recent enough...

@nordlow
Copy link
Contributor Author

nordlow commented Aug 30, 2020

Doing version-branch each definition of course for now until minimum compiler version is bumped.

There's much error checking to gain here so lets see what people think about this brute-force version-branching.

Is this the dmd version where pragma(printf) was introduced?:
https://dlang.org/changelog/2.092.0.html

Update: We could create wrapper functions that have different versions depending on __VERSION__...

@nordlow nordlow force-pushed the use-pragma-printf branch 5 times, most recently from 8097edc to 3390539 Compare August 31, 2020 11:27
@MoonlightSentinel
Copy link
Contributor

Is this the dmd version where pragma(printf) was introduced?:
https://dlang.org/changelog/2.092.0.html

Think so.

Update: We could create wrapper functions that have different versions depending on __VERSION__...

Seems reasonable.

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

@MoonlightSentinel
Copy link
Contributor

Running locally using Ubuntu-WSL (built with -checkaction=context):

core.exception.AssertError@src/dmd/lexer.d(2730): "escape hex sequence has 1 hex digits instead of 2" != "escape hex sequence has 1 hex digits instead of -703763272"       
----------------
??:? _d_assert_msg [0x7fa00f693bf2]
src/dmd/lexer.d:2730 nothrow @nogc bool dmd.lexer.__unittest_L2716_C1().expectDiagnosticHandler(ref const(dmd.globals.Loc), dmd.console.Color, const(char)*, const(char)*, core.internal.vararg.sysv_x64.__va_list_tag*, const(char)*, const(char)*) [0x7fa00f5b1d2f]
src/dmd/errors.d:338 nothrow void dmd.errors.verrorPrint(ref const(dmd.globals.Loc), dmd.console.Color, const(char)*, const(char)*, core.internal.vararg.sysv_x64.__va_list_tag*, const(char)*, const(char)*) [0x7fa00f5a1161]
src/dmd/errors.d:421 _Z6verrorRK3LocPKcP13__va_list_tagS3_S3_S3_ [0x7fa00f5a15c6]
src/dmd/errors.d:59 _Z6_errorRK3LocPKcz [0x7fa00f5a0309]
src/dmd/errors.d:53 _Z5errorRK3LocPKcz [0x7fa00f5a023e]
src/dmd/lexer.d:1230 nothrow dchar dmd.lexer.Lexer.escapeSequence(ref const(dmd.globals.Loc), ref const(char)*) [0x7fa00f5ae7a8]
src/dmd/lexer.d:2742 nothrow void dmd.lexer.__unittest_L2716_C1().test(immutable(char)[], immutable(char)[], dchar, uint) [0x7fa00f5b1da6]
src/dmd/lexer.d:2754 nothrow void dmd.lexer.__unittest_L2716_C1() [0x7fa00f5b17d6]

Win64 passes the test, so it looks like a parameter corruption.

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

So I have to duplicate the creation of the va_list aps, then.

@nordlow nordlow force-pushed the use-pragma-printf branch from 3390539 to ea93b5c Compare August 31, 2020 15:23
@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

Ready to go, @MoonlightSentinel?

@MoonlightSentinel
Copy link
Contributor

LGTM except that this overload is missing:

dmd/src/dmd/errors.d

Lines 62 to 75 in ea93b5c

/**
* Same as above, but allows Loc() literals to be passed.
* Params:
* loc = location of error
* format = printf-style format specification
* ... = printf-style variadic arguments
*/
extern (D) void error(Loc loc, const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
va_end(ap);
}

This overload cannot be marked with pragma(printf) as it's extern(D)so you would have to mark it as extern(C++). But I think you can simply remove it because it's only used once:

error(Loc(filename.xarraydup.ptr, lineNum, 0), "Use `NAME=value` syntax, not `%s`", pn);

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

LGTM except that this overload is missing:

The call in dinifile.d requires an r-value Loc. Shall I convert the call to use an l-value or add r-value overloads for

extern (C++) void error(const Loc loc, const(char)* format, ...)

or, perhaps, even better, remove the extern(D)-overload and convert all arguments taking Loc to be passed as in value? Loc is 16 bytes wide and will be passed in registers, AFAICT. If we later add more members to Loc the new rules for in in future versions of the host dmd compiler will handle this correctly.

@MoonlightSentinel
Copy link
Contributor

Rewrite it to store a local Loc for now, we can look into optimizations later.

-error(Loc(filename.xarraydup.ptr, lineNum, 0), "Use `NAME=value` syntax, not `%s`", pn); 
+Loc(filename.xarraydup.ptr, lineNum, 0)
+error(loc, "Use `NAME=value` syntax, not `%s`", pn); 

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

Rewrite it to store a local Loc for now, we can look into optimizations later.

Using in Loc loc builds ok.

You mean do the transition from const ref to in at larger scale?

@MoonlightSentinel
Copy link
Contributor

Yes, let's stick with the current default (const ref) and discuss optimizations in a dedicated PR.

@nordlow nordlow force-pushed the use-pragma-printf branch from ea93b5c to 8378abd Compare August 31, 2020 18:36
@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

Yes, let's stick with the current default (const ref) and discuss optimizations in a dedicated PR.

Done.

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

Why does druntime fail to build in buildkite/dmd? I can't see any error message.

Only a warning:

Warning: struct HasNonConstToHash has method toHash, however it cannot be called with const(HasNonConstToHash) this.

@MoonlightSentinel
Copy link
Contributor

Seems like a spurious OOM, restarted the job manually.

Testing printf
--
  | ./generated/linux/debug/64/printf
  | /var/lib/buildkite-agent/builds/ci-agent-a5eb829d-1249-4ef6-a546-0eb660ed8d77-5/dlang/dmd/dmd/generated/linux/release/64/dmd -debug=LOGGING -m64 -fPIC -w -I../../src -I../../import -Isrc -defaultlib= -debuglib= -dip1000 -L-lpthread -L-lm -L/var/lib/buildkite-agent/builds/ci-agent-a5eb829d-1249-4ef6-a546-0eb660ed8d77-5/dlang/dmd/druntime/generated/linux/release/64/libdruntime.a -O -release -unittest -version=CoreUnittest -main -ofgenerated/linux/release/64/logging ../../src/gc/impl/conservative/gc.d ../../src/rt/lifetime.d
  | src/core/exception.d(647): [unittest] Memory allocation failed
  | core.exception.OutOfMemoryError@src/core/exception.d(647): Memory allocation failed
  | ----------------
  | 1/1 modules FAILED unittests
  | Makefile:15: recipe for target 'generated/linux/debug/64/printf.done' failed
  | make[2]: *** [generated/linux/debug/64/printf.done] Error 1


@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

Seems like a spurious OOM, restarted the job manually.

Is dmd taking too much memory?

@MoonlightSentinel
Copy link
Contributor

Is dmd taking too much memory?

The OOM occurred in the printf executable (but I guess Buildkite just got too many jobs at once there)

@nordlow
Copy link
Contributor Author

nordlow commented Aug 31, 2020

The OOM occurred in the printf executable (but I guess Buildkite just got too many jobs at once there)

Is there no guarantee for the minimum amount of memory available?

@wilzbach
Copy link
Contributor

The OOM occurred in the printf executable (but I guess Buildkite just got too many jobs at once there)

Is there no guarantee for the minimum amount of memory available?

Nope, we run the agents ourselves and to save resources we run multiple agents on one machine (and they share the memory). It usually works out well though ;-)

@nordlow
Copy link
Contributor Author

nordlow commented Sep 1, 2020

What's up with this failure?

@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Sep 1, 2020

What's up with this failure?

No idea but it looks environmental (std.parallelism wasn't changed in the last few days AFAICT)

@nordlow
Copy link
Contributor Author

nordlow commented Sep 1, 2020

No idea but it looks environmental (std.parallelism wasn't changed in the last few days AFAICT)

Ok, thanks. Shall I do a forced push again?

@MoonlightSentinel
Copy link
Contributor

No, I've restarted it manually

@nordlow
Copy link
Contributor Author

nordlow commented Sep 1, 2020

No, I've restarted it manually

Thanks.

@nordlow
Copy link
Contributor Author

nordlow commented Sep 1, 2020

No, I've restarted it manually

Can you restart parts of the autotester or only the whole?

I presume I don't have the permissions to restart individual jobs manually, right?

@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Sep 1, 2020

Can you restart parts of the autotester or only the whole?

Individual jobs (causing less workload than force-pushing)

I presume I don't have the permissions to restart individual jobs manually, right?

No, the auto-tester requires a linked account with mege rights IIRC. (But that situation should improve once we retire the auto-tester inf favour of other CI's, see e.g. #11653).

See below

@wilzbach
Copy link
Contributor

wilzbach commented Sep 1, 2020

No, the auto-tester requires a linked account with mege rights IIRC. (But that situation should improve once we retire the auto-tester inf favour of other CI's, see e.g. #11653).

Actually, anyone whose PRs can get tested on the auto-tester can also login there and deprecate the builds. Not that it would be important as the builds are constantly restarted. Once "auto-merge" is applied the PR branch will get higher priority and restart the build until it is green.

@dlang-bot dlang-bot merged commit b25fcdf into dlang:master Sep 1, 2020
@nordlow nordlow deleted the use-pragma-printf branch September 1, 2020 20:51
{
_vdeprecationSupplemental(loc, format, ap);
}
extern (C++) void _vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have been private and extern(D)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants