Uploaded image for project: 'SonarCFamily'
  1. SonarCFamily
  2. CPP-2736

OneStatementPerLine (S122): FP with incomplete loc for temporary expressions

    Details

    • Type: False-Positive
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 6.13
    • Fix Version/s: 6.14
    • Component/s: Rules
    • Labels:
      None

      Description

      The following code triggers the FP:

      #include <initializer_list>
      
      using namespace std;
      
      template <class T>
      struct Vector {
        Vector();
        void f();
        explicit Vector(std::initializer_list<T> l, int i = 0);
      };
      
      
      template<class T>
      void f() {
        Vector<T> input;
        input = Vector<T>{ 3, 4, 5 };
        input.f();
      }
      
      void g() {
        f<float>();
      }
      

      What happens is that the end location of the statement input = ... is invalid.
      For that to happen, the following are required:

      • A temporary object should be created
      • With a constructor with an initializer_list
      • The constructor with initializer_list must have an extra optional parameter with not argument provided

      For instance, compare the AST generated with this code with and without the extra parameter:

      |     |-ExprWithCleanups <line:16:3, 'Vector<float>' lvalue
      |     | `-CXXOperatorCallExpr <col:3, 'Vector<float>' lvalue
      |     |   |-ImplicitCastExpr <col:9> 'Vector<float> &(*)(Vector<float> &&) noexcept' <FunctionToPointerDecay>
      |     |   | `-DeclRefExpr <col:9> 'Vector<float> &(Vector<float> &&) noexcept' lvalue CXXMethod 0x55d8dbe0a2b8 'operator=' 'Vector<float> &(Vector<float> &&) noexcept'
      |     |   |-DeclRefExpr <col:3> 'Vector<float>':'Vector<float>' lvalue Var 0x55d8dbe068e0 'input' 'Vector<float>':'Vector<float>'
      |     |   `-MaterializeTemporaryExpr <col:11, 'Vector<float>':'Vector<float>' xvalue
      |     |     `-CXXTemporaryObjectExpr <col:11, 'Vector<float>':'Vector<float>' 'void (std::initializer_list<float>, int)' list std::initializer_list
      |     |       |-CXXStdInitializerListExpr <col:20, col:30> 'std::initializer_list<float>':'std::initializer_list<float>'
      |     |       | `-MaterializeTemporaryExpr <col:20, col:30> 'const float [3]' xvalue
      |     |       |   `-InitListExpr <col:20, col:30> 'const float [3]'
      |     |       |     |-ImplicitCastExpr <col:22> 'const float' <IntegralToFloating>
      |     |       |     | `-IntegerLiteral <col:22> 'int' 3
      |     |       |     |-ImplicitCastExpr <col:25> 'const float' <IntegralToFloating>
      |     |       |     | `-IntegerLiteral <col:25> 'int' 4
      |     |       |     `-ImplicitCastExpr <col:28> 'const float' <IntegralToFloating>
      |     |       |       `-IntegerLiteral <col:28> 'int' 5
      |     |       `-CXXDefaultArgExpr 'int'
      |     |-ExprWithCleanups <line:16:3, col:30> 'Vector<float>' lvalue
      |     | `-CXXOperatorCallExpr <col:3, col:30> 'Vector<float>' lvalue
      |     |   |-ImplicitCastExpr <col:9> 'Vector<float> &(*)(Vector<float> &&) noexcept' <FunctionToPointerDecay>
      |     |   | `-DeclRefExpr <col:9> 'Vector<float> &(Vector<float> &&) noexcept' lvalue CXXMethod 0x55c29a1e6bc8 'operator=' 'Vector<float> &(Vector<float> &&) noexcept'
      |     |   |-DeclRefExpr <col:3> 'Vector<float>':'Vector<float>' lvalue Var 0x55c29a1e32b0 'input' 'Vector<float>':'Vector<float>'
      |     |   `-MaterializeTemporaryExpr <col:11, col:30> 'Vector<float>':'Vector<float>' xvalue
      |     |     `-CXXTemporaryObjectExpr <col:11, col:30> 'Vector<float>':'Vector<float>' 'void (std::initializer_list<float>)' list std::initializer_list
      |     |       `-CXXStdInitializerListExpr <col:20, col:30> 'std::initializer_list<float>':'std::initializer_list<float>'
      |     |         `-MaterializeTemporaryExpr <col:20, col:30> 'const float [3]' xvalue
      |     |           `-InitListExpr <col:20, col:30> 'const float [3]'
      |     |             |-ImplicitCastExpr <col:22> 'const float' <IntegralToFloating>
      |     |             | `-IntegerLiteral <col:22> 'int' 3
      |     |             |-ImplicitCastExpr <col:25> 'const float' <IntegralToFloating>
      |     |             | `-IntegerLiteral <col:25> 'int' 4
      |     |             `-ImplicitCastExpr <col:28> 'const float' <IntegralToFloating>
      |     |               `-IntegerLiteral <col:28> 'int' 5

      Maybe to silent the false positive, checking if the location is wrong is enough...

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                loic.joly Loïc Joly
                Reporter:
                loic.joly Loïc Joly
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Due:
                  Created:
                  Updated:
                  Resolved: