summaryrefslogtreecommitdiff
path: root/test/Analysis/cast-value-state-dump.cpp
diff options
context:
space:
mode:
authorCsaba Dabis <dabis.csaba98@gmail.com>2019-08-22 00:20:36 +0000
committerCsaba Dabis <dabis.csaba98@gmail.com>2019-08-22 00:20:36 +0000
commiteefe06446cf8fa6b98da049a67da4447bdc70ea9 (patch)
tree520afed5b1eb27dee4762234561a2d4c7fb2e14a /test/Analysis/cast-value-state-dump.cpp
parentb55c8505d68ca889a022da275aa53143917fea8a (diff)
downloadclang-eefe06446cf8fa6b98da049a67da4447bdc70ea9.tar.gz
[analyzer] CastValueChecker: Store the dynamic types and casts
Summary: This patch introduces `DynamicCastInfo` similar to `DynamicTypeInfo` which is stored in `CastSets` which are storing the dynamic cast informations of objects based on memory regions. It could be used to store and check the casts and prevent infeasible paths. Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D66325 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369605 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/cast-value-state-dump.cpp')
-rw-r--r--test/Analysis/cast-value-state-dump.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/test/Analysis/cast-value-state-dump.cpp b/test/Analysis/cast-value-state-dump.cpp
new file mode 100644
index 0000000000..fd679984d6
--- /dev/null
+++ b/test/Analysis/cast-value-state-dump.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=core,apiModeling.llvm.CastValue,debug.ExprInspection\
+// RUN: -analyzer-output=text -verify %s 2>&1 | FileCheck %s
+
+#include "Inputs/llvm.h"
+
+void clang_analyzer_printState();
+
+namespace clang {
+struct Shape {};
+class Triangle : public Shape {};
+class Circle : public Shape {};
+class Square : public Shape {};
+} // namespace clang
+
+using namespace llvm;
+using namespace clang;
+
+void evalNonNullParamNonNullReturnReference(const Shape &S) {
+ const auto *C = dyn_cast_or_null<Circle>(S);
+ // expected-note@-1 {{Assuming 'S' is a 'Circle'}}
+ // expected-note@-2 {{'C' initialized here}}
+
+ // FIXME: We assumed that 'S' is a 'Circle' therefore it is not a 'Square'.
+ if (dyn_cast_or_null<Square>(S)) {
+ // expected-note@-1 {{Assuming 'S' is not a 'Square'}}
+ // expected-note@-2 {{Taking false branch}}
+ return;
+ }
+
+ clang_analyzer_printState();
+
+ // CHECK: "dynamic_types": [
+ // CHECK-NEXT: { "region": "SymRegion{reg_$0<const struct clang::Shape & S>}", "dyn_type": "const class clang::Circle", "sub_classable": true }
+ // CHECK-NEXT: ],
+ // CHECK-NEXT: "dynamic_casts": [
+ // CHECK: { "region": "SymRegion{reg_$0<const struct clang::Shape & S>}", "casts": [
+ // CHECK-NEXT: { "from": "struct clang::Shape", "to": "class clang::Circle", "kind": "success" },
+ // CHECK-NEXT: { "from": "struct clang::Shape", "to": "class clang::Square", "kind": "fail" }
+ // CHECK-NEXT: ]}
+
+ (void)(1 / !C);
+ // expected-note@-1 {{'C' is non-null}}
+ // expected-note@-2 {{Division by zero}}
+ // expected-warning@-3 {{Division by zero}}
+}
+