Menu

False negatives: moved string accesses through lambda expressions

Rodri
4 days ago
4 days ago
  • Rodri

    Rodri - 4 days ago

    Hi, I found false negatives regarding the rule accessMoved involving lambda expressions.

    Cppcheck should report accessMoved warnings for the following two programs because both access a std::string object after it has been moved from. However, cppcheck reports no accessMoved warning.

    Case 1: moved object passed through a lambda rvalue-reference parameter

    #include <iostream>
    #include <string>
    #include <utility>
    
    int main() {
      std::string s = "test";
    
      auto f = [](std::string &&m) {
        std::string n = std::move(m);
      };
    
      f(std::move(s));
    
      if (s.empty()) {
      }
    
      std::cout << s << '\n' << std::flush;
      return 0;
    }
    

    In this program, s is passed to the lambda as an rvalue reference, then moved from inside the lambda. The later accesses to s should be reported.

    Case 2: moved object accessed inside a lambda capture

    #include <iostream>
    #include <string>
    #include <utility>
    
    void consume(std::string);
    
    int main() {
      using namespace std::string_literals;
    
      std::string s = "test"s;
      consume(std::move(s));
    
      [&s]() {
        std::cout << s << std::endl;
      }();
    }
    

    In this program, s is moved into consume, and then accessed inside a lambda that captures it by reference. This should also trigger an accessMoved warning.

    Actual result

    Cppcheck reports no accessMoved warning for either program.

    Expected result

    Cppcheck should report accessMoved warnings for the accesses to s after std::move(s).

    Version: 2.21.0

     
  • CHR

    CHR - 4 days ago

    For the first example, I'm getting two warnings:

    test.cpp:10:7: warning: inconclusive: Access of moved variable 's'. [accessMoved]
      if (s.empty()) {
          ^
    test.cpp:8:5: note: Calling std::move(s)
      f(std::move(s));
        ^
    test.cpp:10:7: note: Access of moved variable 's'.
      if (s.empty()) {
          ^
    test.cpp:13:16: warning: Access of moved variable 's'. [accessMoved]
      std::cout << s << '\n' << std::flush;
                   ^
    test.cpp:8:5: note: Calling std::move(s)
      f(std::move(s));
        ^
    test.cpp:13:16: note: Access of moved variable 's'.
      std::cout << s << '\n' << std::flush;
                   ^
    
     
  • CHR

    CHR - 4 days ago

    The second example is covered by https://trac.cppcheck.net/ticket/13774

     

Log in to post a comment.

Monday.com Logo