top | item 32288699

(no title)

pfultz2 | 3 years ago

You dont need annotations, cppcheck already warns with:

    test.cpp:16:45: error: Using object that is a temporary. [danglingTemporaryLifetime]
        assert((std::vector<int>{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB
                                                ^
    test.cpp:3:12: note: Return lambda.
        return [&](std::vector<int>&& items) {
               ^
    test.cpp:2:50: note: Passed to reference.
    auto make_appender(std::vector<int> const& suffix) {
                                                     ^
    test.cpp:4:36: note: Lambda captures variable by reference here.
            return append(move(items), suffix);
                                       ^
    test.cpp:15:35: note: Passed to 'make_appender'.
        auto append34 = make_appender({3, 4});
                                      ^
    test.cpp:15:35: note: Temporary created here.
        auto append34 = make_appender({3, 4});
                                      ^
    test.cpp:16:45: note: Using object that is a temporary.
        assert((std::vector<int>{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB

discuss

order

dataflow|3 years ago

As awesome as that is, cppcheck doesn't seem ready for real-world use. Literally the first invocation I ran resulted in this error:

  error: Syntax Error: AST broken, binary operator '!=' doesn't have two operands. [internalAstError]
   explicit operator bool() const { return this->get() != pointer(); }
This is for a simple wrapper class that looks like this:

  template<class T>
  class Foo : private Bar<T> {
  public:
   typedef value_type *pointer;
   pointer get() const { return ...; }
   explicit operator bool() const { return this->get() != pointer(); }
  };
Another example:

  void foo(uintptr_t const (&input)[2]) {
   if constexpr (sizeof(uintptr_t) == sizeof(int) && sizeof(long long) == 2 * sizeof(int)) {
    long long value;
    memcpy(&reinterpret_cast<uintptr_t *>(&value)[0], &input[0], sizeof(input[0]));
    memcpy(&reinterpret_cast<uintptr_t *>(&value)[1], &input[1], sizeof(input[1]));
   }
  }

  error: The address of local variable 'value' is accessed at non-zero index. [objectIndex]
    memcpy(&reinterpret_cast<uintptr_t *>(&value)[1], &input[1], sizeof(input[1]));
                                                 ^