Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add -check command line switch #8972

Merged
merged 1 commit into from
Dec 10, 2018
Merged

Conversation

WalterBright
Copy link
Member

@WalterBright WalterBright commented Nov 19, 2018

An implementation of the idea behind DIP1006, but not the specifics.

https://github.com/dlang/DIPs/blob/master/DIPs/DIP1006.md

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @WalterBright!

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 fetch digger
dub run digger -- build "master + dmd#8972"

@Geod24
Copy link
Member

Geod24 commented Nov 19, 2018

@thewilsonator
Copy link
Contributor

doc tester doesn't like something there.

@WalterBright WalterBright force-pushed the check-switch branch 2 times, most recently from 6290263 to 58a2df5 Compare November 19, 2018 11:20
@leandro-lucarella-sociomantic
Copy link
Contributor

It definitely cover our needs, thanks! The DIP should probably be updated too, although it is mostly only an update on names (switch and values) and add/remove some options.

@joseph-wakeling-sociomantic

A question about behaviour: if one excludes assert does this mean that in, out and invariant checks are also effectively disabled, even if they are still requested with -check=in -check=out -check=invariant ... ?

src/dmd/cli.d Outdated
@@ -169,14 +169,30 @@ struct Usage
Option("c",
"compile only, do not link"
),
Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
"Enable or disable specific checks",
`Overrides default, -boundscheck, and -release options to enable or disable specific checks.
Copy link
Member

Choose a reason for hiding this comment

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

It currently overrides -boundscheck only if it is specified after it on the command line. I'd rather leave bounds out here, it already has two options and another setting safeonly.

Copy link
Member Author

Choose a reason for hiding this comment

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

We actually have boundscheck and noboundscheck. I'd like to deprecate them and just go with the more general check. I also want to add safe as a third option to check, so that all the checks are handled the same way with one switch.

Copy link
Member

Choose a reason for hiding this comment

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

The current implementation is not in line with this documentation: To match it -boundscheck has to remember its setting and change params.useArrayBounds only if not set already by -check=bounds=on|off.

Choose a reason for hiding this comment

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

We actually have boundscheck and noboundscheck. I'd like to deprecate them and just go with the more general check. I also want to add safe as a third option to check, so that all the checks are handled the same way with one switch.

If you want to go this route, I might suggest considering adding back the all and none values present in the DIP.

Choose a reason for hiding this comment

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

On the other hand, what you said afterwards contradicts this idea:

The idea is that changing one setting with -check has no effect on any other settings. It's designed so that each setting can be controlled independently of the others. Therefore, if you set check=in, then the in contracts are run, but if assert is turned off, then they'll be vacuous.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can see someone running the in contracts with the assert turned off, after all, they may want to do their own wacky thing. I fear that if we get too clever with "surely the user wants assert on if in is on" we'll find ourselves in the future inevitably adding another switch so that becomes settable.

I don't want to be adding more switches. We've already tried several times to "package" these settings into other switches. The desire for this switch shows it obviously is inadequate.

Copy link
Member Author

Choose a reason for hiding this comment

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

It currently overrides -boundscheck only if it is specified after it on the command line.

Fixed.

@@ -169,14 +169,30 @@ struct Usage
Option("c",
"compile only, do not link"
),
Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
Copy link
Member

Choose a reason for hiding this comment

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

Don't want to start bikeshedding, but the duplicate = looks strange. Why not use check-[assert|...]?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because 1) we use on|off elsewhere, not +|- 2) I want to add a safe option as well 3) other options may become useful than just on|off|safe

Copy link
Member

Choose a reason for hiding this comment

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

I didn't mean to remove the on/off, but to replace the first = with -, e.g. -check-assert=on instead of -check=assert=on.

Copy link
Member Author

Choose a reason for hiding this comment

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

We already use = for the mv switch.

Choose a reason for hiding this comment

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

Another syntax question: is it assumed that the user will write separate -check=assert -check=in -check=out -check=bounds calls, or do we want to support a syntax like -check=assert,bounds,in,out that allows all the options to be specified in a single flag?

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps in the future. For right now, I want to maximize simplicity.

@WalterBright
Copy link
Member Author

if one excludes assert does this mean that in, out and invariant checks are also effectively disabled, even if they are still requested with -check=in -check=out -check=invariant ... ?

The idea is that changing one setting with -check has no effect on any other settings. It's designed so that each setting can be controlled independently of the others. Therefore, if you set check=in, then the in contracts are run, but if assert is turned off, then they'll be vacuous.

@wilzbach
Copy link
Member

Why not use the existing work from #7980?

*/

// Check for legal option string; return true if so
static bool check(const(char)* p, string name, ref CHECKENABLE ce)
Copy link
Member

Choose a reason for hiding this comment

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

This seems awfully rigid, re checking for exactly =on or =off
For a first implementation it might be alight though.

@leandro-lucarella-sociomantic
Copy link
Contributor

Why not use the existing work from #7980?

I find -release much less clear than -check, I would rather not end up with another enum just because there was a pre-existing -release option :trollface:

@joseph-wakeling-sociomantic

The idea is that changing one setting with -check has no effect on any other settings. It's designed so that each setting can be controlled independently of the others. Therefore, if you set check=in, then the in contracts are run, but if assert is turned off, then they'll be vacuous.

Gotcha. So (for example) if one just set check=assert then in effect only asserts in function bodies would run ... ?

I remember suggesting a body option in the discussion to turn on/off asserts in function bodies alone, but from what I recall that is non-trivial to implement. In any case it seems reasonable to always have in-body assert checks if one is supporting asserts at all.

@WalterBright
Copy link
Member Author

So (for example) if one just set check=assert then in effect only asserts in function bodies would run ... ?

No. All asserts would run.

@joseph-wakeling-sociomantic

No. All asserts would run.

Presumably not asserts in in, out and invariant contracts, since the entire contracts would be excluded?

Other than that, where else would you see assert checks existing other than in function bodies? (OK, and unittests, but I assume that's a special case anyway)

@WalterBright
Copy link
Member Author

Presumably not asserts in in, out and invariant contracts, since the entire contracts would be excluded?

That's right.

Other than that, where else would you see assert checks existing other than in function bodies? (OK, and unittests, but I assume that's a special case anyway)

In executable code, which would be those areas you mentioned.

@@ -175,6 +175,7 @@ struct Param
CHECKENABLE useArrayBounds = CHECKENABLE._default; // when to generate code for array bounds checks
CHECKENABLE useAssert = CHECKENABLE._default; // when to generate code for assert()'s
CHECKENABLE useSwitchError = CHECKENABLE._default; // check for switches without a default
CHECKENABLE boundscheck = CHECKENABLE._default; // state of -boundscheck switch
Copy link
Member

Choose a reason for hiding this comment

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

While this now works as documented, I think it's a bit confusing to have both useArrayBounds and boundscheck as fields of Param. I would expect boundscheck to be a local variable in parseCommandLine().

@wilzbach
Copy link
Member

Why not use the existing work from #7980?
I find -release much less clear than -check, I would rather not end up with another enum just because there was a pre-existing -release option :trollface:

I was referring to the tests in #7980 as this PR currently has no tests.

@WalterBright
Copy link
Member Author

It's not very testable because of the use of global variables, particularly around line 339 of mars.d. I've had thoughts once this is pulled to pull out that section into a separate function, and pass global.params in as a parameter. Then it would be testable with unit tests.

Copy link
Member

@andralex andralex left a comment

Choose a reason for hiding this comment

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

I understand this has also been OK by Sociomantic.

@andralex andralex merged commit 987012b into dlang:master Dec 10, 2018
@WalterBright WalterBright deleted the check-switch branch December 10, 2018 04:19
@wilzbach
Copy link
Member

Why are there still no tests? This shouldn't have been merged without tests!!
Especially because a former submission of this which was ignored for a year had plenty of tests :/

@WalterBright
Copy link
Member Author

WalterBright commented Dec 10, 2018

@wilzbach please add them!

@wilzbach
Copy link
Member

wilzbach commented Jan 4, 2019

Why are there still no tests? This shouldn't have been merged without tests!!
Especially because a former submission of this which was ignored for a year had plenty of tests :/

Guess what: I was correct. the feature didn't work: #9195

please add them!

I'm sorry, but my main focus isn't D anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants