-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
P0627R6: Function to mark unreachable code #2526
Merged
Merged
Changes from 8 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ab32fa7
unreachable code
AlexGuteniev 7b03bb9
(c)
AlexGuteniev 27d7a8c
inline
AlexGuteniev 6317604
Apply suggestions from code review
AlexGuteniev b234d9b
[[noreturn]] , noexcept /* strengthened */
AlexGuteniev d183d52
__builtin_unreachable
AlexGuteniev 04e36c8
debugging experience
AlexGuteniev 6d9de6f
it wouldn't hurt
AlexGuteniev b564b0d
Use _STL_UNREACHABLE and don't call abort()
AlexGuteniev e9f57df
unreachable()
AlexGuteniev ea8eb26
char
AlexGuteniev 68dc5a7
hail undefined behavior!
AlexGuteniev e64e511
to be (or not to be)
AlexGuteniev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright (c) Microsoft Corporation. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
RUNALL_INCLUDE ..\usual_latest_matrix.lst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <cassert> | ||
#include <utility> | ||
|
||
constexpr int test_impl(int arg) { | ||
AlexGuteniev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
switch (arg) { | ||
case 1: | ||
return 'x'; | ||
|
||
case 2: | ||
return 'y'; | ||
|
||
default: | ||
std::unreachable(); | ||
} | ||
} | ||
|
||
constexpr bool test() { | ||
assert(test_impl(1) == 'x'); | ||
assert(test_impl(2) == 'y'); | ||
return true; | ||
AlexGuteniev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
int main() { | ||
test(); | ||
static_assert(test()); | ||
static_assert(noexcept(std::unreachable())); // strengthened | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I'm not sure this is a great idea.
abort
is well-defined, and therefore doesn't poison the code path leading to it with undefined behavior. That seems like a very subtle difference that folks may not be expecting when they flip the debug/release switch. (I'm going to call this "Comment" rather than "Request change" to get more reviewers' opinions.)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.
I observed that
__assume(false)
does provide UB in debug. Up to thisNormally I'd except debug mode to catch any UBs that can be caught.
Also look into
ATLASSUME
for a precedent.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.
@AlexGuteniev I really like your idea of using
_STL_UNREACHABLE
here as we're already using it in product code for this exact purpose (in<format>
and<variant>
).@CaseyCarter I share your concern about well-defined behavior. How would you feel about:
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.
I think this is the best of both worlds. +1 from me.
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.
Is not really a good option.
By having
abort();
after_STL_UNREACHABLE;
you ask for UB, and compiler may implement the UB by not actually calling abort, and in/O2
it really does!_DEBUG
may be used with/O2
, and I don't think#pragma optimize
is good here.If you want to enjoy UB even in
_DEBUG
here, I'd rather leave just__assume(false)
/__builtin_unreachable()
, wrapped in_STL_UNREACHABLE;
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.
A possible way to be able to debug the unreachable is to guard the original
_STL_UNREACHABLE
in#ifndef _STL_UNREACHABLE
. This way a user may do#define _STL_UNREACHABLE abort()
,#define _STL_UNREACHABLE __debugbreak()
or#define _STL_UNREACHABLE __ud2()
. Still it is arguable place for a customization; if we decide to embrace the UB, let's have it.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.
I'm fine with this, it is working as intended. The goal of putting
abort
here is not to define the behavior, it's to increase the likelihood that the outcome of the UB is to crash near to the occurrence ofunreachable
in the user's code. That outcome isn't deterministic and can't be made deterministic without breaking the intended functionality. I don't agree that the lack of determinism makes theabort
call useless.If people sometimes want to not use
unreachable
they can define their own macros.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.
Please review the comment I added next to
abort()
.(I don't think we can leave the code with deliberate UB without a comment).
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.
Also what exactly the semantic of
_STL_UNREACHABLE
?I mean if this is precondition and not internal invariant, maybe the
abort()
should rather be embedded there rather than here?