-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][bytecode] Fix 'if consteval' in non-constant contexts #104707
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
Merged
Merged
Changes from all commits
Commits
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 hidden or 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 hidden or 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 hidden or 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 |
---|---|---|
|
@@ -780,3 +780,5 @@ def AllocCN : Opcode { | |
def Free : Opcode { | ||
let Args = [ArgBool]; | ||
} | ||
|
||
def IsConstantContext: Opcode; |
This file contains hidden or 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
Oops, something went wrong.
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.
We really should not evaluate the condition, just the underlying statement directly
(getThen or getElse depending on both
S.inConstantContext()
and whether it's negated)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 condition is only evaluated if the ifstmt is not a consteval stmt at all
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 mean, we should not have a
emitIsConstantContext(IS)
- just emit the underlying statementThere 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.
That's what the previous code did, though. That doesn't work if we compile to bytecode and later interpret the same bytecode in a non-constant context.
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.
How would you deal with code like
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.
Only if that has truly not been implemented yet. Otherwise, we need to always diagnose it anyway, in the same way we do for regular if statements.
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 whole point of
if consteval
is to allow a runtime evaluation to do thing that would not be valid in constant context, such as asm or simd or reinterpret cast or crazy vendor extensions.so
is intended to always work.
I don't think it would be reasonable to delay adoption of the new interpreter until we support all the features of clang in the bytecode.
So this approach is probably not viable.
If you really want to create bytecode for both branches, you need to have an escape hatch so that if the non-consteval branch cannot produce bytecode, we still can support the consteval branch without error
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.
Stuff like that needs to be "implemented" in the interpreter. It must be, because it must be rejected as well. It's the same example as the
goto
statement above. It needs to be compiled to bytecode, somehow. If it isn't then using it in a constexpr function (without theif consteval
will also fail).Again, this is no different than any other if statement. I could imagine compiling two different versions of functions (one for consteval = true, one for =false), but we have the same problem with other if statements. This is just a difference between the interpreting and compiling approach.
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.
Ok, it took me a while, but iI think i got it... sorry for the brain fart.
Because the interpreter compile functions before they are evaluated (at least morally), we don't know in which context they are going to be executed.
This is somewhat confusing because that means which assume we can constant evaluate something that is not a constant expression, which i guess is true for constant folding.
In that light the patch makes sense, I think
I still wants to make sure that we can recover nicely in the presence of things we can't evaluate, which seems to be the case https://godbolt.org/z/bofa9b8de
Do you do the same thing for
is_constant_evaluated
?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.
Yes:
llvm-project/clang/lib/AST/ByteCode/InterpBuiltin.cpp
Line 162 in 933f722