| // Refer issue 55019 for more details. | |
| // A supplemental test case of pr22954.c for other functions modeled in | |
| // the CStringChecker. | |
| // RUN: %clang_analyze_cc1 %s -verify \ | |
| // RUN: -analyzer-checker=core \ | |
| // RUN: -analyzer-checker=unix \ | |
| // RUN: -analyzer-checker=debug.ExprInspection | |
| #include "Inputs/system-header-simulator.h" | |
| #include "Inputs/system-header-simulator-cxx.h" | |
| void *malloc(size_t); | |
| void free(void *); | |
| struct mystruct { | |
| void *ptr; | |
| char arr[4]; | |
| }; | |
| void clang_analyzer_dump(const void *); | |
| // CStringChecker::memsetAux | |
| void fmemset() { | |
| mystruct x; | |
| x.ptr = malloc(1); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| memset(x.arr, 0, sizeof(x.arr)); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| free(x.ptr); // no-leak-warning | |
| } | |
| // CStringChecker::evalCopyCommon | |
| void fmemcpy() { | |
| mystruct x; | |
| x.ptr = malloc(1); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| memcpy(x.arr, "hi", 2); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| free(x.ptr); // no-leak-warning | |
| } | |
| // CStringChecker::evalStrcpyCommon | |
| void fstrcpy() { | |
| mystruct x; | |
| x.ptr = malloc(1); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| strcpy(x.arr, "hi"); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| free(x.ptr); // no-leak-warning | |
| } | |
| void fstrncpy() { | |
| mystruct x; | |
| x.ptr = malloc(1); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| strncpy(x.arr, "hi", sizeof(x.arr)); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| free(x.ptr); // no-leak-warning | |
| } | |
| // CStringChecker::evalStrsep | |
| void fstrsep() { | |
| mystruct x; | |
| x.ptr = malloc(1); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| char *p = x.arr; | |
| (void)strsep(&p, "x"); | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| free(x.ptr); // no-leak-warning | |
| } | |
| // CStringChecker::evalStdCopyCommon | |
| void fstdcopy() { | |
| mystruct x; | |
| x.ptr = new char; | |
| clang_analyzer_dump(x.ptr); // expected-warning {{HeapSymRegion}} | |
| const char *p = "x"; | |
| std::copy(p, p + 1, x.arr); | |
| // FIXME: As we currently cannot know whether the copy overflows, the checker | |
| // invalidates the entire `x` object. When the copy size through iterators | |
| // can be correctly modeled, we can then update the verify direction from | |
| // SymRegion to HeapSymRegion as this std::copy call never overflows and | |
| // hence the pointer `x.ptr` shall not be invalidated. | |
| clang_analyzer_dump(x.ptr); // expected-warning {{SymRegion}} | |
| delete static_cast<char*>(x.ptr); // no-leak-warning | |
| } |