Skip to content

Qualify diagnostic functions as pragma(printf)#11638

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

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

Conversation

@nordlow

@nordlow nordlow commented Aug 28, 2020

Copy link
Copy Markdown
Contributor

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

@dlang-bot

Copy link
Copy Markdown
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

MoonlightSentinel commented Aug 28, 2020

Copy link
Copy Markdown
Contributor

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

@MoonlightSentinel

MoonlightSentinel commented Aug 28, 2020

Copy link
Copy Markdown
Contributor

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

nordlow commented Aug 29, 2020

Copy link
Copy Markdown
Contributor Author

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

nordlow commented Aug 29, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Aug 30, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

@MoonlightSentinel

Copy link
Copy Markdown
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.

Comment thread src/dmd/errors.d Outdated
Comment thread src/dmd/errors.d Outdated
@nordlow

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

Ready to go, @MoonlightSentinel?

@MoonlightSentinel

Copy link
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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

Done.

@nordlow

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

Seems like a spurious OOM, restarted the job manually.

Is dmd taking too much memory?

@MoonlightSentinel

Copy link
Copy Markdown
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

nordlow commented Aug 31, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

nordlow commented Sep 1, 2020

Copy link
Copy Markdown
Contributor Author

What's up with this failure?

@MoonlightSentinel

MoonlightSentinel commented Sep 1, 2020

Copy link
Copy Markdown
Contributor

What's up with this failure?

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

@nordlow

nordlow commented Sep 1, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
Contributor

No, I've restarted it manually

@nordlow

nordlow commented Sep 1, 2020

Copy link
Copy Markdown
Contributor Author

No, I've restarted it manually

Thanks.

@nordlow

nordlow commented Sep 1, 2020

Copy link
Copy Markdown
Contributor Author

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

MoonlightSentinel commented Sep 1, 2020

Copy link
Copy Markdown
Contributor

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

wilzbach commented Sep 1, 2020

Copy link
Copy Markdown
Contributor

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
Comment thread src/dmd/errors.d
{
_vdeprecationSupplemental(loc, format, ap);
}
extern (C++) void _vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap)

Copy link
Copy Markdown
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