diff options
author | Petar Jovanovic <petar.jovanovic@mips.com> | 2019-03-07 15:50:52 +0000 |
---|---|---|
committer | Petar Jovanovic <petar.jovanovic@mips.com> | 2019-03-07 15:50:52 +0000 |
commit | 931a426f3341d5cdbb5f8c92f7d56f7647a013f8 (patch) | |
tree | 236f55310067dabae235bdc914e4e3d5deb84586 /unittests/Analysis | |
parent | 997080398003670def4126cfdec13a94c59af75c (diff) | |
download | clang-931a426f3341d5cdbb5f8c92f7d56f7647a013f8.tar.gz |
[analyzer] handle modification of vars inside an expr with comma operator
We should track mutation of a variable within a comma operator expression.
Current code in ExprMutationAnalyzer does not handle it.
This will handle cases like:
(a, b) ++ < == b is modified
(a, b) = c < == b is modifed
Patch by Djordje Todorovic.
Differential Revision: https://reviews.llvm.org/D58894
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355605 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Analysis')
-rw-r--r-- | unittests/Analysis/ExprMutationAnalyzerTest.cpp | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/unittests/Analysis/ExprMutationAnalyzerTest.cpp index 871c915149..c8ddc48fa7 100644 --- a/unittests/Analysis/ExprMutationAnalyzerTest.cpp +++ b/unittests/Analysis/ExprMutationAnalyzerTest.cpp @@ -881,6 +881,137 @@ TEST(ExprMutationAnalyzerTest, CastToConstRef) { EXPECT_FALSE(isMutated(Results, AST.get())); } +TEST(ExprMutationAnalyzerTest, CommaExprWithAnAssigment) { + const auto AST = + buildASTFromCodeWithArgs("void f() { int x; int y; (x, y) = 5; }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithDecOp) { + const auto AST = + buildASTFromCodeWithArgs("void f() { int x; int y; (x, y)++; }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithNonConstMemberCall) { + const auto AST = + buildASTFromCodeWithArgs("class A { public: int mem; void f() { mem ++; } };" + "void fn() { A o1, o2; (o1, o2).f(); }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("o2")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithConstMemberCall) { + const auto AST = + buildASTFromCodeWithArgs("class A { public: int mem; void f() const { } };" + "void fn() { A o1, o2; (o1, o2).f(); }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("o2")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithCallExpr) { + const auto AST = + buildASTFromCodeWithArgs("class A { public: int mem; void f(A &O1) {} };" + "void fn() { A o1, o2; o2.f((o2, o1)); }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithCallUnresolved) { + auto AST = buildASTFromCodeWithArgs( + "template <class T> struct S;" + "template <class T> void f() { S<T> s; int x, y; s.mf((y, x)); }", + {"-fno-delayed-template-parsing -Wno-unused-value"}); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); + + AST = buildASTFromCodeWithArgs( + "template <class T> void f(T t) { int x, y; g(t, (y, x)); }", + {"-fno-delayed-template-parsing -Wno-unused-value"}); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprParmRef) { + const auto AST = + buildASTFromCodeWithArgs("class A { public: int mem;};" + "extern void fn(A &o1);" + "void fn2 () { A o1, o2; fn((o2, o1)); } ", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprWithAmpersandOp) { + const auto AST = + buildASTFromCodeWithArgs("class A { public: int mem;};" + "void fn () { A o1, o2;" + "void *addr = &(o2, o1); } ", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprAsReturnAsValue) { + auto AST = buildASTFromCodeWithArgs("int f() { int x, y; return (x, y); }", + {"-Wno-unused-value"}); + auto Results = + match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); + EXPECT_FALSE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaEpxrAsReturnAsNonConstRef) { + const auto AST = + buildASTFromCodeWithArgs("int& f() { int x, y; return (y, x); }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprAsArrayToPointerDecay) { + const auto AST = + buildASTFromCodeWithArgs("void g(int*); " + "void f() { int x[2], y[2]; g((y, x)); }", + {"-Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + +TEST(ExprMutationAnalyzerTest, CommaExprAsUniquePtr) { + const std::string UniquePtrDef = + "template <class T> struct UniquePtr {" + " UniquePtr();" + " UniquePtr(const UniquePtr&) = delete;" + " T& operator*() const;" + " T* operator->() const;" + "};"; + const auto AST = buildASTFromCodeWithArgs( + UniquePtrDef + "template <class T> void f() " + "{ UniquePtr<T> x; UniquePtr<T> y;" + " (y, x)->mf(); }", + {"-fno-delayed-template-parsing -Wno-unused-value"}); + const auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isMutated(Results, AST.get())); +} + TEST(ExprMutationAnalyzerTest, LambdaDefaultCaptureByValue) { const auto AST = buildASTFromCode("void f() { int x; [=]() { x; }; }"); const auto Results = |