summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorShuai Wang <shuaiwang@google.com>2018-09-19 18:00:55 +0000
committerShuai Wang <shuaiwang@google.com>2018-09-19 18:00:55 +0000
commit86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee (patch)
tree3680dc59a119ff4c387bcb3ee1cfdff3f52827dc /clang
parentc33b2e6d0f84125c77fad2fe715f9c4a35ad19de (diff)
downloadbcm5719-llvm-86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee.tar.gz
bcm5719-llvm-86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee.zip
[analyzer] Fix nullptr access when processing instantiated function in ExprMutationAnalyzer.
llvm-svn: 342562
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/ExprMutationAnalyzer.cpp2
-rw-r--r--clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp30
2 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index db8c259a52a..8414cb5c726 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -379,7 +379,7 @@ const Stmt *ExprMutationAnalyzer::findFunctionArgMutation(const Expr *Exp) {
for (const auto &Nodes : Matches) {
const auto *Exp = Nodes.getNodeAs<Expr>(NodeID<Expr>::value);
const auto *Func = Nodes.getNodeAs<FunctionDecl>("func");
- if (!Func->getBody())
+ if (!Func->getBody() || !Func->getPrimaryTemplate())
return Exp;
const auto *Parm = Nodes.getNodeAs<ParmVarDecl>("parm");
diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index 30950e0dd60..8823ac803e3 100644
--- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -215,6 +215,12 @@ TEST(ExprMutationAnalyzerTest, ByValueArgument) {
"void f() { A x, y; y = x; }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_FALSE(isMutated(Results, AST.get()));
+
+ AST = buildASTFromCode(
+ "template <int> struct A { A(); A(const A&); static void mf(A) {} };"
+ "void f() { A<0> x; A<0>::mf(x); }");
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_FALSE(isMutated(Results, AST.get()));
}
TEST(ExprMutationAnalyzerTest, ByConstValueArgument) {
@@ -241,6 +247,12 @@ TEST(ExprMutationAnalyzerTest, ByConstValueArgument) {
"void f() { struct A { A(const int); }; int x; A y(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_FALSE(isMutated(Results, AST.get()));
+
+ AST = buildASTFromCode("template <int> struct A { A(); A(const A&);"
+ "static void mf(const A&) {} };"
+ "void f() { A<0> x; A<0>::mf(x); }");
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_FALSE(isMutated(Results, AST.get()));
}
TEST(ExprMutationAnalyzerTest, ByNonConstRefArgument) {
@@ -288,6 +300,12 @@ TEST(ExprMutationAnalyzerTest, ByNonConstRefArgument) {
AST = buildASTFromCode("void f() { struct A { A(); A(A&); }; A x; A y(x); }");
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x"));
+
+ AST = buildASTFromCode(
+ "template <int> struct A { A(); A(const A&); static void mf(A&) {} };"
+ "void f() { A<0> x; A<0>::mf(x); }");
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("A<0>::mf(x)"));
}
TEST(ExprMutationAnalyzerTest, ByConstRefArgument) {
@@ -686,6 +704,12 @@ TEST(ExprMutationAnalyzerTest, FollowFuncArgModified) {
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x"));
+ AST = buildASTFromCode("template <class U> struct S {"
+ "template <class T> S(T&& t) : m(++t) { } U m; };"
+ "void f() { int x; S<int> s(x); }");
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x"));
+
AST = buildASTFromCode(StdRemoveReference + StdForward +
"template <class... Args> void u(Args&...);"
"template <class... Args> void h(Args&&... args)"
@@ -737,6 +761,12 @@ TEST(ExprMutationAnalyzerTest, FollowFuncArgNotModified) {
Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_FALSE(isMutated(Results, AST.get()));
+ AST = buildASTFromCode("template <class U> struct S {"
+ "template <class T> S(T&& t) : m(t) { } U m; };"
+ "void f() { int x; S<int> s(x); }");
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_FALSE(isMutated(Results, AST.get()));
+
AST = buildASTFromCode(StdRemoveReference + StdForward +
"template <class... Args> void u(Args...);"
"template <class... Args> void h(Args&&... args)"
OpenPOWER on IntegriCloud