1 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
2 // RUN: -analyzer-checker=core,debug.ExprInspection
3
4 template <typename T> void clang_analyzer_dump(T);
5 using size_t = decltype(sizeof(int));
6
_castf32_u32(float __A)7 __attribute__((always_inline)) static inline constexpr unsigned int _castf32_u32(float __A) {
8 return __builtin_bit_cast(unsigned int, __A); // no-warning
9 }
10
test(int i)11 void test(int i) {
12 _castf32_u32(42);
13
14 float f = 42;
15
16 // Loading from a floating point value results in unknown,
17 // which later materializes as a conjured value.
18 auto g = __builtin_bit_cast(unsigned int, f);
19 clang_analyzer_dump(g);
20 // expected-warning-re@-1 {{{{^conj_\$[0-9]+{unsigned int,}}}}
21
22 auto g2 = __builtin_bit_cast(unsigned int, 42.0f);
23 clang_analyzer_dump(g2);
24 // expected-warning-re@-1 {{{{^conj_\$[0-9]+{unsigned int,}}}}
25
26 auto g3 = __builtin_bit_cast(unsigned int, i);
27 clang_analyzer_dump(g3);
28 // expected-warning-re@-1 {{{{^reg_\$[0-9]+<int i>}}}}
29
30 auto g4 = __builtin_bit_cast(unsigned long, &i);
31 clang_analyzer_dump(g4);
32 // expected-warning@-1 {{&i [as 64 bit integer]}}
33 }
34
35 struct A {
36 int n;
setA37 void set(int x) {
38 n = x;
39 }
40 };
gh_69922(size_t p)41 void gh_69922(size_t p) {
42 // expected-warning-re@+1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
43 clang_analyzer_dump(__builtin_bit_cast(A*, p & 1));
44
45 __builtin_bit_cast(A*, p & 1)->set(2); // no-crash
46 // However, since the `this` pointer is expected to be a Loc, but we have
47 // NonLoc there, we simply give up and resolve it as `Unknown`.
48 // Then, inside the `set()` member function call we can't evaluate the
49 // store to the member variable `n`.
50
51 clang_analyzer_dump(__builtin_bit_cast(A*, p & 1)->n); // Ideally, this should print "2".
52 // expected-warning-re@-1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
53 }
54