示例#1
0
    void deallocuse2() {
        check("void f(char *p) {\n"
              "    free(p);\n"
              "    strcpy(a, p);\n"
              "}");
        TODO_ASSERT_EQUALS("error (free,use)", "[test.c:3]: (information) --check-library: Function strcpy() should have <noreturn> configuration\n", errout.str());

        check("void f(char *p) {\n"   // #3041 - assigning pointer when it's used
              "    free(p);\n"
              "    strcpy(a, p=b());\n"
              "}");
        TODO_ASSERT_EQUALS("", "[test.c:3]: (information) --check-library: Function strcpy() should have <noreturn> configuration\n", errout.str());
    }
示例#2
0
    void heapDoubleFree() {
        check("void f() {"
              "  HANDLE MyHeap = HeapCreate(0, 0, 0);"
              "  int *a = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  int *b = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  HeapFree(MyHeap, 0, a);"
              "  HeapFree(MyHeap, 0, b);"
              "  HeapDestroy(MyHeap);"
              "}");
        TODO_ASSERT_EQUALS("", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n"
                           "[test.c:1]: (error) Resource handle 'MyHeap' freed twice.\n", errout.str());

        check("void f() {"
              "  int *a = HeapAlloc(GetProcessHeap(), 0, sizeof(int));"
              "  int *b = HeapAlloc(GetProcessHeap(), 0, sizeof(int));"
              "  HeapFree(GetProcessHeap(), 0, a);"
              "  HeapFree(GetProcessHeap(), 0, b);"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f() {"
              "  HANDLE MyHeap = HeapCreate(0, 0, 0);"
              "  int *a = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  int *b = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  HeapFree(MyHeap, 0, a);"
              "  HeapDestroy(MyHeap);"
              "}");
        TODO_ASSERT_EQUALS("[test.c:1] (error) Memory leak: b", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n"
                           "[test.c:1]: (error) Memory leak: b\n", errout.str());

        check("void f() {"
              "  HANDLE MyHeap = HeapCreate(0, 0, 0);"
              "  int *a = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  int *b = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  HeapFree(MyHeap, 0, a);"
              "  HeapFree(MyHeap, 0, b);"
              "}");
        TODO_ASSERT_EQUALS("[test.c:1] (error) Resource leak: MyHeap", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n", errout.str());

        check("void f() {"
              "  HANDLE MyHeap = HeapCreate(0, 0, 0);"
              "  int *a = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  int *b = HeapAlloc(MyHeap, 0, sizeof(int));"
              "  HeapFree(MyHeap, 0, a);"
              "}");
        TODO_ASSERT_EQUALS("[test.c:1] (error) Resource leak: MyHeap\n[test.c:1] (error) Memory leak: b",
                           "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n[test.c:1]: (error) Memory leak: b\n", errout.str());
    }
示例#3
0
 void structmember() {
     check("struct Foo { int *p };\n"
           "void f(struct Foo *foo) {\n"
           "    int i = foo->p;\n"
           "}\n");
     TODO_ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning an address value to the integer (int/long/etc) type is not portable\n", "", errout.str());
 }
示例#4
0
    void ptrarithmetic() {
        // #3073
        check("void foo(int *p) {\n"
              "    int x = 10;\n"
              "    int *a = p + x;\n"
              "}\n");
        ASSERT_EQUALS("", errout.str());

        check("void foo(int *p) {\n"
              "    int x = 10;\n"
              "    int *a = x + p;\n"
              "}\n");
        ASSERT_EQUALS("", errout.str());

        check("void foo(int *p) {\n"
              "    int x = 10;\n"
              "    int *a = x * x;\n"
              "}\n");
        TODO_ASSERT_EQUALS("error", "", errout.str());

        check("void foo(int *start, int *end) {\n"
              "    int len;\n"
              "    int len = end + 10 - start;\n"
              "}\n");
        ASSERT_EQUALS("", errout.str());
    }
示例#5
0
    void division8() {
        check("void foo(int b)\n"
              "{\n"
              "    if (b > 0)\n"
              "    {\n"
              "         unsigned int a;\n"
              "         unsigned int c = a / b;\n"
              "    }\n"
              "}", true);
        ASSERT_EQUALS("", errout.str());

        check("void foo(int b)\n"
              "{\n"
              "    if (b < 0)\n"
              "    {\n"
              "         unsigned int a;\n"
              "         unsigned int c = a / b;\n"
              "    }\n"
              "}", true);
        TODO_ASSERT_EQUALS("[test.cpp:6]: (warning) Division with signed and unsigned operators. The result might be wrong.\n",
                           "", errout.str());

        check("void a(int i) { }\n"
              "int foo( unsigned int sz )\n"
              "{\n"
              "    register unsigned int i=1;\n"
              "    return i/sz;\n"
              "}", true);
        ASSERT_EQUALS("", errout.str());
    }
示例#6
0
 void structmember() {
     check("struct Foo { int *p };\n"
           "void f(struct Foo *foo) {\n"
           "    int i = foo->p;\n"
           "}");
     TODO_ASSERT_EQUALS("[test.cpp:3]: (portability) Assigning a pointer to an integer is not portable.\n", "", errout.str());
 }
示例#7
0
    void deallocuse2() {
        check("void f(char *p) {\n"
              "    free(p);\n"
              "    strcpy(a, p);\n"
              "}");
        TODO_ASSERT_EQUALS("error", "", errout.str());

        check("void f(char *p) {\n"   // #3041 - assigning pointer when it's used
              "    free(p);\n"
              "    strcpy(a, p=b());\n"
              "}");
        ASSERT_EQUALS("", errout.str());
    }
示例#8
0
 void testvolatile()
 {
     check("\n"
           "#include <iostream>\n"
           "class K {};\n"
           "int main(int argc, char *argv[])\n"
           "{\n"
           "    volatile K k(0);\n"
           "    std::cout << k << std::endl;\n"
           "    k++;\n"
           "    std::cout << k << std::endl;\n"
           "    return 0;\n"
           "}\n");
     TODO_ASSERT_EQUALS("",
                        "[test.cpp:8]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
 }
示例#9
0
    void throw1() { // 3987 - Execution reach a 'throw'
        check("void f() {\n"
              "    char *p = malloc(10);\n"
              "    throw 123;\n"
              "}");
        TODO_ASSERT_EQUALS("error", "", errout.str());

        check("void f() {\n"
              "    char *p;\n"
              "    try {\n"
              "        p = malloc(10);\n"
              "        throw 123;\n"
              "    } catch (...) { }\n"
              "    free(p);\n"
              "}");
        ASSERT_EQUALS("", errout.str());
    }
示例#10
0
    void destructors() {
        check("class x {\n"
              "    ~x() {\n"
              "        throw e;\n"
              "    }\n"
              "};");
        ASSERT_EQUALS("[test.cpp:3]: (warning) Class x is not safe, destructor throws exception\n", errout.str());

        check("class x {\n"
              "    ~x();\n"
              "};\n"
              "x::~x() {\n"
              "    throw e;\n"
              "}");
        ASSERT_EQUALS("[test.cpp:5]: (warning) Class x is not safe, destructor throws exception\n", errout.str());

        check("x::~x() {\n"
              "    throw e;\n"
              "}");
        TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) Class x is not safe, destructor throws exception\n", "", errout.str());

        // #3858 - throwing exception in try block in destructor.
        check("class x {\n"
              "    ~x() {\n"
              "        try {\n"
              "            throw e;\n"
              "        } catch (...) {\n"
              "        }\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("class x {\n"
              "    ~x() {\n"
              "        if(!std::uncaught_exception()) {\n"
              "            throw e;\n"
              "        }\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());
    }
示例#11
0
    void fp_operator() {
        // #2407 - FP when function is called from operator()
        check("class Fred\n"
              "{\n"
              "public:\n"
              "    void operator()(int x) {\n"
              "        startListening();\n"
              "    }\n"
              "\n"
              "private:\n"
              "    void startListening() {\n"
              "    }\n"
              "};");
        ASSERT_EQUALS("", errout.str());

        check("class Fred\n"
              "{\n"
              "public:\n"
              "    void operator()(int x) {\n"
              "    }\n"
              "\n"
              "private:\n"
              "    void startListening() {\n"
              "    }\n"
              "};");
        ASSERT_EQUALS("[test.cpp:8]: (style) Unused private function: 'Fred::startListening'\n", errout.str());

        // #5059
        check("class Fred {\n"
              "    void* operator new(size_t obj_size, size_t buf_size) {}\n"
              "};");
        TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Unused private function: 'Fred::operatornew'\n", "", errout.str()); // No message for operators - we currently cannot check their usage

        check("class Fred {\n"
              "    void* operator new(size_t obj_size, size_t buf_size) {}\n"
              "public:\n"
              "    void* foo() { return new(size) Fred(); }\n"
              "};");
        ASSERT_EQUALS("", errout.str());
    }
示例#12
0
    void checkPointerSizeofStruct() {
        check("void f() {\n"
              "    struct foo *ptr;\n"
              "    memset( ptr->bar, 0, sizeof ptr->bar );\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f() {\n"
              "    struct foo {\n"
              "        char bar[10];\n"
              "    };\n"
              "    memset( ptr->bar, 0, sizeof ptr->bar );\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f() {\n"
              "    struct foo {\n"
              "        char *bar;\n"
              "    };\n"
              "    memset( ptr->bar, 0, sizeof ptr->bar );\n"
              "}");
        TODO_ASSERT_EQUALS("[test.cpp:5]: (warning) Size of pointer 'bar' used instead of size of its data.\n", "", errout.str());
    }
示例#13
0
    void test1()
    {
        check("class Fred\n"
              "{\n"
              "private:\n"
              "    unsigned int f();\n"
              "public:\n"
              "    Fred();\n"
              "};\n"
              "\n"
              "Fred::Fred()\n"
              "{ }\n"
              "\n"
              "unsigned int Fred::f()\n"
              "{ }\n");

        ASSERT_EQUALS("[test.cpp:4]: (style) Unused private function 'Fred::f'\n", errout.str());

        check("#file \"p.h\"\n"
              "class Fred\n"
              "{\n"
              "private:\n"
              "    unsigned int f();\n"
              "public:\n"
              "    Fred();\n"
              "};\n"
              "\n"
              "#endfile\n"
              "Fred::Fred()\n"
              "{ }\n"
              "\n"
              "unsigned int Fred::f()\n"
              "{ }\n");

        TODO_ASSERT_EQUALS("[p.h:4]: (style) Unused private function 'Fred::f'\n", errout.str());

        check("#file \"p.h\"\n"
              "class Fred\n"
              "{\n"
              "private:\n"
              "void f();\n"
              "};\n"
              "\n"
              "\n"
              "#endfile\n"
              "\n"
              "void Fred::f()\n"
              "{\n"
              "}\n"
              "\n");
        TODO_ASSERT_EQUALS("[p.h:4]: (style) Unused private function 'Fred::f'\n", errout.str());

        // Don't warn about include files which implementation we don't see
        check("#file \"p.h\"\n"
              "class Fred\n"
              "{\n"
              "private:\n"
              "void f();\n"
              "void g() {}\n"
              "};\n"
              "\n"
              "#endfile\n"
              "\n"
              "int main()\n"
              "{\n"
              "}\n"
              "\n");
        ASSERT_EQUALS("", errout.str());
    }
示例#14
0
    void testinvaliddealloc() {
        check("void func1() {\n"
              "    char tmp1[256];\n"
              "    free(tmp1);\n"
              "    char tmp2[256];\n"
              "    delete tmp2;\n"
              "    char tmp3[256];\n"
              "    delete tmp3;\n"
              "    char tmp4[256];\n"
              "    delete[] (tmp4);\n"
              "    char tmp5[256];\n"
              "    delete[] tmp5;\n"
              "}");
        ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
                      "[test.cpp:5]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
                      "[test.cpp:7]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
                      "[test.cpp:9]: (error) Deallocation of an auto-variable results in undefined behaviour.\n"
                      "[test.cpp:11]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());

        check("void func1() {\n"
              "    char* tmp1[256];\n"
              "    init(tmp1);\n"
              "    delete tmp1[34];\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f()\n"
              "{\n"
              "    char psz_title[10];\n"
              "    {\n"
              "        char *psz_title = 0;\n"
              "        abc(0, psz_title);\n"
              "        free(psz_title);\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        // #2298 new check: passing stack-address to free()
        check("int main() {\n"
              "   int *p = malloc(4);\n"
              "   free(&p);\n"
              "   return 0;\n"
              "}");
        ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());
        check("int main() {\n"
              "   int i;\n"
              "   free(&i);\n"
              "   return 0;\n"
              "}");
        ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", errout.str());

        // #5732
        check("int main() {\n"
              "   long (*pKoeff)[256] = new long[9][256];\n"
              "   delete[] pKoeff;\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("int main() {\n"
              "   long *pKoeff[256];\n"
              "   delete[] pKoeff;\n"
              "}");
        TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", "", errout.str());

        check("int main() {\n"
              "   long *pKoeff[256];\n"
              "   free (pKoeff);\n"
              "}");
        TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Deallocation of an auto-variable results in undefined behaviour.\n", "", errout.str());

        check("void foo() {\n"
              "   const intPtr& intref = Getter();\n"
              "   delete intref;\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void test() {\n"
              "   MyObj& obj = *new MyObj;\n"
              "   delete &obj;\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        // #6506
        check("struct F {\n"
              "  void free(void*) {}\n"
              "};\n"
              "void foo() {\n"
              "  char c1[1];\n"
              "  F().free(c1);\n"
              "  char *c2 = 0;\n"
              "  F().free(&c2);\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("class foo {\n"
              "  void free(void* );\n"
              "  void someMethod() {\n"
              "    char **dst_copy = NULL;\n"
              "    free(&dst_copy);\n"
              "  }\n"
              "};");
        ASSERT_EQUALS("", errout.str());
    }
示例#15
0
    void doublefree1() {  // #3895
        check("void f(char *p) {\n"
              "    if (x)\n"
              "        free(p);\n"
              "    else\n"
              "        p = 0;\n"
              "    free(p);\n"
              "}");
        ASSERT_EQUALS("[test.c:6]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p) {\n"
            "  free(p);\n"
            "  free(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:3]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p, char *r) {\n"
            "  free(p);\n"
            "  free(r);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo() {\n"
            "  free(p);\n"
            "  free(r);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  if (x < 3) free(p);\n"
            "  else { if (x > 9) free(p); }\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  free(p);\n"
            "  getNext(&p);\n"
            "  free(p);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  free(p);\n"
            "  bar();\n"
            "  free(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p) {\n"
            "  free(p);\n"
            "  printf(\"Freed memory at location %x\", p);\n"
            "  free(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(FILE *p) {\n"
            "  fclose(p);\n"
            "  fclose(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:3]: (error) Resource handle 'p' freed twice.\n", errout.str());

        check(
            "void foo(FILE *p, FILE *r) {\n"
            "  fclose(p);\n"
            "  fclose(r);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(FILE *p) {\n"
            "  if (x < 3) fclose(p);\n"
            "  else { if (x > 9) fclose(p); }\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(FILE *p) {\n"
            "  fclose(p);\n"
            "  gethandle(&p);\n"
            "  fclose(p);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(FILE *p) {\n"
            "  fclose(p);\n"
            "  gethandle();\n"
            "  fclose(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:4]: (error) Resource handle 'p' freed twice.\n", errout.str());

        check(
            "void foo(Data* p) {\n"
            "  free(p->a);\n"
            "  free(p->b);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void f() {\n"
            "    char *p; p = malloc(100);\n"
            "    if (x) {\n"
            "        free(p);\n"
            "        exit();\n"
            "    }\n"
            "    free(p);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void f() {\n"
            "    char *p; p = malloc(100);\n"
            "    if (x) {\n"
            "        free(p);\n"
            "        x = 0;\n"
            "    }\n"
            "    free(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:7]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void f() {\n"
            "    char *p; p = do_something();\n"
            "    free(p);\n"
            "    p = do_something();\n"
            "    free(p);\n"
            "}");
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete p;\n"
            "  delete p;\n"
            "}", true);
        ASSERT_EQUALS("[test.cpp:3]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p, char *r) {\n"
            "  delete p;\n"
            "  delete r;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(P p) {\n"
            "  delete p.x;\n"
            "  delete p;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char **p) {\n"
            "  delete p[0];\n"
            "  delete p[1];\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete p;\n"
            "  getNext(&p);\n"
            "  delete p;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete p;\n"
            "  bar();\n"
            "  delete p;\n"
            "}", true);
        ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete[] p;\n"
            "  delete[] p;\n"
            "}", true);
        ASSERT_EQUALS("[test.cpp:3]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void foo(char *p, char *r) {\n"
            "  delete[] p;\n"
            "  delete[] r;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete[] p;\n"
            "  getNext(&p);\n"
            "  delete[] p;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(char *p) {\n"
            "  delete[] p;\n"
            "  bar();\n"
            "  delete[] p;\n"
            "}", true);
        ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "~LineMarker() {\n"
            "  delete pxpm;\n"
            "}\n"
            "LineMarker &operator=(const LineMarker &) {\n"
            "  delete pxpm;\n"
            "  pxpm = NULL;\n"
            "  return *this;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo()\n"
            "{\n"
            "  int* ptr; ptr = NULL;\n"
            "  try\n"
            "    {\n"
            "      ptr = new int(4);\n"
            "    }\n"
            "  catch(...)\n"
            "    {\n"
            "      delete ptr;\n"
            "      throw;\n"
            "    }\n"
            "  delete ptr;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "int foo()\n"
            "{\n"
            "   int* a; a = new int;\n"
            "   bool doDelete; doDelete = true;\n"
            "   if (a != 0)\n"
            "   {\n"
            "       doDelete = false;\n"
            "       delete a;\n"
            "   }\n"
            "   if(doDelete)\n"
            "       delete a;\n"
            "   return 0;\n"
            "}", true);
        TODO_ASSERT_EQUALS("", "[test.cpp:11]: (error) Memory pointed to by 'a' is freed twice.\n", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    while(true) {\n"
            "        x = new char[100];\n"
            "        if (y++ > 100)\n"
            "            break;\n"
            "        delete[] x;\n"
            "    }\n"
            "    delete[] x;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    for (int i = 0; i < 10000; i++) {\n"
            "        x = new char[100];\n"
            "        delete[] x;\n"
            "    }\n"
            "    delete[] x;\n"
            "}", true);
        TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    while (isRunning()) {\n"
            "        x = new char[100];\n"
            "        delete[] x;\n"
            "    }\n"
            "    delete[] x;\n"
            "}", true);
        TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    while (isRunning()) {\n"
            "        x = malloc(100);\n"
            "        free(x);\n"
            "    }\n"
            "    free(x);\n"
            "}");
        TODO_ASSERT_EQUALS("[test.c:8]: (error) Memory pointed to by 'x' is freed twice.\n", "", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    for (;;) {\n"
            "        x = new char[100];\n"
            "        if (y++ > 100)\n"
            "            break;\n"
            "        delete[] x;\n"
            "    }\n"
            "    delete[] x;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void foo(int y)\n"
            "{\n"
            "    char * x; x = NULL;\n"
            "    do {\n"
            "        x = new char[100];\n"
            "        if (y++ > 100)\n"
            "            break;\n"
            "        delete[] x;\n"
            "    } while (true);\n"
            "    delete[] x;\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void f()\n"
            "{\n"
            "    char *p; p = 0;\n"
            "    if (x < 100) {\n"
            "        p = malloc(10);\n"
            "        free(p);\n"
            "    }\n"
            "    free(p);\n"
            "}");
        ASSERT_EQUALS("[test.c:8]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());

        check(
            "void MyFunction()\n"
            "{\n"
            "    char* data; data = new char[100];\n"
            "    try\n"
            "    {\n"
            "    }\n"
            "    catch(err)\n"
            "    {\n"
            "        delete[] data;\n"
            "        MyThrow(err);\n"
            "    }\n"
            "    delete[] data;\n"
            "}\n"

            "void MyThrow(err)\n"
            "{\n"
            "    throw(err);\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check(
            "void MyFunction()\n"
            "{\n"
            "    char* data; data = new char[100];\n"
            "    try\n"
            "    {\n"
            "    }\n"
            "    catch(err)\n"
            "    {\n"
            "        delete[] data;\n"
            "        MyExit(err);\n"
            "    }\n"
            "    delete[] data;\n"
            "}\n"

            "void MyExit(err)\n"
            "{\n"
            "    exit(err);\n"
            "}", true);
        ASSERT_EQUALS("", errout.str());

        check( // #6252
            "struct Wrapper {\n"
            "    Thing* m_thing;\n"
            "    Wrapper() : m_thing(0) {\n"
            "    }\n"
            "    ~Wrapper() {\n"
            "        delete m_thing;\n"
            "    }\n"
            "    void changeThing() {\n"
            "        delete m_thing;\n"
            "        m_thing = new Thing;\n"
            "    }\n"
            "};", true);
        ASSERT_EQUALS("", errout.str());
    }
示例#16
0
    void comparisonOfBoolExpressionWithInt2() {
        check("void f(int x) {\n"
              "    if (!x == 10) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str());

        check("void f(int x) {\n"
              "    if (!x != 10) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str());

        check("void f(int x) {\n"
              "    if (x != 10) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f(int x) {\n"
              "    if (10 == !x) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str());

        check("void f(int x) {\n"
              "    if (10 != !x) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str());

        check("void f(int x, int y) {\n"
              "    if (y != !x) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f(int x, bool y) {\n"
              "    if (y != !x) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f(int x) {\n"
              "    if (10 != x) {\n"
              "        printf(\"x not equal to 10\");\n"
              "    }\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("void f(int x, int y) {\n"
              "    return (!y == !x);\n"
              "}");
        ASSERT_EQUALS("", errout.str());

        check("int f(int a) {\n"
              "  return (x()+1 == !a);\n"
              "}");
        TODO_ASSERT_EQUALS("error", "", errout.str());

        check("void f() { if (!!a+!!b+!!c>1){} }");
        ASSERT_EQUALS("",errout.str());

        check("void f(int a, int b, int c) { if (a != !b || c) {} }");
        ASSERT_EQUALS("",errout.str());

        check("void f(int a, int b, int c) { if (1 < !!a + !!b + !!c) {} }");
        ASSERT_EQUALS("",errout.str());

        check("void f(int a, int b, int c) { if (1 < !(a+b)) {} }");
        ASSERT_EQUALS("[test.cpp:1]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n",errout.str());
    }