| Issue |
180521
|
| Summary |
[clang][CFG] Assignment evaluates LHS before RHS, violating C++17 sequencing rules
|
| Labels |
clang:static analyzer,
clang:dataflow,
clang:analysis
|
| Assignees |
|
| Reporter |
usx95
|
https://godbolt.org/z/r37beTW9r
"In every simple assignment _expression_ E1=E2 and every compound assignment _expression_ E1@=E2, E2 is sequenced before E1" - https://en.cppreference.com/w/cpp/language/eval_order.html (point 19)
"The right operand is sequenced before the left operand." - https://eel.is/c++draft/expr.assign#1.sentence-5
```cpp
#include <flat_map>
#include <string>
int main() {
std::flat_map<int, std::string> mp;
for (int i = 0; i < 100; ++i) {
mp[i] = "123456";
int next = i + 1;
// According to C++17, mp[i] (RHS) must be evaluated before mp[next] (LHS)
mp[next] = mp[i];
}
}
```
CFG:
```
16: int next = i + 1;
17: operator=
18: [B3.17] (ImplicitCastExpr, FunctionToPointerDecay, basic_string<char> &(*)(const basic_string<char> &))
19: operator[]
20: [B3.19] (ImplicitCastExpr, FunctionToPointerDecay, mapped_type &(*)(const key_type &))
21: mp
22: next
23: [B3.22] (ImplicitCastExpr, NoOp, const key_type)
24: [B3.21][[B3.23]] (OperatorCall) <-- LHS evaluated here `mp[next]`
25: operator[]
26: [B3.25] (ImplicitCastExpr, FunctionToPointerDecay, mapped_type &(*)(const key_type &))
27: mp
28: i
29: [B3.28] (ImplicitCastExpr, NoOp, const key_type)
30: [B3.27][[B3.29]] (OperatorCall) <-- RHS evaluated here `mp[i]`
31: [B3.30] (ImplicitCastExpr, NoOp, const basic_string<char>)
32: [B3.24] = [B3.31] (OperatorCall) <-- Final assignment
```
(This is not a bug in clang and clang does the expected. https://godbolt.org/z/ehzsnYqnG is detected as a use-after-free!)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs