Index: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp +++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp @@ -145,16 +145,11 @@ hasUnaryOperand(equalsNode(Exp))); // Invoking non-const member function. - // A member function is assumed to be non-const when it is unresolved. const auto NonConstMethod = cxxMethodDecl(unless(isConst())); const auto AsNonConstThis = expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod), on(equalsNode(Exp))), cxxOperatorCallExpr(callee(NonConstMethod), - hasArgument(0, equalsNode(Exp))), - callExpr(callee(expr(anyOf( - unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))), - cxxDependentScopeMemberExpr( - hasObjectExpression(equalsNode(Exp))))))))); + hasArgument(0, equalsNode(Exp))))); // Taking address of 'Exp'. // We're assuming 'Exp' is mutated as soon as its address is taken, though in @@ -170,16 +165,10 @@ unless(hasParent(arraySubscriptExpr())), has(equalsNode(Exp))); // Used as non-const-ref argument when calling a function. - // An argument is assumed to be non-const-ref when the function is unresolved. const auto NonConstRefParam = forEachArgumentWithParam( equalsNode(Exp), parmVarDecl(hasType(nonConstReferenceType()))); - const auto AsNonConstRefArg = anyOf( - callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam), - callExpr(callee(expr(anyOf(unresolvedLookupExpr(), unresolvedMemberExpr(), - cxxDependentScopeMemberExpr(), - hasType(templateTypeParmType())))), - hasAnyArgument(equalsNode(Exp))), - cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp)))); + const auto AsNonConstRefArg = + anyOf(callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam)); // Captured by a lambda by reference. // If we're initializing a capture with 'Exp' directly then we're initializing @@ -206,12 +195,9 @@ const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) { // Check whether any member of 'Exp' is mutated. - const auto MemberExprs = - match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))), - cxxDependentScopeMemberExpr( - hasObjectExpression(equalsNode(Exp))))) - .bind("expr")), - Stm, Context); + const auto MemberExprs = match( + findAll(memberExpr(hasObjectExpression(equalsNode(Exp))).bind("expr")), + Stm, Context); return findExprMutation(MemberExprs); } Index: clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp +++ clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp @@ -114,26 +114,6 @@ EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()")); } -TEST(ExprMutationAnalyzerTest, AssumedNonConstMemberFunc) { - auto AST = tooling::buildASTFromCode( - "struct X { template void mf(); };" - "template void f() { X x; x.mf(); }"); - auto Results = - match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()")); - - AST = - tooling::buildASTFromCode("template void f() { T x; x.mf(); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()")); - - AST = tooling::buildASTFromCode( - "template struct X;" - "template void f() { X x; x.mf(); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()")); -} - TEST(ExprMutationAnalyzerTest, ConstMemberFunc) { const auto AST = tooling::buildASTFromCode( "void f() { struct Foo { void mf() const; }; Foo x; x.mf(); }"); @@ -312,51 +292,6 @@ ElementsAre("std::forward(x)")); } -TEST(ExprMutationAnalyzerTest, CallUnresolved) { - auto AST = - tooling::buildASTFromCode("template void f() { T x; g(x); }"); - auto Results = - match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)")); - - AST = tooling::buildASTFromCode( - "template void f() { char x[N]; g(x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)")); - - AST = tooling::buildASTFromCode( - "template void f(T t) { int x; g(t, x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(t, x)")); - - AST = tooling::buildASTFromCode( - "template void f(T t) { int x; t.mf(x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("t.mf(x)")); - - AST = tooling::buildASTFromCode( - "template struct S;" - "template void f() { S s; int x; s.mf(x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("s.mf(x)")); - - AST = tooling::buildASTFromCode( - "struct S { template void mf(); };" - "template void f(S s) { int x; s.mf(x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("s.mf(x)")); - - AST = tooling::buildASTFromCode("template " - "void g(F f) { int x; f(x); } "); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("f(x)")); - - AST = tooling::buildASTFromCode( - "template void f() { int x; (void)T(x); }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("T(x)")); -} - TEST(ExprMutationAnalyzerTest, ReturnAsValue) { const auto AST = tooling::buildASTFromCode("int f() { int x; return x; }"); const auto Results = @@ -412,21 +347,6 @@ EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x")); } -TEST(ExprMutationAnalyzerTest, TemplateWithArrayToPointerDecay) { - const auto AST = tooling::buildASTFromCode( - "template struct S { static constexpr int v = 8; };" - "template <> struct S { static constexpr int v = 4; };" - "void g(char*);" - "template void f() { char x[S::v]; g(x); }" - "template <> void f() { char y[S::v]; g(y); }"); - const auto ResultsX = - match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(ResultsX, AST.get()), ElementsAre("g(x)")); - const auto ResultsY = - match(withEnclosingCompound(declRefTo("y")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(ResultsY, AST.get()), ElementsAre("y")); -} - TEST(ExprMutationAnalyzerTest, FollowRefModified) { const auto AST = tooling::buildASTFromCode( "void f() { int x; int& r0 = x; int& r1 = r0; int& r2 = r1; " @@ -478,43 +398,21 @@ } TEST(ExprMutationAnalyzerTest, NestedMemberModified) { - auto AST = tooling::buildASTFromCode( + const auto AST = tooling::buildASTFromCode( "void f() { struct A { int vi; }; struct B { A va; }; " "struct C { B vb; }; C x; x.vb.va.vi = 10; }"); - auto Results = + const auto Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.vb.va.vi = 10")); - - AST = tooling::buildASTFromCode( - "template void f() { T x; x.y.z = 10; }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.y.z = 10")); - - AST = tooling::buildASTFromCode( - "template struct S;" - "template void f() { S x; x.y.z = 10; }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.y.z = 10")); } TEST(ExprMutationAnalyzerTest, NestedMemberNotModified) { - auto AST = tooling::buildASTFromCode( + const auto AST = tooling::buildASTFromCode( "void f() { struct A { int vi; }; struct B { A va; }; " "struct C { B vb; }; C x; x.vb.va.vi; }"); - auto Results = + const auto Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); EXPECT_FALSE(isMutated(Results, AST.get())); - - AST = - tooling::buildASTFromCode("template void f() { T x; x.y.z; }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_FALSE(isMutated(Results, AST.get())); - - AST = tooling::buildASTFromCode( - "template struct S;" - "template void f() { S x; x.y.z; }"); - Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); - EXPECT_FALSE(isMutated(Results, AST.get())); } TEST(ExprMutationAnalyzerTest, CastToValue) {