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