aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/casts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/casts.cpp')
-rw-r--r--test/Analysis/casts.cpp75
1 files changed, 74 insertions, 1 deletions
diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp
index 757eb6da6623..aa2bd9c1fadc 100644
--- a/test/Analysis/casts.cpp
+++ b/test/Analysis/casts.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(bool);
bool PR14634(int x) {
double y = (double)x;
@@ -41,3 +43,74 @@ bool retrievePointerFromBoolean(int *p) {
*reinterpret_cast<int **>(&q) = p;
return q;
}
+
+namespace base_to_derived {
+struct A {};
+struct B : public A{};
+
+void foo(A* a) {
+ B* b = (B* ) a;
+ A* a2 = (A *) b;
+ clang_analyzer_eval(a2 == a); // expected-warning{{TRUE}}
+}
+}
+
+namespace base_to_derived_double_inheritance {
+struct A {
+ int x;
+};
+struct B {
+ int y;
+};
+struct C : A, B {};
+
+void foo(B *b) {
+ C *c = (C *)b;
+ b->y = 1;
+ clang_analyzer_eval(c->x); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c->y); // expected-warning{{TRUE}}
+}
+} // namespace base_to_derived_double_inheritance
+
+namespace base_to_derived_opaque_class {
+class NotInt {
+public:
+ operator int() { return !x; } // no-crash
+ int x;
+};
+
+typedef struct Opaque *OpaqueRef;
+typedef void *VeryOpaqueRef;
+
+class Transparent {
+public:
+ int getNotInt() { return NI; }
+ NotInt NI;
+};
+
+class SubTransparent : public Transparent {};
+
+SubTransparent *castToDerived(Transparent *TRef) {
+ return (SubTransparent *)TRef;
+}
+
+void foo(OpaqueRef ORef) {
+ castToDerived(reinterpret_cast<Transparent *>(ORef))->getNotInt();
+}
+
+void foo(VeryOpaqueRef ORef) {
+ castToDerived(reinterpret_cast<Transparent *>(ORef))->getNotInt();
+}
+} // namespace base_to_derived_opaque_class
+
+namespace bool_to_nullptr {
+struct S {
+ int *a[1];
+ bool b;
+};
+void foo(S s) {
+ s.b = true;
+ for (int i = 0; i < 2; ++i)
+ (void)(s.a[i] != nullptr); // no-crash
+}
+} // namespace bool_to_nullptr