| // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s |
| |
| // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,alpha.unix,debug.ExprInspection -verify %s |
| |
| #include "Inputs/system-header-simulator.h" |
| #include "Inputs/system-header-simulator-for-malloc.h" |
| |
| void test_getline_null_buffer() { |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| char *buffer = NULL; |
| size_t n = 0; |
| if (getline(&buffer, &n, F1) > 0) { |
| char c = buffer[0]; // ok |
| } |
| free(buffer); |
| fclose(F1); |
| } |
| |
| void test_getline_malloc_buffer() { |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| |
| size_t n = 10; |
| char *buffer = malloc(n); |
| char *ptr = buffer; |
| |
| ssize_t r = getdelim(&buffer, &n, '\r', F1); |
| // ptr may be dangling |
| free(ptr); // expected-warning {{Attempt to free released memory}} |
| free(buffer); // ok |
| fclose(F1); |
| } |
| |
| void test_getline_alloca() { |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| size_t n = 10; |
| char *buffer = alloca(n); |
| getline(&buffer, &n, F1); // expected-warning {{Memory allocated by alloca() should not be deallocated}} |
| fclose(F1); |
| } |
| |
| void test_getline_invalid_ptr() { |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| size_t n = 10; |
| char *buffer = (char*)test_getline_invalid_ptr; |
| getline(&buffer, &n, F1); // expected-warning {{Argument to getline() is the address of the function 'test_getline_invalid_ptr', which is not memory allocated by malloc()}} |
| fclose(F1); |
| } |
| |
| void test_getline_leak() { |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| |
| char *buffer = NULL; |
| size_t n = 0; |
| ssize_t read; |
| |
| while ((read = getline(&buffer, &n, F1)) != -1) { |
| printf("%s\n", buffer); |
| } |
| |
| fclose(F1); // expected-warning {{Potential memory leak}} |
| } |
| |
| void test_getline_stack() { |
| size_t n = 10; |
| char buffer[10]; |
| char *ptr = buffer; |
| |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| |
| getline(&ptr, &n, F1); // expected-warning {{Argument to getline() is the address of the local variable 'buffer', which is not memory allocated by malloc()}} |
| } |
| |
| void test_getline_static() { |
| static size_t n = 10; |
| static char buffer[10]; |
| char *ptr = buffer; |
| |
| FILE *F1 = tmpfile(); |
| if (!F1) |
| return; |
| |
| getline(&ptr, &n, F1); // expected-warning {{Argument to getline() is the address of the static variable 'buffer', which is not memory allocated by malloc()}} |
| } |