xref: /llvm-project/clang/test/Analysis/std-string.cpp (revision c18407217e91abea73555e07956d7132dd093bd2)
1 // RUN: %clang_analyze_cc1 -std=c++14 %s -verify                  \
2 // RUN:   -analyzer-checker=core,unix.Malloc,debug.ExprInspection \
3 // RUN:   -analyzer-checker=cplusplus.StringChecker               \
4 // RUN:   -analyzer-config eagerly-assume=false                   \
5 // RUN:   -analyzer-output=text
6 
7 #include "Inputs/system-header-simulator-cxx.h"
8 
9 void clang_analyzer_eval(bool);
10 void clang_analyzer_warnIfReached();
11 template <typename T> void clang_analyzer_dump(T);
12 
13 void free(void *ptr);
14 
irrelevant_std_string_ctors(const char * p)15 void irrelevant_std_string_ctors(const char *p) {
16   std::string x1;                             // no-warning
17   std::string x2(2, 'x');                     // no-warning
18   std::string x3(x1, /*pos=*/2);              // no-warning
19   std::string x4(x1, /*pos=*/2, /*count=*/2); // no-warning
20   std::string x5(p, /*count=*/(size_t)2);     // no-warning
21   // skip std::string(const char*)
22   std::string x6(x1.begin(), x1.end()); // no-warning
23   std::string x7(x1);                   // no-warning
24   std::string x8(std::move(x1));        // no-warning
25   std::string x9({'a', 'b', '\0'});     // no-warning
26 }
27 
null_cstring_parameter(const char * p)28 void null_cstring_parameter(const char *p) {
29   clang_analyzer_eval(p == 0); // expected-warning {{UNKNOWN}} expected-note {{UNKNOWN}}
30   if (!p) {
31     // expected-note@-1 2 {{Assuming 'p' is null}}
32     // expected-note@-2 2 {{Taking true branch}}
33     clang_analyzer_eval(p == 0); // expected-warning {{TRUE}} expected-note {{TRUE}}
34     std::string x(p);
35     // expected-warning@-1 {{The parameter must not be null}}
36     // expected-note@-2    {{The parameter must not be null}}
37     clang_analyzer_warnIfReached(); // no-warning
38   }
39 }
40 
null_constant_parameter()41 void null_constant_parameter() {
42   std::string x((char *)0);
43   // expected-warning@-1 {{The parameter must not be null}}
44   // expected-note@-2    {{The parameter must not be null}}
45 }
46 
unknown_ctor_param(const char * p)47 void unknown_ctor_param(const char *p) {
48   // Pass 'UnknownVal' to the std::string constructor.
49   clang_analyzer_dump((char *)(p == 0)); // expected-warning {{Unknown}} expected-note {{Unknown}}
50   std::string x((char *)(p == 0));       // no-crash, no-warning
51 }
52 
ctor_notetag_on_constraining_symbol(const char * p)53 void ctor_notetag_on_constraining_symbol(const char *p) {
54   clang_analyzer_eval(p == 0); // expected-warning {{UNKNOWN}} expected-note {{UNKNOWN}}
55   std::string x(p);            // expected-note {{Assuming the pointer is not null}}
56   clang_analyzer_eval(p == 0); // expected-warning {{FALSE}} expected-note {{FALSE}}
57 
58   free((void *)p); // expected-note {{Memory is released}}
59   free((void *)p);
60   // expected-warning@-1 {{Attempt to free released memory}}
61   // expected-note@-2    {{Attempt to free released memory}}
62 }
63 
ctor_no_notetag_symbol_already_constrained(const char * p)64 void ctor_no_notetag_symbol_already_constrained(const char *p) {
65   // expected-note@+2 + {{Assuming 'p' is non-null}}
66   // expected-note@+1 + {{Taking false branch}}
67   if (!p)
68     return;
69 
70   clang_analyzer_eval(p == 0); // expected-warning {{FALSE}} expected-note {{FALSE}}
71   std::string x(p);            // no-note: 'p' is already constrained to be non-null.
72   clang_analyzer_eval(p == 0); // expected-warning {{FALSE}} expected-note {{FALSE}}
73 
74   free((void *)p); // expected-note {{Memory is released}}
75   free((void *)p);
76   // expected-warning@-1 {{Attempt to free released memory}}
77   // expected-note@-2    {{Attempt to free released memory}}
78 }
79 
ctor_no_notetag_if_not_interesting(const char * p1,const char * p2)80 void ctor_no_notetag_if_not_interesting(const char *p1, const char *p2) {
81   std::string s1(p1); // expected-note {{Assuming the pointer is not null}}
82   std::string s2(p2); // no-note: s2 is not interesting
83 
84   free((void *)p1); // expected-note {{Memory is released}}
85   free((void *)p1);
86   // expected-warning@-1 {{Attempt to free released memory}}
87   // expected-note@-2    {{Attempt to free released memory}}
88 }
89