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