diff options
Diffstat (limited to 'clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp')
| -rw-r--r-- | clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp index f8b70565dc7..318fb0d82ae 100644 --- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp +++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp @@ -595,6 +595,96 @@ TEST(ExprMutationAnalyzerTest, FollowConditionalRefNotModified) { EXPECT_FALSE(isMutated(Results, AST.get())); } +TEST(ExprMutationAnalyzerTest, FollowFuncArgModified) { + auto AST = + tooling::buildASTFromCode("template <class T> void g(T&& t) { t = 10; }" + "void f() { int x; g(x); }"); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)")); + + AST = tooling::buildASTFromCode( + "void h(int&);" + "template <class... Args> void g(Args&&... args) { h(args...); }" + "void f() { int x; g(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)")); + + AST = tooling::buildASTFromCode( + "void h(int&, int);" + "template <class... Args> void g(Args&&... args) { h(args...); }" + "void f() { int x, y; g(x, y); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x, y)")); + Results = match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode( + "void h(int, int&);" + "template <class... Args> void g(Args&&... args) { h(args...); }" + "void f() { int x, y; g(y, x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(y, x)")); + Results = match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode( + "struct S { template <class T> S(T&& t) { t = 10; } };" + "void f() { int x; S s(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x")); + + AST = tooling::buildASTFromCode( + "struct S { template <class T> S(T&& t) : m(++t) { } int m; };" + "void f() { int x; S s(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x")); +} + +TEST(ExprMutationAnalyzerTest, FollowFuncArgNotModified) { + auto AST = tooling::buildASTFromCode("template <class T> void g(T&&) {}" + "void f() { int x; g(x); }"); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode("template <class T> void g(T&& t) { t; }" + "void f() { int x; g(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = + tooling::buildASTFromCode("template <class... Args> void g(Args&&...) {}" + "void f() { int x; g(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = + tooling::buildASTFromCode("template <class... Args> void g(Args&&...) {}" + "void f() { int y, x; g(y, x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode( + "void h(int, int&);" + "template <class... Args> void g(Args&&... args) { h(args...); }" + "void f() { int x, y; g(x, y); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode( + "struct S { template <class T> S(T&& t) { t; } };" + "void f() { int x; S s(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); + + AST = tooling::buildASTFromCode( + "struct S { template <class T> S(T&& t) : m(t) { } int m; };" + "void f() { int x; S s(x); }"); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); +} + TEST(ExprMutationAnalyzerTest, ArrayElementModified) { const auto AST = tooling::buildASTFromCode("void f() { int x[2]; x[0] = 10; }"); |

