// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -verify %s typedef decltype(sizeof(int)) size_t; void clang_analyzer_eval(bool); char *strncpy(char *dest, const char *src, size_t x); constexpr int initB = 100; struct Base { int b; Base(): b(initB) {} }; // issue 143807 struct strncpyTestClass: public Base { int *m_ptr; char m_buff[1000]; void KnownLen(char *src) { m_ptr = new int; strncpy(m_buff, src, sizeof(m_buff)); // known len but unknown src size delete m_ptr; // no warning } void KnownSrcLen(size_t n) { m_ptr = new int; strncpy(m_buff, "xyz", n); // known src size but unknown len delete m_ptr; // no warning } }; void strncpyTest(char *src, size_t n) { strncpyTestClass rep; rep.KnownLen(src); rep.KnownSrcLen(n); clang_analyzer_eval(rep.b == initB); // expected-warning{{TRUE}} } size_t strlcpy(char *dest, const char *src, size_t size); struct strlcpyTestClass: public Base { int *m_ptr; char m_buff[1000]; void KnownLen(char *src) { m_ptr = new int; strlcpy(m_buff, src, sizeof(m_buff)); // known len but unknown src size delete m_ptr; // no warning } void KnownSrcLen(size_t n) { m_ptr = new int; strlcpy(m_buff, "xyz", n); // known src size but unknown len delete m_ptr; // no warning } }; void strlcpyTest(char *src, size_t n) { strlcpyTestClass rep; rep.KnownLen(src); rep.KnownSrcLen(n); clang_analyzer_eval(rep.b == initB); // expected-warning{{TRUE}} } char *strncat(char *s1, const char *s2, size_t n); struct strncatTestClass: public Base { int *m_ptr; char m_buff[1000]; void KnownLen(char *src) { m_ptr = new int; strncat(m_buff, src, sizeof(m_buff) - 1); // known len but unknown src size delete m_ptr; // no warning } void KnownSrcLen(size_t n) { m_ptr = new int; strncat(m_buff, "xyz", n); // known src size but unknown len delete m_ptr; // no warning } }; void strncatTest(char *src, size_t n) { strncatTestClass rep; rep.KnownLen(src); rep.KnownSrcLen(n); clang_analyzer_eval(rep.b == initB); // expected-warning{{TRUE}} } struct strncatReportOutOfBoundTestClass { int *m_ptr; char m_buff[1000]; void KnownLen(char *src) { m_ptr = new int; // expected-warning@+1{{String concatenation function overflows the destination buffer}} strncat(m_buff, src, sizeof(m_buff)); // known len but unknown src size delete m_ptr; // no warning } }; void strncatReportOutOfBoundTest(char *src, size_t n) { strncatReportOutOfBoundTestClass rep; rep.KnownLen(src); } size_t strlcat(char *dst, const char *src, size_t size); struct strlcatTestClass: public Base { int *m_ptr; char m_buff[1000]; void KnownLen(char *src) { m_ptr = new int; strlcat(m_buff, src, sizeof(m_buff)); // known len but unknown src size delete m_ptr; // no warning } void KnownSrcLen(size_t n) { m_ptr = new int; strlcat(m_buff, "xyz", n); // known src size but unknown len delete m_ptr; // no warning } }; void strlcatTest(char *src, size_t n) { strlcatTestClass rep; rep.KnownLen(src); rep.KnownSrcLen(n); clang_analyzer_eval(rep.b == initB); // expected-warning{{TRUE}} }