diff options
| author | Shuai Wang <shuaiwang@google.com> | 2018-09-19 18:00:55 +0000 |
|---|---|---|
| committer | Shuai Wang <shuaiwang@google.com> | 2018-09-19 18:00:55 +0000 |
| commit | 86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee (patch) | |
| tree | 3680dc59a119ff4c387bcb3ee1cfdff3f52827dc | |
| parent | c33b2e6d0f84125c77fad2fe715f9c4a35ad19de (diff) | |
| download | bcm5719-llvm-86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee.tar.gz bcm5719-llvm-86e5cb0e0bc938c9cf44d91eeffdce31ab5cb3ee.zip | |
[analyzer] Fix nullptr access when processing instantiated function in ExprMutationAnalyzer.
llvm-svn: 342562
| -rw-r--r-- | clang/lib/Analysis/ExprMutationAnalyzer.cpp | 2 | ||||
| -rw-r--r-- | clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp | 30 |
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)" |

