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

Reply via email to