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
7 #include "Inputs/system-header-simulator-cxx.h"
9 void clang_analyzer_eval(bool);
10 void clang_analyzer_warnIfReached();
11 template <typename T
> void clang_analyzer_dump(T
);
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
28 void null_cstring_parameter(const char *p
) {
29 clang_analyzer_eval(p
== 0); // expected-warning {{UNKNOWN}} expected-note {{UNKNOWN}}
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}}
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
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}}
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
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}}
58 free((void *)p
); // expected-note {{Memory is released}}
60 // expected-warning@-1 {{Attempt to free released memory}}
61 // expected-note@-2 {{Attempt to free released memory}}
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}}
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}}
74 free((void *)p
); // expected-note {{Memory is released}}
76 // expected-warning@-1 {{Attempt to free released memory}}
77 // expected-note@-2 {{Attempt to free released memory}}
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
84 free((void *)p1
); // expected-note {{Memory is released}}
86 // expected-warning@-1 {{Attempt to free released memory}}
87 // expected-note@-2 {{Attempt to free released memory}}