summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Analysis/CFG.h1
-rw-r--r--clang/lib/Analysis/CFG.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp6
-rw-r--r--clang/test/Analysis/designated-initializer-values.c38
-rw-r--r--clang/test/Analysis/designated-initializer.c13
-rw-r--r--clang/test/Analysis/initializers-cfg-output.cpp15
-rw-r--r--clang/test/Analysis/temp-obj-dtors-cfg-output.cpp3
8 files changed, 64 insertions, 18 deletions
diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h
index a8301a0e006..ea3d8b2921a 100644
--- a/clang/include/clang/Analysis/CFG.h
+++ b/clang/include/clang/Analysis/CFG.h
@@ -1251,6 +1251,7 @@ public:
bool AddRichCXXConstructors = false;
bool MarkElidedCXXConstructors = false;
bool AddVirtualBaseBranches = false;
+ bool OmitImplicitValueInitializers = false;
BuildOptions() = default;
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index bc21d1c9076..e10bfd80593 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -2135,6 +2135,11 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc,
default:
return VisitStmt(S, asc);
+ case Stmt::ImplicitValueInitExprClass:
+ if (BuildOpts.OmitImplicitValueInitializers)
+ return Block;
+ return VisitStmt(S, asc);
+
case Stmt::AddrLabelExprClass:
return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc);
diff --git a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 73e1a0d0000..94fc09e64aa 100644
--- a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -43,6 +43,7 @@ AnalysisManager::AnalysisManager(ASTContext &ASTCtx,
CreateConstraintMgr(constraintmgr), CheckerMgr(checkerMgr),
options(Options) {
AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
+ AnaCtxMgr.getCFGBuildOptions().OmitImplicitValueInitializers = true;
}
AnalysisManager::~AnalysisManager() {
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 2a23d1cae7b..f917a4c8637 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1321,6 +1321,11 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::WhileStmtClass:
case Expr::MSDependentExistsStmtClass:
llvm_unreachable("Stmt should not be in analyzer evaluation loop");
+ case Stmt::ImplicitValueInitExprClass:
+ // These nodes are shared in the CFG and would case caching out.
+ // Moreover, no additional evaluation required for them, the
+ // analyzer can reconstruct these values from the AST.
+ llvm_unreachable("Should be pruned from CFG");
case Stmt::ObjCSubscriptRefExprClass:
case Stmt::ObjCPropertyRefExprClass:
@@ -1391,7 +1396,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::IntegerLiteralClass:
case Stmt::FixedPointLiteralClass:
case Stmt::CharacterLiteralClass:
- case Stmt::ImplicitValueInitExprClass:
case Stmt::CXXScalarValueInitExprClass:
case Stmt::CXXBoolLiteralExprClass:
case Stmt::ObjCBoolLiteralExprClass:
diff --git a/clang/test/Analysis/designated-initializer-values.c b/clang/test/Analysis/designated-initializer-values.c
new file mode 100644
index 00000000000..1efc10aece6
--- /dev/null
+++ b/clang/test/Analysis/designated-initializer-values.c
@@ -0,0 +1,38 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c99 -verify %s
+
+void clang_analyzer_eval(int);
+
+void array_init() {
+ int a[5] = {[4] = 29, [2] = 15, [0] = 4};
+ clang_analyzer_eval(a[0] == 4); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a[1] == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a[2] == 15); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a[3] == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a[4] == 29); // expected-warning{{TRUE}}
+ int b[5] = {[0 ... 2] = 1, [4] = 5};
+ clang_analyzer_eval(b[0] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b[1] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b[2] == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b[3] == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b[4] == 5); // expected-warning{{TRUE}}
+}
+
+struct point {
+ int x, y;
+};
+
+void struct_init() {
+ struct point p = {.y = 5, .x = 3};
+ clang_analyzer_eval(p.x == 3); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p.y == 5); // expected-warning{{TRUE}}
+}
+
+void array_of_struct() {
+ struct point ptarray[3] = { [2].y = 1, [2].x = 2, [0].x = 3 };
+ clang_analyzer_eval(ptarray[0].x == 3); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ptarray[0].y == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ptarray[1].x == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ptarray[1].y == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ptarray[2].x == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ptarray[2].y == 1); // expected-warning{{TRUE}}
+}
diff --git a/clang/test/Analysis/designated-initializer.c b/clang/test/Analysis/designated-initializer.c
index 920b2f08d7e..adca0ab6c87 100644
--- a/clang/test/Analysis/designated-initializer.c
+++ b/clang/test/Analysis/designated-initializer.c
@@ -31,11 +31,10 @@ void test() {
// CHECK: 11: struct LUQ var = {getUQ(), .uq.q.a = 100};
// CHECK: 12: 1
// CHECK: 13: 2
-// CHECK: 14: /*implicit*/(int)0
-// CHECK: 15: {[B1.12], [B1.13]}
+// CHECK: 14: {[B1.12], [B1.13]}
+// CHECK: 17: /*no init*/
// CHECK: 18: /*no init*/
-// CHECK: 19: /*no init*/
-// CHECK: 20: 3
-// CHECK: 21: {[B1.18], [B1.19], [B1.20]}
-// CHECK: 22: {/*base*/[B1.17], /*updater*/[B1.21]}
-// CHECK: 24: struct Q s[] = {[0] = (struct Q){1, 2}, [0].c = 3};
+// CHECK: 19: 3
+// CHECK: 20: {[B1.17], [B1.18], [B1.19]}
+// CHECK: 21: {/*base*/[B1.16], /*updater*/[B1.20]}
+// CHECK: 23: struct Q s[] = {[0] = (struct Q){1, 2}, [0].c = 3};
diff --git a/clang/test/Analysis/initializers-cfg-output.cpp b/clang/test/Analysis/initializers-cfg-output.cpp
index f8338649265..14c1b1e99a4 100644
--- a/clang/test/Analysis/initializers-cfg-output.cpp
+++ b/clang/test/Analysis/initializers-cfg-output.cpp
@@ -126,14 +126,13 @@ public:
// WARNINGS-NEXT: 5: (CXXConstructExpr, class A)
// ANALYZER-NEXT: 5: (CXXConstructExpr, A() (Base initializer), class A)
// CHECK-NEXT: 6: A([B1.5]) (Base initializer)
-// CHECK-NEXT: 7: /*implicit*/(int)0
-// CHECK-NEXT: 8: i([B1.7]) (Member initializer)
-// CHECK-NEXT: 9: this
-// CHECK-NEXT: 10: [B1.9]->i
-// CHECK-NEXT: 11: r([B1.10]) (Member initializer)
-// WARNINGS-NEXT: 12: (CXXConstructExpr, class A)
-// ANALYZER-NEXT: 12: (CXXConstructExpr, [B1.13], class A)
-// CHECK-NEXT: 13: A a;
+// CHECK-NEXT: 7: i(/*implicit*/(int)0) (Member initializer)
+// CHECK-NEXT: 8: this
+// CHECK-NEXT: 9: [B1.8]->i
+// CHECK-NEXT: 10: r([B1.9]) (Member initializer)
+// WARNINGS-NEXT: 11: (CXXConstructExpr, class A)
+// ANALYZER-NEXT: 11: (CXXConstructExpr, [B1.12], class A)
+// CHECK-NEXT: 12: A a;
// CHECK-NEXT: Preds (2): B2 B3
// CHECK-NEXT: Succs (1): B0
// CHECK: [B2]
diff --git a/clang/test/Analysis/temp-obj-dtors-cfg-output.cpp b/clang/test/Analysis/temp-obj-dtors-cfg-output.cpp
index d08b01cd396..5b16915ae6f 100644
--- a/clang/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/clang/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1224,8 +1224,7 @@ const C &bar3(bool coin) {
// CHECK: 16: a([B1.15]) (Member initializer)
// CHECK: 17: ~B() (Temporary object destructor)
// CHECK: 18: ~A() (Temporary object destructor)
-// CHECK: 19: /*implicit*/(int)0
-// CHECK: 20: b([B1.19]) (Member initializer)
+// CHECK: 19: b(/*implicit*/(int)0) (Member initializer)
// CHECK: Preds (1): B2
// CHECK: Succs (1): B0
// CHECK: [B0 (EXIT)]
OpenPOWER on IntegriCloud