summaryrefslogtreecommitdiffstats
path: root/unittests/Analysis/ExprMutationAnalyzerTest.cpp
diff options
context:
space:
mode:
authorJordan Rupprecht <[email protected]>2019-05-14 21:58:59 +0000
committerJordan Rupprecht <[email protected]>2019-05-14 21:58:59 +0000
commitb35a2aa71f76a334a9c98c0a3c3995b5d902d2b9 (patch)
treecdff4a5d1a715d4ad622fd8f190128b54bebe440 /unittests/Analysis/ExprMutationAnalyzerTest.cpp
parent3748d41833787fcbf59cc5624e8d2b042a8991bc (diff)
parent741e05796da92b46d4f7bcbee00702ff37df6489 (diff)
Creating branches/google/stable and tags/google/stable/2019-05-14 from r360103upstream/google/stable
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@360714 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Analysis/ExprMutationAnalyzerTest.cpp')
-rw-r--r--unittests/Analysis/ExprMutationAnalyzerTest.cpp157
1 files changed, 153 insertions, 4 deletions
diff --git a/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index 68c921e439..2c22a5cf9e 100644
--- a/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -1,9 +1,8 @@
//===---------- ExprMutationAnalyzerTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -882,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 =
@@ -1109,4 +1239,23 @@ TEST(ExprMutationAnalyzerTest, UniquePtr) {
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x->mf()"));
}
+TEST(ExprMutationAnalyzerTest, ReproduceFailureMinimal) {
+ const std::string Reproducer =
+ "namespace std {"
+ "template <class T> T forward(T & A) { return static_cast<T&&>(A); }"
+ "template <class T> struct __bind {"
+ " T f;"
+ " template <class V> __bind(T v, V &&) : f(forward(v)) {}"
+ "};"
+ "}"
+ "void f() {"
+ " int x = 42;"
+ " auto Lambda = [] {};"
+ " std::__bind<decltype(Lambda)>(Lambda, x);"
+ "}";
+ auto AST11 = buildASTFromCodeWithArgs(Reproducer, {"-std=c++11"});
+ auto Results11 =
+ match(withEnclosingCompound(declRefTo("x")), AST11->getASTContext());
+ EXPECT_FALSE(isMutated(Results11, AST11.get()));
+}
} // namespace clang