1 // RUN: %clang_analyze_cc1 -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=debug.ExprInspection \ 4 // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ 5 // RUN: -analyzer-checker=apiModeling.Errno \ 6 // RUN: -analyzer-checker=alpha.unix.Errno \ 7 // RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true 8 9 #include "Inputs/errno_var.h" 10 11 typedef typeof(sizeof(int)) size_t; 12 typedef __typeof(sizeof(int)) off_t; 13 typedef size_t ssize_t; 14 ssize_t send(int sockfd, const void *buf, size_t len, int flags); 15 off_t lseek(int fildes, off_t offset, int whence); 16 17 void clang_analyzer_warnIfReached(); 18 void clang_analyzer_eval(int); 19 20 int unsafe_errno_read(int sock, void *data, int data_size) { 21 if (send(sock, data, data_size, 0) != data_size) { 22 if (errno == 1) { 23 // expected-warning@-1{{An undefined value may be read from 'errno'}} 24 return 0; 25 } 26 } 27 return 1; 28 } 29 30 int errno_lseek(int fildes, off_t offset) { 31 off_t result = lseek(fildes, offset, 0); 32 if (result == (off_t)-1) { 33 // Failure path. 34 // check if the function is modeled 35 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} 36 return 2; 37 } 38 if (result != offset) { 39 // Not success path (?) 40 // not sure if this is a valid case, allow to check 'errno' 41 if (errno == 1) { // no warning 42 return 1; 43 } 44 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 45 } 46 if (result == offset) { 47 // The checker does not differentiate for this case. 48 // In general case no relation exists between the arg 2 and the returned 49 // value, only for SEEK_SET. 50 if (errno == 1) { // no warning 51 return 1; 52 } 53 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 54 } 55 return 0; 56 } 57