This is an archive of the discontinued LLVM Phabricator instance.

[clang][Interp] Fix compound assign operator evaluation order
ClosedPublic

Authored by tbaeder on Apr 30 2023, 7:21 AM.

Details

Diff Detail

Event Timeline

tbaeder created this revision.Apr 30 2023, 7:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 30 2023, 7:21 AM
tbaeder requested review of this revision.Apr 30 2023, 7:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 30 2023, 7:21 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
aaron.ballman added inline comments.May 2 2023, 1:26 PM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

In C, the evaluation of the operands are unsequenced. C doesn't currently have constexpr functions, only constexpr objects, but that eliminates mutating operations like compound assignment... for the moment. Perhaps a FIXME comment for figuring out how to handle C?

(The situation I'm worried about in C is with UB dealing with unsequenced operations, like rejecting: https://godbolt.org/z/W11jchrKc)

tbaeder added inline comments.May 4 2023, 12:25 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

Could C make them sequenced when introducing constexpr functions? :)

tbaeder added inline comments.May 4 2023, 12:28 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

Since we already emit a warning for this, we could in the future just check if the statement is in a constexpr function and emit an error instead? We're emitting the warning for c++ pre-17 as well but we don't make it an error, I guess because it's not UB there?

tbaeder updated this revision to Diff 519370.May 4 2023, 12:32 AM
tbaeder updated this revision to Diff 519428.May 4 2023, 4:03 AM
aaron.ballman added inline comments.May 4 2023, 7:44 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

If we're actually leaving the operations unsequenced before C++17, then we should reject that code because it is UB: http://eel.is/c++draft/basic#intro.execution-10

The wording in C++14 for assignment operations is:

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

So the left and right operands are unsequenced relative to one another.

tbaeder added inline comments.May 4 2023, 7:48 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

I was looking at the existing implementation when writing this patch: https://github.com/llvm/llvm-project/blob/1a7a00bdc99fa2b2ca19ecd2d1069991b3c1006b/clang/lib/AST/ExprConstant.cpp#L8545-L8568 which always seems to evaluate RHS first (and actually abort for C++ <= 14, but for unrelated reasons, probably because this statement is just not supported in a constexpr context there).

aaron.ballman added inline comments.May 4 2023, 10:02 AM
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

I think the existing implementation is incorrect to accept this in C++14 and earlier:

https://eel.is/c++draft/basic.exec#intro.execution-10.sentence-4
http://eel.is/c++draft/expr.const#5.8

shafik added a subscriber: rsmith.May 4 2023, 12:53 PM
shafik added inline comments.
clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

I filed a bug on this a while ago that we don't catch unsequenced modifications in constant expressions contexts: https://github.com/llvm/llvm-project/issues/37768

I am almost sure I had a conversation with @rsmith about this.

aaron.ballman accepted this revision.May 16 2023, 9:39 AM

LGTM with an extra comment added.

clang/lib/AST/Interp/ByteCodeExprGen.cpp
623–625

Let's add the FIXME comment here as well and come back to address the issue with sequencing later.

This revision is now accepted and ready to land.May 16 2023, 9:39 AM