-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Link time asserts #4139
base: main
Are you sure you want to change the base?
Link time asserts #4139
Conversation
A link error will look like this:
|
src/library/basetracktablemodel.cpp
Outdated
@@ -612,7 +618,10 @@ QVariant BaseTrackTableModel::roleValue( | |||
} | |||
bool ok; | |||
const auto timesPlayed = rawValue.toInt(&ok); | |||
VERIFY_OR_DEBUG_ASSERT(ok && timesPlayed >= 0) { | |||
VERIFY_OR_DEBUG_ASSERT(ok) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to split all such debug assertions now? In this case using &
in the condition was intended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without the split, the link assertion kicks in. I have not yet an explanation why.
I assume that the compiler optimizes it in a way that it creates a two separate branched where one has no longer a good path.
That the original code no longer works is really a caveat of this solution.
I think I need to examine the ASM code to find out what is going on.
Comments addressed. I am not sure how continue here. This link time assert finds issues early, but has in rare cases false positives due to optimization. I was not able to fix all of them. If this hits a new contributor it will put extra work on us. We can not merge this and test it from time to time ... |
Could we run a CI job without optimization? |
This woks only with optimization. The link assert strikes in, if the good branch is optimized out and only the bad branch remains. |
#endif | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code above enables the feature only on optimized builds.
We can add an extra CMake flag to control it.
Off for local builds.
Than the contributor is surprised when CI fails.
Maybe we may merge it and collect experience ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the builds should behave consistently and the outcome should always be predictable no matter where and how the code is built.
What do others think? I am open to try this out. |
Any new automated checks should be reliable. If they are not reliable they are worse than useless; they are misleading and will end up getting ignored. |
The check itself is reliable once it is in place. The issue is that the DEBUG_ASSERT does fail at link time when the compiler optimizes it ,by splitting up the good and the bad path. In this case the bad path is the only path and it fails. If this happens, the contributor has two options, rearrange the code or use RUNTIME_DEBUG_ASSERT instead. |
This PR is marked as stale because it has been open 90 days with no activity. |
…ranch has been removed
Finding a way to improve debug asserts in const expressions I have developed this PR as a drive by.
This extends our debug asserts to fail linking if the likely good branch is optimized away and not reachable.
This utilizes the __builtin_constant_p() build in function available on gcc and clang.
Unfortunately it does not work in case the DEBUG_ASSERT() statement is duplicated into two branches during optimization.
For these case I have added the old version as X_DEBUG_ASSERT()
Things like DEBUG_ASSERT(false) do no longer work, because they have no good branch and will fail.
For this purpose I have added DEBUG_ASSERT_UNREACHABLE(false)
The good thing is that this works without all constexpr keywords and uses the feature the compiler uses anyway in O3.
The bad thing is that it relies on the compiler optimization.
What do you think about it?