Re: r342827 - Fix modules build with shared library.

2018-11-06 Thread Shuai Wang via cfe-commits
Sorry for the unresponsiveness, I've been fire fighting for other stuffs.
I'll look into this and try to get it fixed this week.

On Tue, Nov 6, 2018 at 9:52 AM David Blaikie  wrote:

> Shuai - have you had a chance to look at this?
>
> On Mon, Oct 22, 2018 at 4:43 PM Richard Smith 
> wrote:
>
>> On Mon, 22 Oct 2018 at 14:57, David Blaikie via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Richard - any further thoughts here (re: layering/dependencies, etc)?
>>> Would love to get the layering oddity fixed rather than having it get more
>>> embedded over time.
>>>
>>
>> Here's the intended current directory layout and layering as I understand
>> it:
>>
>>  * include/clang/Analysis and lib/Analysis are the parts of the static
>> analysis engine that are depended on by both Sema and StaticAnalyzer, and
>> include common functionality / infrastructure
>>  * include/clang/Analysis/Analyses and lib/Analysis/Analyses are the
>> specific Sema analyses (that don't depend on the static analyzer);
>> StaticAnalyzer should not need to depend on this
>>  * the StaticAnalyzer library should contain all the pieces that are
>> specific to the static analyzer
>>  * Sema should not depend on Tooling, but it's fine for StaticAnalyzer to
>> depend on Tooling
>>
>> Compared to where we are today, there are two differences:
>>
>> 1) The implementations of the headers in include/clang/Analysis are in
>> lib/Analysis, not in lib/Analysis/Analyses
>> 2) ExprMutationAnalyzer is in lib/Analysis despite not being part of the
>> common infrastructure depended on by Sema and StaticAnalyzer
>>
>> For point 1, we should change the lib/Analysis directory layout to match
>> the headers.
>> For point 2, we should find a home for this ExprMutationAnalyzer code
>> that makes sense. Given that the intent is to use it from the static
>> analyzer, that seems like a reasonable home for it, but libTooling would
>> also make some sense (perhaps a new subdirectory Tooling/Analysis), since
>> it's only performing AST matching, not a flow-sensitive / path-sensitive
>> static analysis.
>>
>> On Tue, Oct 2, 2018 at 2:44 PM Shuai Wang via cfe-commits <
>>> cfe-commits@lists.llvm.org> wrote:
>>>
>>>> On Mon, Oct 1, 2018 at 4:58 PM Richard Smith 
>>>> wrote:
>>>>
>>>>> On Mon, 1 Oct 2018 at 16:10, George Karpenkov via cfe-commits <
>>>>> cfe-commits@lists.llvm.org> wrote:
>>>>>
>>>>>> Hi Richard,
>>>>>>
>>>>>> On Oct 1, 2018, at 2:50 PM, Richard Smith via cfe-commits <
>>>>>> cfe-commits@lists.llvm.org> wrote:
>>>>>>
>>>>>> This looks like the wrong fix to me, but I don't really know enough
>>>>>> about what's being done with ExprMutationAnalyzer to have an opinion on
>>>>>> what the right fix is.
>>>>>>
>>>>>> Shuai, what is the goal here? Why is this code being moved to
>>>>>> Analysis/?
>>>>>>
>>>>>>
>>>>>> I’ve asked for this possibility, as I wanted to use it from the Clang
>>>>>> static analyzer.
>>>>>>
>>>>>> Do you intend to call it from the compiler frontend at some point? I
>>>>>> can see a code review for the move itself, but no discussion of a plan or
>>>>>> overall direction being followed here. Did I miss it?
>>>>>>
>>>>>> We have historically decided to not use the tooling interfaces
>>>>>> (ASTMatcher, ParentMap, etc) from the frontend,
>>>>>>
>>>>>>
>>>>>> Clang analyzer uses ASTMatcher all over the place.
>>>>>>
>>>>>> because they're generally a poor fit for our goals (we aim for a
>>>>>> largely-single-pass compilation with good locality, and the AST matchers
>>>>>> make different design choices)
>>>>>>
>>>>>>
>>>>>> That’s totally good for the analyzer though, right?
>>>>>>
>>>>>
>>>>> Yes, that all seems fine for the static analyzer.
>>>>>
>>>>>
>>>>>> In any case, in future it might make sense to move the analyzer out
>>>>>> of Clang proper.
>>>>>> But for know the only way to use clang-tidy utilities from the
>>>>>> analyzer is to 

Re: r342827 - Fix modules build with shared library.

2018-10-02 Thread Shuai Wang via cfe-commits
On Mon, Oct 1, 2018 at 4:58 PM Richard Smith  wrote:

> On Mon, 1 Oct 2018 at 16:10, George Karpenkov via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Hi Richard,
>>
>> On Oct 1, 2018, at 2:50 PM, Richard Smith via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>> This looks like the wrong fix to me, but I don't really know enough about
>> what's being done with ExprMutationAnalyzer to have an opinion on what the
>> right fix is.
>>
>> Shuai, what is the goal here? Why is this code being moved to Analysis/?
>>
>>
>> I’ve asked for this possibility, as I wanted to use it from the Clang
>> static analyzer.
>>
>> Do you intend to call it from the compiler frontend at some point? I can
>> see a code review for the move itself, but no discussion of a plan or
>> overall direction being followed here. Did I miss it?
>>
>> We have historically decided to not use the tooling interfaces
>> (ASTMatcher, ParentMap, etc) from the frontend,
>>
>>
>> Clang analyzer uses ASTMatcher all over the place.
>>
>> because they're generally a poor fit for our goals (we aim for a
>> largely-single-pass compilation with good locality, and the AST matchers
>> make different design choices)
>>
>>
>> That’s totally good for the analyzer though, right?
>>
>
> Yes, that all seems fine for the static analyzer.
>
>
>> In any case, in future it might make sense to move the analyzer out of
>> Clang proper.
>> But for know the only way to use clang-tidy utilities from the analyzer
>> is to move them into Clang.
>>
>
> Right. I think we should try to maintain the idea that all the Clang
> Static Analyzer-specific things are in lib/StaticAnalyzer, and lib/Analysis
> only contains things depended on by the frontend. (That is: the things a
> clang binary would use if we didn't link in the static analyzer)
>
> Given the above, I think the best approach would be to move this code out
> of lib/Analysis and into somewhere in lib/StaticAnalyzer. There shouldn't
> be any problem with clang-tidy using it from there, since it already
> depends on the static analyzer.
>
I'm happy to do the move.
Could you (or someone) help point out where exactly I should move it to
though?

> . If you want to change that, we'll need to discuss that decision.
>>
>> If the idea is to move this code into clang proper so that it can be used
>> by various different tooling clients, we'd need to discuss the right place
>> for it. Perhaps lib/Tooling/Analysis would make sense?
>>
>>
>> On Mon, 1 Oct 2018 at 13:13, David Blaikie via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> I can't really reproduce this - when I try to build clang/llvm with
>>> LLVM_ENABLE_MODULES in CMake I'm still seeing an error I reported March on
>>> a cfe-dev thread - something to do with unique_ptr instantiations for
>>> MappedBlockStream in the PDB parsing code.
>>>
>>> So, I'm wondering what error you hit, Eric/where/how, etc...
>>>
>>> On Sun, Sep 30, 2018 at 10:23 AM Eric Fiselier  wrote:
>>>
 +rsmith (actually this time)

 On Sun, Sep 30, 2018 at 12:09 PM Eric Fiselier  wrote:

> +rsmith
>
> Hi All,
>
> Sorry, I'm not actually sure why this fix is correct.I stole both the
> fix and the comment from a similar one on L150 of the module map left by
> Richard Smith.
>
> /Eric
>
> On Tue, Sep 25, 2018 at 8:36 PM Shuai Wang 
> wrote:
>
>> I'd like to understand this better as well, in particular what would
>> be a proper fix?
>>
>> On Tue, Sep 25, 2018 at 2:15 PM David Blaikie 
>> wrote:
>>
>>> +Shuai Wang
>>>
>>> On Tue, Sep 25, 2018 at 2:14 PM David Blaikie 
>>> wrote:
>>>
 Hey Eric - thanks for the fix - but could you explain the issue
 here in a bit more detail, as I'm a bit confused (& really interested 
 in
 understanding any layering problems in LLVM - and fixing them/making 
 sure
 they're fixed/holding the line/etc)

 What do you mean by "pull all of the AST matchers library into
 clang" - how does including a header ever add a link dependency?

 - Dave


 On Sat, Sep 22, 2018 at 5:49 PM Eric Fiselier via cfe-commits <
 cfe-commits@lists.llvm.org> wrote:

> Author: ericwf
> Date: Sat Sep 22 17:48:05 2018
> New Revision: 342827
>
> URL: http://llvm.org/viewvc/llvm-project?rev=342827=rev
> Log:
> Fix modules build with shared library.
>
> r341994 caused clangAnalysis to pull all of the AST matchers
> library into clang. Due to inline key functions in the headers,
> importing the AST matchers library gives a link dependency on the
> AST matchers (and thus the AST), which clang should not
> have.
>
> This patch works around the issues by excluding the offending
> libclangAnalysis header in the 

Re: r342827 - Fix modules build with shared library.

2018-10-01 Thread Shuai Wang via cfe-commits
George wanted to use it from clang (or, at least can't use from anything
from clang-tidy.) I was actually assuming the intended usage is from some
tooling instead of the frontend itself, but I never checked with George.
Personally I don't think ExprMutationAnalyzer should be used in anywhere
other than toolings. I'm happy to move it around if current location is not
desirable.

On Mon, Oct 1, 2018 at 2:50 PM Richard Smith  wrote:

> This looks like the wrong fix to me, but I don't really know enough about
> what's being done with ExprMutationAnalyzer to have an opinion on what the
> right fix is.
>
> Shuai, what is the goal here? Why is this code being moved to Analysis/?
> Do you intend to call it from the compiler frontend at some point? I can
> see a code review for the move itself, but no discussion of a plan or
> overall direction being followed here. Did I miss it?
>
> We have historically decided to not use the tooling interfaces
> (ASTMatcher, ParentMap, etc) from the frontend, because they're generally a
> poor fit for our goals (we aim for a largely-single-pass compilation with
> good locality, and the AST matchers make different design choices). If you
> want to change that, we'll need to discuss that decision.
>
> If the idea is to move this code into clang proper so that it can be used
> by various different tooling clients, we'd need to discuss the right place
> for it. Perhaps lib/Tooling/Analysis would make sense?
>
> On Mon, 1 Oct 2018 at 13:13, David Blaikie via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> I can't really reproduce this - when I try to build clang/llvm with
>> LLVM_ENABLE_MODULES in CMake I'm still seeing an error I reported March on
>> a cfe-dev thread - something to do with unique_ptr instantiations for
>> MappedBlockStream in the PDB parsing code.
>>
>> So, I'm wondering what error you hit, Eric/where/how, etc...
>>
>> On Sun, Sep 30, 2018 at 10:23 AM Eric Fiselier  wrote:
>>
>>> +rsmith (actually this time)
>>>
>>> On Sun, Sep 30, 2018 at 12:09 PM Eric Fiselier  wrote:
>>>
 +rsmith

 Hi All,

 Sorry, I'm not actually sure why this fix is correct.I stole both the
 fix and the comment from a similar one on L150 of the module map left by
 Richard Smith.

 /Eric

 On Tue, Sep 25, 2018 at 8:36 PM Shuai Wang 
 wrote:

> I'd like to understand this better as well, in particular what would
> be a proper fix?
>
> On Tue, Sep 25, 2018 at 2:15 PM David Blaikie 
> wrote:
>
>> +Shuai Wang
>>
>> On Tue, Sep 25, 2018 at 2:14 PM David Blaikie 
>> wrote:
>>
>>> Hey Eric - thanks for the fix - but could you explain the issue here
>>> in a bit more detail, as I'm a bit confused (& really interested in
>>> understanding any layering problems in LLVM - and fixing them/making 
>>> sure
>>> they're fixed/holding the line/etc)
>>>
>>> What do you mean by "pull all of the AST matchers library into
>>> clang" - how does including a header ever add a link dependency?
>>>
>>> - Dave
>>>
>>>
>>> On Sat, Sep 22, 2018 at 5:49 PM Eric Fiselier via cfe-commits <
>>> cfe-commits@lists.llvm.org> wrote:
>>>
 Author: ericwf
 Date: Sat Sep 22 17:48:05 2018
 New Revision: 342827

 URL: http://llvm.org/viewvc/llvm-project?rev=342827=rev
 Log:
 Fix modules build with shared library.

 r341994 caused clangAnalysis to pull all of the AST matchers
 library into clang. Due to inline key functions in the headers,
 importing the AST matchers library gives a link dependency on the
 AST matchers (and thus the AST), which clang should not
 have.

 This patch works around the issues by excluding the offending
 libclangAnalysis header in the modulemap.

 Modified:
 cfe/trunk/include/clang/module.modulemap

 Modified: cfe/trunk/include/clang/module.modulemap
 URL:
 http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/module.modulemap?rev=342827=342826=342827=diff

 ==
 --- cfe/trunk/include/clang/module.modulemap (original)
 +++ cfe/trunk/include/clang/module.modulemap Sat Sep 22 17:48:05
 2018
 @@ -5,6 +5,12 @@ module Clang_Analysis {
textual header "Analysis/Analyses/ThreadSafetyOps.def"

module * { export * }
 +
 +  // FIXME: Exclude these headers to avoid pulling all of the AST
 matchers
 +  // library into clang. Due to inline key functions in the
 headers,
 +  // importing the AST matchers library gives a link dependency on
 the AST
 +  // matchers (and thus the AST), which clang-format should not
 have.
 +  exclude header 

Re: r342827 - Fix modules build with shared library.

2018-09-25 Thread Shuai Wang via cfe-commits
I'd like to understand this better as well, in particular what would be a
proper fix?

On Tue, Sep 25, 2018 at 2:15 PM David Blaikie  wrote:

> +Shuai Wang
>
> On Tue, Sep 25, 2018 at 2:14 PM David Blaikie  wrote:
>
>> Hey Eric - thanks for the fix - but could you explain the issue here in a
>> bit more detail, as I'm a bit confused (& really interested in
>> understanding any layering problems in LLVM - and fixing them/making sure
>> they're fixed/holding the line/etc)
>>
>> What do you mean by "pull all of the AST matchers library into clang" -
>> how does including a header ever add a link dependency?
>>
>> - Dave
>>
>>
>> On Sat, Sep 22, 2018 at 5:49 PM Eric Fiselier via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: ericwf
>>> Date: Sat Sep 22 17:48:05 2018
>>> New Revision: 342827
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=342827=rev
>>> Log:
>>> Fix modules build with shared library.
>>>
>>> r341994 caused clangAnalysis to pull all of the AST matchers
>>> library into clang. Due to inline key functions in the headers,
>>> importing the AST matchers library gives a link dependency on the
>>> AST matchers (and thus the AST), which clang should not
>>> have.
>>>
>>> This patch works around the issues by excluding the offending
>>> libclangAnalysis header in the modulemap.
>>>
>>> Modified:
>>> cfe/trunk/include/clang/module.modulemap
>>>
>>> Modified: cfe/trunk/include/clang/module.modulemap
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/module.modulemap?rev=342827=342826=342827=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/module.modulemap (original)
>>> +++ cfe/trunk/include/clang/module.modulemap Sat Sep 22 17:48:05 2018
>>> @@ -5,6 +5,12 @@ module Clang_Analysis {
>>>textual header "Analysis/Analyses/ThreadSafetyOps.def"
>>>
>>>module * { export * }
>>> +
>>> +  // FIXME: Exclude these headers to avoid pulling all of the AST
>>> matchers
>>> +  // library into clang. Due to inline key functions in the headers,
>>> +  // importing the AST matchers library gives a link dependency on the
>>> AST
>>> +  // matchers (and thus the AST), which clang-format should not have.
>>> +  exclude header "Analysis/Analyses/ExprMutationAnalyzer.h"
>>>  }
>>>
>>>  module Clang_AST {
>>>
>>>
>>> ___
>>> cfe-commits mailing list
>>> cfe-commits@lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342586 - [NFC] Declare instead of define non-void functions in unit tests.

2018-09-19 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Wed Sep 19 13:27:25 2018
New Revision: 342586

URL: http://llvm.org/viewvc/llvm-project?rev=342586=rev
Log:
[NFC] Declare instead of define non-void functions in unit tests.

Modified:
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Modified: cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp?rev=342586=342585=342586=diff
==
--- cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp (original)
+++ cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp Wed Sep 19 
13:27:25 2018
@@ -203,7 +203,7 @@ TEST(ExprMutationAnalyzerTest, ByValueAr
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
   AST = buildASTFromCode(
-  "struct A {}; A operator+(A, int) {} void f() { A x; x + 1; }");
+  "struct A {}; A operator+(A, int); void f() { A x; x + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
@@ -239,7 +239,7 @@ TEST(ExprMutationAnalyzerTest, ByConstVa
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
   AST = buildASTFromCode(
-  "struct A {}; A operator+(const A, int) {} void f() { A x; x + 1; }");
+  "struct A {}; A operator+(const A, int); void f() { A x; x + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
@@ -289,7 +289,7 @@ TEST(ExprMutationAnalyzerTest, ByNonCons
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)"));
 
   AST = buildASTFromCode(
-  "struct A {}; A operator+(A&, int) {} void f() { A x; x + 1; }");
+  "struct A {}; A operator+(A&, int); void f() { A x; x + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x + 1"));
 
@@ -333,7 +333,7 @@ TEST(ExprMutationAnalyzerTest, ByConstRe
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
   AST = buildASTFromCode(
-  "struct A {}; A operator+(const A&, int) {} void f() { A x; x + 1; }");
+  "struct A {}; A operator+(const A&, int); void f() { A x; x + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
@@ -356,7 +356,7 @@ TEST(ExprMutationAnalyzerTest, ByNonCons
   EXPECT_THAT(mutatedBy(Results, AST.get()),
   ElementsAre("g(static_cast(x))"));
 
-  AST = buildASTFromCode("struct A {}; A operator+(A&&, int) {}"
+  AST = buildASTFromCode("struct A {}; A operator+(A&&, int);"
  "void f() { A x; static_cast(x) + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()),
@@ -382,7 +382,7 @@ TEST(ExprMutationAnalyzerTest, ByConstRR
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
-  AST = buildASTFromCode("struct A {}; A operator+(const A&&, int) {}"
+  AST = buildASTFromCode("struct A {}; A operator+(const A&&, int);"
  "void f() { A x; static_cast(x) + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342562 - [analyzer] Fix nullptr access when processing instantiated function in ExprMutationAnalyzer.

2018-09-19 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Wed Sep 19 11:00:55 2018
New Revision: 342562

URL: http://llvm.org/viewvc/llvm-project?rev=342562=rev
Log:
[analyzer] Fix nullptr access when processing instantiated function in 
ExprMutationAnalyzer.

Modified:
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Modified: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=342562=342561=342562=diff
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (original)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Wed Sep 19 11:00:55 2018
@@ -379,7 +379,7 @@ const Stmt *ExprMutationAnalyzer::findFu
   for (const auto  : Matches) {
 const auto *Exp = Nodes.getNodeAs(NodeID::value);
 const auto *Func = Nodes.getNodeAs("func");
-if (!Func->getBody())
+if (!Func->getBody() || !Func->getPrimaryTemplate())
   return Exp;
 
 const auto *Parm = Nodes.getNodeAs("parm");

Modified: cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp?rev=342562=342561=342562=diff
==
--- cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp (original)
+++ cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp Wed Sep 19 
11:00:55 2018
@@ -215,6 +215,12 @@ TEST(ExprMutationAnalyzerTest, ByValueAr
  "void f() { A x, y; y = x; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST = buildASTFromCode(
+  "template  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, ByConstVa
   "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  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, ByNonCons
   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  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, FollowFun
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x"));
 
+  AST = buildASTFromCode("template  struct S {"
+ "template  S(T&& t) : m(++t) { } U m; };"
+ "void f() { int x; S s(x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x"));
+
   AST = buildASTFromCode(StdRemoveReference + StdForward +
  "template  void u(Args&...);"
  "template  void h(Args&&... args)"
@@ -737,6 +761,12 @@ TEST(ExprMutationAnalyzerTest, FollowFun
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
+  AST = buildASTFromCode("template  struct S {"
+ "template  S(T&& t) : m(t) { } U m; };"
+ "void f() { int x; S s(x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
   AST = buildASTFromCode(StdRemoveReference + StdForward +
  "template  void u(Args...);"
  "template  void h(Args&&... args)"


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342525 - [NFC] Fix uncompilable test cases of ExprMutationAnalyzer.

2018-09-18 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 18 20:50:03 2018
New Revision: 342525

URL: http://llvm.org/viewvc/llvm-project?rev=342525=rev
Log:
[NFC] Fix uncompilable test cases of ExprMutationAnalyzer.

And ensure future test cases doesn't have compile errors.

Modified:
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Modified: cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp?rev=342525=342524=342525=diff
==
--- cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp (original)
+++ cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp Tue Sep 18 
20:50:03 2018
@@ -29,6 +29,18 @@ namespace {
 using ExprMatcher = internal::Matcher;
 using StmtMatcher = internal::Matcher;
 
+std::unique_ptr
+buildASTFromCodeWithArgs(const Twine ,
+ const std::vector ) {
+  auto AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+  EXPECT_FALSE(AST->getDiagnostics().hasErrorOccurred());
+  return AST;
+}
+
+std::unique_ptr buildASTFromCode(const Twine ) {
+  return buildASTFromCodeWithArgs(Code, {});
+}
+
 ExprMatcher declRefTo(StringRef Name) {
   return declRefExpr(to(namedDecl(hasName(Name;
 }
@@ -83,12 +95,12 @@ const std::string StdForward =
 "template T&& "
 "forward(typename remove_reference::type& t) noexcept { return t; }"
 "template T&& "
-"forward(typename remove_reference::type&&) noexcept { return t; } }";
+"forward(typename remove_reference::type&& t) noexcept { return t; } }";
 
 } // namespace
 
 TEST(ExprMutationAnalyzerTest, Trivial) {
-  const auto AST = tooling::buildASTFromCode("void f() { int x; x; }");
+  const auto AST = buildASTFromCode("void f() { int x; x; }");
   const auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
@@ -98,8 +110,7 @@ class AssignmentTest : public ::testing:
 
 TEST_P(AssignmentTest, AssignmentModifies) {
   const std::string ModExpr = "x " + GetParam() + " 10";
-  const auto AST =
-  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto AST = buildASTFromCode("void f() { int x; " + ModExpr + "; }");
   const auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
@@ -113,8 +124,7 @@ class IncDecTest : public ::testing::Tes
 
 TEST_P(IncDecTest, IncDecModifies) {
   const std::string ModExpr = GetParam();
-  const auto AST =
-  tooling::buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+  const auto AST = buildASTFromCode("void f() { int x; " + ModExpr + "; }");
   const auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
@@ -124,7 +134,7 @@ INSTANTIATE_TEST_CASE_P(AllIncDecOperato
 Values("++x", "--x", "x++", "x--"), );
 
 TEST(ExprMutationAnalyzerTest, NonConstMemberFunc) {
-  const auto AST = tooling::buildASTFromCode(
+  const auto AST = buildASTFromCode(
   "void f() { struct Foo { void mf(); }; Foo x; x.mf(); }");
   const auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
@@ -132,7 +142,7 @@ TEST(ExprMutationAnalyzerTest, NonConstM
 }
 
 TEST(ExprMutationAnalyzerTest, AssumedNonConstMemberFunc) {
-  auto AST = tooling::buildASTFromCodeWithArgs(
+  auto AST = buildASTFromCodeWithArgs(
   "struct X { template  void mf(); };"
   "template  void f() { X x; x.mf(); }",
   {"-fno-delayed-template-parsing"});
@@ -140,13 +150,12 @@ TEST(ExprMutationAnalyzerTest, AssumedNo
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
 
-  AST = tooling::buildASTFromCodeWithArgs(
-  "template  void f() { T x; x.mf(); }",
-  {"-fno-delayed-template-parsing"});
+  AST = buildASTFromCodeWithArgs("template  void f() { T x; x.mf(); 
}",
+ {"-fno-delayed-template-parsing"});
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
 
-  AST = tooling::buildASTFromCodeWithArgs(
+  AST = buildASTFromCodeWithArgs(
   "template  struct X;"
   "template  void f() { X x; x.mf(); }",
   {"-fno-delayed-template-parsing"});
@@ -155,7 +164,7 @@ TEST(ExprMutationAnalyzerTest, AssumedNo
 }
 
 TEST(ExprMutationAnalyzerTest, ConstMemberFunc) {
-  const auto AST = tooling::buildASTFromCode(
+  const auto AST = buildASTFromCode(
   "void f() { struct Foo { void mf() const; }; Foo x; x.mf(); }");
   const auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
@@ -163,7 +172,7 @@ 

[clang-tools-extra] r342417 - [clang-tidy] Fix tests for performance-for-range-copy

2018-09-17 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 17 14:28:08 2018
New Revision: 342417

URL: http://llvm.org/viewvc/llvm-project?rev=342417=rev
Log:
[clang-tidy] Fix tests for performance-for-range-copy

Test failed as D52120 made ExprMutationAnalyzer smarter, fixed by:
- Add move-ctor for `Mutable` to make it actually movable.
- Properly implement `remove_reference`.

The failed test case is:
void negativeVarIsMoved() {
  for (auto M : View>()) {
auto Moved = std::move(M);
  }
}
Before D52120, `std::move(M)` itself is considered as a mutation to `M`,
while after D52120 it's only considered as a cast to rvalue, the
move-assignment is what causes the actual mutation. The test case didn't
mock things properly so the intended move-assignement was actually a
copy-assignment.

Modified:
clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp

Modified: clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp?rev=342417=342416=342417=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp 
(original)
+++ clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp Mon 
Sep 17 14:28:08 2018
@@ -4,6 +4,10 @@ namespace std {
 
 template 
 struct remove_reference { typedef _Tp type; };
+template 
+struct remove_reference<_Tp&> { typedef _Tp type; };
+template 
+struct remove_reference<_Tp&&> { typedef _Tp type; };
 
 template 
 constexpr typename std::remove_reference<_Tp>::type &(_Tp &&__t) {
@@ -103,6 +107,7 @@ void f() {
 struct Mutable {
   Mutable() {}
   Mutable(const Mutable &) = default;
+  Mutable(Mutable&&) = default;
   Mutable(const Mutable &, const Mutable &) {}
   void setBool(bool B) {}
   bool constMethod() const {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342409 - [analyzer] Treat std::{move, forward} as casts in ExprMutationAnalyzer.

2018-09-17 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 17 13:10:56 2018
New Revision: 342409

URL: http://llvm.org/viewvc/llvm-project?rev=342409=rev
Log:
[analyzer] Treat std::{move,forward} as casts in ExprMutationAnalyzer.

Summary:
This is a follow up of D52008 and should make the analyzer being able to handle 
perfect forwardings in real world cases where forwardings are done through 
multiple layers of function calls with `std::forward`.

Fixes PR38891.

Reviewers: lebedev.ri, JonasToth, george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, mikhail.ramalho, Szelethus, 
cfe-commits

Differential Revision: https://reviews.llvm.org/D52120

Modified:
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Modified: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=342409=342408=342409=diff
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (original)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Mon Sep 17 13:10:56 2018
@@ -304,7 +304,16 @@ const Stmt *ExprMutationAnalyzer::findCa
nonConstReferenceType()
 .bind(NodeID::value)),
 Stm, Context);
-  return findExprMutation(Casts);
+  if (const Stmt *S = findExprMutation(Casts))
+return S;
+  // Treat std::{move,forward} as cast.
+  const auto Calls =
+  match(findAll(callExpr(callee(namedDecl(
+ hasAnyName("::std::move", "::std::forward"))),
+ hasArgument(0, equalsNode(Exp)))
+.bind("expr")),
+Stm, Context);
+  return findExprMutation(Calls);
 }
 
 const Stmt *ExprMutationAnalyzer::findRangeLoopMutation(const Expr *Exp) {
@@ -360,7 +369,9 @@ const Stmt *ExprMutationAnalyzer::findFu
   const auto IsInstantiated = hasDeclaration(isInstantiated());
   const auto FuncDecl = hasDeclaration(functionDecl().bind("func"));
   const auto Matches = match(
-  findAll(expr(anyOf(callExpr(NonConstRefParam, IsInstantiated, FuncDecl),
+  findAll(expr(anyOf(callExpr(NonConstRefParam, IsInstantiated, FuncDecl,
+  unless(callee(namedDecl(hasAnyName(
+  "::std::move", "::std::forward"),
  cxxConstructExpr(NonConstRefParam, IsInstantiated,
   FuncDecl)))
   .bind(NodeID::value)),

Modified: cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp?rev=342409=342408=342409=diff
==
--- cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp (original)
+++ cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp Mon Sep 17 
13:10:56 2018
@@ -66,6 +66,25 @@ std::string removeSpace(std::string s) {
   return s;
 }
 
+const std::string StdRemoveReference =
+"namespace std {"
+"template struct remove_reference { typedef T type; };"
+"template struct remove_reference { typedef T type; };"
+"template struct remove_reference { typedef T type; }; }";
+
+const std::string StdMove =
+"namespace std {"
+"template typename remove_reference::type&& "
+"move(T&& t) noexcept {"
+"return static_cast::type&&>(t); } }";
+
+const std::string StdForward =
+"namespace std {"
+"template T&& "
+"forward(typename remove_reference::type& t) noexcept { return t; }"
+"template T&& "
+"forward(typename remove_reference::type&&) noexcept { return t; } }";
+
 } // namespace
 
 TEST(ExprMutationAnalyzerTest, Trivial) {
@@ -373,36 +392,87 @@ TEST(ExprMutationAnalyzerTest, ByConstRR
 }
 
 TEST(ExprMutationAnalyzerTest, Move) {
-  // Technically almost the same as ByNonConstRRefArgument, just double 
checking
-  const auto AST = tooling::buildASTFromCode(
-  "namespace std {"
-  "template struct remove_reference { typedef T type; };"
-  "template struct remove_reference { typedef T type; };"
-  "template struct remove_reference { typedef T type; };"
-  "template typename std::remove_reference::type&& "
-  "move(T&& t) noexcept; }"
-  "void f() { struct A {}; A x; std::move(x); }");
-  const auto Results =
+  auto AST =
+  tooling::buildASTFromCode(StdRemoveReference + StdMove +
+"void f() { struct A {}; A x; std::move(x); 
}");
+  auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
-  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("std::move(x)"));
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST = tooling::buildASTFromCode(
+  StdRemoveReference + StdMove +
+  "void f() { struct A {}; A x, y; std::move(x) = 

[clang-tools-extra] r342408 - Fix build failure caused by D52157

2018-09-17 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 17 13:10:33 2018
New Revision: 342408

URL: http://llvm.org/viewvc/llvm-project?rev=342408=rev
Log:
Fix build failure caused by D52157

Modified:
clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp

Modified: clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp?rev=342408=342407=342408=diff
==
--- clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp Mon Sep 
17 13:10:33 2018
@@ -115,7 +115,7 @@ TEST_F(QueryEngineTest, Basic) {
 
   Str.clear();
 
-  EXPECT_FALSE(MatchQuery(isArrow()).run(OS, S));
+  EXPECT_FALSE(MatchQuery(isMain()).run(OS, S));
 
   EXPECT_EQ("Not a valid top-level matcher.\n", OS.str());
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342407 - [ASTMatchers] Let isArrow also support UnresolvedMemberExpr, CXXDependentScopeMemberExpr

2018-09-17 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 17 11:48:43 2018
New Revision: 342407

URL: http://llvm.org/viewvc/llvm-project?rev=342407=rev
Log:
[ASTMatchers] Let isArrow also support UnresolvedMemberExpr, 
CXXDependentScopeMemberExpr

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D52157

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=342407=342406=342407=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Mon Sep 17 11:48:43 2018
@@ -2235,6 +2235,32 @@ cxxConstructorDecl(hasAnyConstructorInit
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html;>CXXDependentScopeMemberExprisArrow
+Matches member expressions 
that are called with '-' as opposed
+to '.'.
+
+Member calls on the implicit this pointer match as called with '-'.
+
+Given
+  class Y {
+void x() { this-x(); x(); Y y; y.x(); a; this-b; Y::b; }
+template class T void f() { this-fT(); fT(); }
+int a;
+static int b;
+  };
+  template class T
+  class Z {
+void x() { this-m; }
+  };
+memberExpr(isArrow())
+  matches this-x, x, y.x, a, this-b
+cxxDependentScopeMemberExpr(isArrow())
+  matches this-m
+unresolvedMemberExpr(isArrow())
+  matches this-fT, fT
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html;>CXXMethodDeclisConst
 Matches if the given method 
declaration is const.
 
@@ -3228,11 +3254,20 @@ Member calls on the implicit this pointe
 Given
   class Y {
 void x() { this-x(); x(); Y y; y.x(); a; this-b; Y::b; }
+template class T void f() { this-fT(); fT(); }
 int a;
 static int b;
   };
+  template class T
+  class Z {
+void x() { this-m; }
+  };
 memberExpr(isArrow())
   matches this-x, x, y.x, a, this-b
+cxxDependentScopeMemberExpr(isArrow())
+  matches this-m
+unresolvedMemberExpr(isArrow())
+  matches this-fT, fT
 
 
 
@@ -3886,6 +3921,32 @@ Example matches a || b (matcher = binary
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html;>UnresolvedMemberExprisArrow
+Matches member expressions 
that are called with '-' as opposed
+to '.'.
+
+Member calls on the implicit this pointer match as called with '-'.
+
+Given
+  class Y {
+void x() { this-x(); x(); Y y; y.x(); a; this-b; Y::b; }
+template class T void f() { this-fT(); fT(); }
+int a;
+static int b;
+  };
+  template class T
+  class Z {
+void x() { this-m; }
+  };
+memberExpr(isArrow())
+  matches this-x, x, y.x, a, this-b
+cxxDependentScopeMemberExpr(isArrow())
+  matches this-m
+unresolvedMemberExpr(isArrow())
+  matches this-fT, fT
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1VarDecl.html;>VarDeclhasAutomaticStorageDuration
 Matches 
a variable declaration that has automatic storage duration.
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=342407=342406=342407=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Sep 17 11:48:43 2018
@@ -4697,13 +4697,24 @@ AST_MATCHER(CXXMethodDecl, isUserProvide
 /// \code
 ///   class Y {
 /// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
+/// template  void f() { this->f(); f(); }
 /// int a;
 /// static int b;
 ///   };
+///   template 
+///   class Z {
+/// void x() { this->m; }
+///   };
 /// \endcode
 /// memberExpr(isArrow())
 ///   matches this->x, x, y.x, a, this->b
-AST_MATCHER(MemberExpr, isArrow) {
+/// cxxDependentScopeMemberExpr(isArrow())
+///   matches this->m
+/// unresolvedMemberExpr(isArrow())
+///   matches this->f, f
+AST_POLYMORPHIC_MATCHER(
+isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+ CXXDependentScopeMemberExpr)) {
   return Node.isArrow();
 }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=342407=342406=342407=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Mon Sep 17 
11:48:43 2018
@@ -765,6 +765,11 @@ TEST(IsArrow, 

[clang-tools-extra] r342403 - [clang-tidy] Remove duplicated logic in UnnecessaryValueParamCheck and use FunctionParmMutationAnalyzer instead.

2018-09-17 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 17 10:59:51 2018
New Revision: 342403

URL: http://llvm.org/viewvc/llvm-project?rev=342403=rev
Log:
[clang-tidy] Remove duplicated logic in UnnecessaryValueParamCheck and use 
FunctionParmMutationAnalyzer instead.

Reviewers: alexfh, JonasToth, george.karpenkov

Subscribers: xazax.hun, kristof.beyls, chrib, a.sidorin, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D52158

Modified:

clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.h

Modified: 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp?rev=342403=342402=342403=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
Mon Sep 17 10:59:51 2018
@@ -13,7 +13,6 @@
 #include "../utils/FixItHintUtils.h"
 #include "../utils/Matchers.h"
 #include "../utils/TypeTraits.h"
-#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
@@ -92,21 +91,11 @@ void UnnecessaryValueParamCheck::check(c
   const auto *Param = Result.Nodes.getNodeAs("param");
   const auto *Function = Result.Nodes.getNodeAs("functionDecl");
 
-  // Do not trigger on non-const value parameters when they are mutated either
-  // within the function body or within init expression(s) when the function is
-  // a ctor.
-  if (ExprMutationAnalyzer(*Function->getBody(), *Result.Context)
-  .isMutated(Param))
+  FunctionParmMutationAnalyzer  =
+  MutationAnalyzers.try_emplace(Function, *Function, *Result.Context)
+  .first->second;
+  if (Analyzer.isMutated(Param))
 return;
-  // CXXCtorInitializer might also mutate Param but they're not part of 
function
-  // body, so check them separately here.
-  if (const auto *Ctor = dyn_cast(Function)) {
-for (const auto *Init : Ctor->inits()) {
-  if (ExprMutationAnalyzer(*Init->getInit(), *Result.Context)
-  .isMutated(Param))
-return;
-}
-  }
 
   const bool IsConstQualified =
   Param->getType().getCanonicalType().isConstQualified();
@@ -186,6 +175,10 @@ void UnnecessaryValueParamCheck::storeOp
 utils::IncludeSorter::toString(IncludeStyle));
 }
 
+void UnnecessaryValueParamCheck::onEndOfTranslationUnit() {
+  MutationAnalyzers.clear();
+}
+
 void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl ,
const DeclRefExpr ,
const ASTContext ) {

Modified: 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.h?rev=342403=342402=342403=diff
==
--- clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.h 
(original)
+++ clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.h 
Mon Sep 17 10:59:51 2018
@@ -12,6 +12,7 @@
 
 #include "../ClangTidy.h"
 #include "../utils/IncludeInserter.h"
+#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 
 namespace clang {
 namespace tidy {
@@ -29,11 +30,14 @@ public:
   void check(const ast_matchers::MatchFinder::MatchResult ) override;
   void registerPPCallbacks(CompilerInstance ) override;
   void storeOptions(ClangTidyOptions::OptionMap ) override;
+  void onEndOfTranslationUnit() override;
 
 private:
   void handleMoveFix(const ParmVarDecl , const DeclRefExpr ,
  const ASTContext );
 
+  llvm::DenseMap
+  MutationAnalyzers;
   std::unique_ptr Inserter;
   const utils::IncludeSorter::IncludeStyle IncludeStyle;
 };


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342353 - [NFC] Minor refactoring to setup the stage for supporting pointers in ExprMutationAnalyzer

2018-09-16 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sun Sep 16 14:09:50 2018
New Revision: 342353

URL: http://llvm.org/viewvc/llvm-project?rev=342353=rev
Log:
[NFC] Minor refactoring to setup the stage for supporting pointers in 
ExprMutationAnalyzer

Modified:
cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp

Modified: cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h?rev=342353=342352=342353=diff
==
--- cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h Sun Sep 16 
14:09:50 2018
@@ -31,13 +31,32 @@ public:
   const Stmt *findMutation(const Expr *Exp);
   const Stmt *findMutation(const Decl *Dec);
 
+  bool isPointeeMutated(const Expr *Exp) {
+return findPointeeMutation(Exp) != nullptr;
+  }
+  bool isPointeeMutated(const Decl *Dec) {
+return findPointeeMutation(Dec) != nullptr;
+  }
+  const Stmt *findPointeeMutation(const Expr *Exp);
+  const Stmt *findPointeeMutation(const Decl *Dec);
+
 private:
+  using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
   using ResultMap = llvm::DenseMap;
 
+  const Stmt *findMutationMemoized(const Expr *Exp,
+   llvm::ArrayRef Finders,
+   ResultMap );
+  const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
+
   bool isUnevaluated(const Expr *Exp);
 
   const Stmt *findExprMutation(ArrayRef Matches);
   const Stmt *findDeclMutation(ArrayRef Matches);
+  const Stmt *
+  findExprPointeeMutation(ArrayRef Matches);
+  const Stmt *
+  findDeclPointeeMutation(ArrayRef Matches);
 
   const Stmt *findDirectMutation(const Expr *Exp);
   const Stmt *findMemberMutation(const Expr *Exp);
@@ -53,6 +72,7 @@ private:
  std::unique_ptr>
   FuncParmAnalyzer;
   ResultMap Results;
+  ResultMap PointeeResults;
 };
 
 // A convenient wrapper around ExprMutationAnalyzer for analyzing function

Modified: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=342353=342352=342353=diff
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (original)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Sun Sep 16 14:09:50 2018
@@ -64,33 +64,83 @@ const auto isMoveOnly = [] {
unless(isDeleted()));
 };
 
+template  struct NodeID;
+template <> struct NodeID { static const std::string value; };
+template <> struct NodeID { static const std::string value; };
+const std::string NodeID::value = "expr";
+const std::string NodeID::value = "decl";
+
+template 
+const Stmt *tryEachMatch(ArrayRef Matches,
+ ExprMutationAnalyzer *Analyzer, F Finder) {
+  const StringRef ID = NodeID::value;
+  for (const auto  : Matches) {
+if (const Stmt *S = (Analyzer->*Finder)(Nodes.getNodeAs(ID)))
+  return S;
+  }
+  return nullptr;
+}
+
 } // namespace
 
 const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) {
-  const auto Memoized = Results.find(Exp);
-  if (Memoized != Results.end())
+  return findMutationMemoized(Exp,
+  {::findDirectMutation,
+   ::findMemberMutation,
+   ::findArrayElementMutation,
+   ::findCastMutation,
+   ::findRangeLoopMutation,
+   ::findReferenceMutation,
+   ::findFunctionArgMutation},
+  Results);
+}
+
+const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) {
+  return tryEachDeclRef(Dec, ::findMutation);
+}
+
+const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Expr *Exp) {
+  return findMutationMemoized(Exp, {/*TODO*/}, PointeeResults);
+}
+
+const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Decl *Dec) {
+  return tryEachDeclRef(Dec, ::findPointeeMutation);
+}
+
+const Stmt *ExprMutationAnalyzer::findMutationMemoized(
+const Expr *Exp, llvm::ArrayRef Finders,
+ResultMap ) {
+  const auto Memoized = MemoizedResults.find(Exp);
+  if (Memoized != MemoizedResults.end())
 return Memoized->second;
 
   if (isUnevaluated(Exp))
-return Results[Exp] = nullptr;
+return MemoizedResults[Exp] = nullptr;
 
-  for (const auto  : {::findDirectMutation,
- ::findMemberMutation,
- ::findArrayElementMutation,
- ::findCastMutation,
- ::findRangeLoopMutation,
- ::findReferenceMutation,
-  

r342340 - [NFC] cosmetic tweaks to ExprMutationAnalyzer to be more consistent

2018-09-15 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sat Sep 15 14:38:18 2018
New Revision: 342340

URL: http://llvm.org/viewvc/llvm-project?rev=342340=rev
Log:
[NFC] cosmetic tweaks to ExprMutationAnalyzer to be more consistent
especially considering future changes.

Modified:
cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp

Modified: cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h?rev=342340=342339=342340=diff
==
--- cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h Sat Sep 15 
14:38:18 2018
@@ -26,12 +26,14 @@ public:
   ExprMutationAnalyzer(const Stmt , ASTContext )
   : Stm(Stm), Context(Context) {}
 
-  bool isMutated(const Decl *Dec) { return findDeclMutation(Dec) != nullptr; }
   bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
+  bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
   const Stmt *findMutation(const Expr *Exp);
-  const Stmt *findDeclMutation(const Decl *Dec);
+  const Stmt *findMutation(const Decl *Dec);
 
 private:
+  using ResultMap = llvm::DenseMap;
+
   bool isUnevaluated(const Expr *Exp);
 
   const Stmt *findExprMutation(ArrayRef Matches);
@@ -50,7 +52,7 @@ private:
   llvm::DenseMap>
   FuncParmAnalyzer;
-  llvm::DenseMap Results;
+  ResultMap Results;
 };
 
 // A convenient wrapper around ExprMutationAnalyzer for analyzing function

Modified: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=342340=342339=342340=diff
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (original)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Sat Sep 15 14:38:18 2018
@@ -131,13 +131,13 @@ ExprMutationAnalyzer::findExprMutation(A
 const Stmt *
 ExprMutationAnalyzer::findDeclMutation(ArrayRef Matches) {
   for (const auto  : Matches) {
-if (const Stmt *S = findDeclMutation(DeclNodes.getNodeAs("decl")))
+if (const Stmt *S = findMutation(DeclNodes.getNodeAs("decl")))
   return S;
   }
   return nullptr;
 }
 
-const Stmt *ExprMutationAnalyzer::findDeclMutation(const Decl *Dec) {
+const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) {
   const auto Refs = match(
   findAll(declRefExpr(to(equalsNode(Dec))).bind("expr")), Stm, Context);
   for (const auto  : Refs) {
@@ -280,15 +280,14 @@ const Stmt *ExprMutationAnalyzer::findRe
   // Follow non-const reference returned by `operator*()` of move-only classes.
   // These are typically smart pointers with unique ownership so we treat
   // mutation of pointee as mutation of the smart pointer itself.
-  const auto Ref = match(
-  findAll(cxxOperatorCallExpr(
-  hasOverloadedOperatorName("*"),
-  callee(cxxMethodDecl(ofClass(isMoveOnly()),
-   returns(hasUnqualifiedDesugaredType(
-   nonConstReferenceType(),
-  argumentCountIs(1), hasArgument(0, equalsNode(Exp)))
-  .bind("expr")),
-  Stm, Context);
+  const auto Ref =
+  match(findAll(cxxOperatorCallExpr(
+hasOverloadedOperatorName("*"),
+callee(cxxMethodDecl(ofClass(isMoveOnly()),
+ 
returns(nonConstReferenceType(,
+argumentCountIs(1), hasArgument(0, equalsNode(Exp)))
+.bind("expr")),
+Stm, Context);
   if (const Stmt *S = findExprMutation(Ref))
 return S;
 
@@ -370,7 +369,7 @@ FunctionParmMutationAnalyzer::FunctionPa
   for (const ParmVarDecl *Parm : Ctor->parameters()) {
 if (Results.find(Parm) != Results.end())
   continue;
-if (const Stmt *S = InitAnalyzer.findDeclMutation(Parm))
+if (const Stmt *S = InitAnalyzer.findMutation(Parm))
   Results[Parm] = S;
   }
 }
@@ -383,7 +382,7 @@ FunctionParmMutationAnalyzer::findMutati
   if (Memoized != Results.end())
 return Memoized->second;
 
-  if (const Stmt *S = BodyAnalyzer.findDeclMutation(Parm))
+  if (const Stmt *S = BodyAnalyzer.findMutation(Parm))
 return Results[Parm] = S;
 
   return Results[Parm] = nullptr;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342271 - [analyzer] Handle forwarding reference better in ExprMutationAnalyzer.

2018-09-14 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Fri Sep 14 13:07:18 2018
New Revision: 342271

URL: http://llvm.org/viewvc/llvm-project?rev=342271=rev
Log:
[analyzer] Handle forwarding reference better in ExprMutationAnalyzer.

Summary:
We used to treat an `Expr` mutated whenever it's passed as non-const
reference argument to a function. This results in false positives in
cases like this:
```
int x;
std::vector v;
v.emplace_back(x); // `x` is passed as non-const reference to `emplace_back`
```
In theory the false positives can be suppressed with
`v.emplace_back(std::as_const(x))` but that's considered overly verbose,
inconsistent with existing code and spammy as diags.

This diff handles such cases by following into the function definition
and see whether the argument is mutated inside.

Reviewers: lebedev.ri, JonasToth, george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, mikhail.ramalho, Szelethus, 
cfe-commits

Differential Revision: https://reviews.llvm.org/D52008

Modified:
cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Modified: cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h?rev=342271=342270=342271=diff
==
--- cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h Fri Sep 14 
13:07:18 2018
@@ -17,6 +17,8 @@
 
 namespace clang {
 
+class FunctionParmMutationAnalyzer;
+
 /// Analyzes whether any mutative operations are applied to an expression 
within
 /// a given statement.
 class ExprMutationAnalyzer {
@@ -27,13 +29,13 @@ public:
   bool isMutated(const Decl *Dec) { return findDeclMutation(Dec) != nullptr; }
   bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
   const Stmt *findMutation(const Expr *Exp);
+  const Stmt *findDeclMutation(const Decl *Dec);
 
 private:
   bool isUnevaluated(const Expr *Exp);
 
   const Stmt *findExprMutation(ArrayRef Matches);
   const Stmt *findDeclMutation(ArrayRef Matches);
-  const Stmt *findDeclMutation(const Decl *Dec);
 
   const Stmt *findDirectMutation(const Expr *Exp);
   const Stmt *findMemberMutation(const Expr *Exp);
@@ -41,12 +43,32 @@ private:
   const Stmt *findCastMutation(const Expr *Exp);
   const Stmt *findRangeLoopMutation(const Expr *Exp);
   const Stmt *findReferenceMutation(const Expr *Exp);
+  const Stmt *findFunctionArgMutation(const Expr *Exp);
 
   const Stmt 
   ASTContext 
+  llvm::DenseMap>
+  FuncParmAnalyzer;
   llvm::DenseMap Results;
 };
 
+// A convenient wrapper around ExprMutationAnalyzer for analyzing function
+// params.
+class FunctionParmMutationAnalyzer {
+public:
+  FunctionParmMutationAnalyzer(const FunctionDecl , ASTContext );
+
+  bool isMutated(const ParmVarDecl *Parm) {
+return findMutation(Parm) != nullptr;
+  }
+  const Stmt *findMutation(const ParmVarDecl *Parm);
+
+private:
+  ExprMutationAnalyzer BodyAnalyzer;
+  llvm::DenseMap Results;
+};
+
 } // namespace clang
 
 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H

Modified: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=342271=342270=342271=diff
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (original)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Fri Sep 14 13:07:18 2018
@@ -79,7 +79,8 @@ const Stmt *ExprMutationAnalyzer::findMu
  ::findArrayElementMutation,
  ::findCastMutation,
  ::findRangeLoopMutation,
- ::findReferenceMutation}) {
+ ::findReferenceMutation,
+ ::findFunctionArgMutation}) {
 if (const Stmt *S = (this->*Finder)(Exp))
   return Results[Exp] = S;
   }
@@ -192,10 +193,15 @@ const Stmt *ExprMutationAnalyzer::findDi
 
   // Used as non-const-ref argument when calling a function.
   // An argument is assumed to be non-const-ref when the function is 
unresolved.
+  // Instantiated template functions are not handled here but in
+  // findFunctionArgMutation which has additional smarts for handling 
forwarding
+  // references.
   const auto NonConstRefParam = forEachArgumentWithParam(
   equalsNode(Exp), parmVarDecl(hasType(nonConstReferenceType(;
+  const auto NotInstantiated = unless(hasDeclaration(isInstantiated()));
   const auto AsNonConstRefArg = anyOf(
-  callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam),
+  callExpr(NonConstRefParam, NotInstantiated),
+  cxxConstructExpr(NonConstRefParam, NotInstantiated),

r342246 - Remove PseudoConstantAnalysis

2018-09-14 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Fri Sep 14 10:27:27 2018
New Revision: 342246

URL: http://llvm.org/viewvc/llvm-project?rev=342246=rev
Log:
Remove PseudoConstantAnalysis

Summary: It's not used anywhere for years. The last usage is removed in 
https://reviews.llvm.org/rL198476 in 2014.

Subscribers: mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D51946

Removed:
cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
cfe/trunk/lib/Analysis/PseudoConstantAnalysis.cpp
Modified:
cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
cfe/trunk/lib/Analysis/CMakeLists.txt

Removed: cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h?rev=342245=auto
==
--- cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h 
(original)
+++ cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h (removed)
@@ -1,45 +0,0 @@
-//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ 
-*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-//
-// This file tracks the usage of variables in a Decl body to see if they are
-// never written to, implying that they constant. This is useful in static
-// analysis to see if a developer might have intended a variable to be const.
-//
-//===--===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
-
-#include "clang/AST/Stmt.h"
-
-namespace clang {
-
-class PseudoConstantAnalysis {
-public:
-  PseudoConstantAnalysis(const Stmt *DeclBody);
-  ~PseudoConstantAnalysis();
-
-  bool isPseudoConstant(const VarDecl *VD);
-  bool wasReferenced(const VarDecl *VD);
-
-private:
-  void RunAnalysis();
-  inline static const Decl *getDecl(const Expr *E);
-
-  // for storing the result of analyzed ValueDecls
-  void *NonConstantsImpl;
-  void *UsedVarsImpl;
-
-  const Stmt *DeclBody;
-  bool Analyzed;
-};
-
-}
-
-#endif

Modified: cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h?rev=342246=342245=342246=diff
==
--- cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h Fri Sep 14 10:27:27 
2018
@@ -40,7 +40,6 @@ class ImplicitParamDecl;
 class LocationContext;
 class LocationContextManager;
 class ParentMap;
-class PseudoConstantAnalysis;
 class StackFrameContext;
 class Stmt;
 class VarDecl;
@@ -84,7 +83,6 @@ class AnalysisDeclContext {
   bool builtCFG = false;
   bool builtCompleteCFG = false;
   std::unique_ptr PM;
-  std::unique_ptr PCA;
   std::unique_ptr CFA;
 
   llvm::BumpPtrAllocator A;
@@ -175,7 +173,6 @@ public:
   bool isCFGBuilt() const { return builtCFG; }
 
   ParentMap ();
-  PseudoConstantAnalysis *getPseudoConstantAnalysis();
 
   using referenced_decls_iterator = const VarDecl * const *;
 

Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=342246=342245=342246=diff
==
--- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Fri Sep 14 10:27:27 2018
@@ -27,7 +27,6 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
-#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
 #include "clang/Analysis/BodyFarm.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CFGStmtMap.h"
@@ -292,12 +291,6 @@ ParentMap ::getParen
   return *PM;
 }
 
-PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
-  if (!PCA)
-PCA.reset(new PseudoConstantAnalysis(getBody()));
-  return PCA.get();
-}
-
 AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
   if (const auto *FD = dyn_cast(D)) {
 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=342246=342245=342246=diff
==
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Fri Sep 14 10:27:27 2018
@@ 

[clang-tools-extra] r342012 - [NFC] Fix build breakage due to missing dep caused by D51950

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 17:32:13 2018
New Revision: 342012

URL: http://llvm.org/viewvc/llvm-project?rev=342012=rev
Log:
[NFC] Fix build breakage due to missing dep caused by D51950

Modified:
clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt?rev=342012=342011=342012=diff
==
--- clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/performance/CMakeLists.txt Tue Sep 11 
17:32:13 2018
@@ -18,6 +18,7 @@ add_clang_library(clangTidyPerformanceMo
   LINK_LIBS
   clangAST
   clangASTMatchers
+  clangAnalysis
   clangBasic
   clangLex
   clangTidy


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r342006 - [clangtidy] Remove old copy of ExprMutationAnalyzer

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 15:59:46 2018
New Revision: 342006

URL: http://llvm.org/viewvc/llvm-project?rev=342006=rev
Log:
[clangtidy] Remove old copy of ExprMutationAnalyzer

Summary:
This is 2/2 of moving ExprMutationAnalyzer from clangtidy to clang/Analysis.
ExprMutationAnalyzer is moved to clang/Analysis in D51948.
This diff migrates existing usages within clangtidy to point to the new
location and remove the old copy of ExprMutationAnalyzer.

Reviewers: george.karpenkov, JonasToth

Reviewed By: george.karpenkov

Subscribers: mgorny, a.sidorin, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D51950

Removed:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.h
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp

clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp?rev=342006=342005=342006=diff
==
--- clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp Tue 
Sep 11 15:59:46 2018
@@ -9,9 +9,9 @@
 
 #include "ForRangeCopyCheck.h"
 #include "../utils/DeclRefExprUtils.h"
-#include "../utils/ExprMutationAnalyzer.h"
 #include "../utils/FixItHintUtils.h"
 #include "../utils/TypeTraits.h"
+#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 
 using namespace clang::ast_matchers;
 
@@ -88,8 +88,7 @@ bool ForRangeCopyCheck::handleCopyIsOnly
   // Because the fix (changing to `const auto &`) will introduce an unused
   // compiler warning which can't be suppressed.
   // Since this case is very rare, it is safe to ignore it.
-  if (!utils::ExprMutationAnalyzer(*ForRange.getBody(), Context)
-   .isMutated() &&
+  if (!ExprMutationAnalyzer(*ForRange.getBody(), Context).isMutated() 
&&
   !utils::decl_ref_expr::allDeclRefExprs(LoopVar, *ForRange.getBody(),
  Context)
.empty()) {

Modified: 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp?rev=342006=342005=342006=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
Tue Sep 11 15:59:46 2018
@@ -10,10 +10,10 @@
 #include "UnnecessaryValueParamCheck.h"
 
 #include "../utils/DeclRefExprUtils.h"
-#include "../utils/ExprMutationAnalyzer.h"
 #include "../utils/FixItHintUtils.h"
 #include "../utils/Matchers.h"
 #include "../utils/TypeTraits.h"
+#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
@@ -95,14 +95,14 @@ void UnnecessaryValueParamCheck::check(c
   // Do not trigger on non-const value parameters when they are mutated either
   // within the function body or within init expression(s) when the function is
   // a ctor.
-  if (utils::ExprMutationAnalyzer(*Function->getBody(), *Result.Context)
+  if (ExprMutationAnalyzer(*Function->getBody(), *Result.Context)
   .isMutated(Param))
 return;
   // CXXCtorInitializer might also mutate Param but they're not part of 
function
   // body, so check them separately here.
   if (const auto *Ctor = dyn_cast(Function)) {
 for (const auto *Init : Ctor->inits()) {
-  if (utils::ExprMutationAnalyzer(*Init->getInit(), *Result.Context)
+  if (ExprMutationAnalyzer(*Init->getInit(), *Result.Context)
   .isMutated(Param))
 return;
 }

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=342006=342005=342006=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Tue Sep 11 15:59:46 
2018
@@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyUtils
   ASTUtils.cpp
   DeclRefExprUtils.cpp
-  ExprMutationAnalyzer.cpp
   ExprSequence.cpp
   FixItHintUtils.cpp
   HeaderFileExtensionsUtils.cpp

Removed: 

r342005 - [NFC] Fix build breakage caused by D51948

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 15:41:14 2018
New Revision: 342005

URL: http://llvm.org/viewvc/llvm-project?rev=342005=rev
Log:
[NFC] Fix build breakage caused by D51948

Modified:
cfe/trunk/lib/Analysis/CMakeLists.txt

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=342005=342004=342005=diff
==
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Tue Sep 11 15:41:14 2018
@@ -34,6 +34,7 @@ add_clang_library(clangAnalysis
 
   LINK_LIBS
   clangAST
+  clangASTMatchers
   clangBasic
   clangLex
   )


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r341994 - [analyzer] Add ExprMutationAnalyzer

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 14:13:20 2018
New Revision: 341994

URL: http://llvm.org/viewvc/llvm-project?rev=341994=rev
Log:
[analyzer] Add ExprMutationAnalyzer

Summary:
This is 1/2 of moving ExprMutationAnalyzer from clangtidy to
clang/Analysis.
This diff along simply copies the ExprMutationAnalyzer over with trivial
modifications (e.g. include path, namespace)
2/2 will migrate existing usage of ExprMutationAnalyzer and remove the
original copy inside clangtidy.

Reviewers: george.karpenkov

Subscribers: mgorny, xazax.hun, szepet, a.sidorin, mikhail.ramalho, Szelethus, 
cfe-commits, JonasToth

Differential Revision: https://reviews.llvm.org/D51948

Added:
cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
cfe/trunk/unittests/Analysis/ExprMutationAnalyzerTest.cpp
Modified:
cfe/trunk/lib/Analysis/CMakeLists.txt
cfe/trunk/unittests/Analysis/CMakeLists.txt

Added: cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h?rev=341994=auto
==
--- cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h (added)
+++ cfe/trunk/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h Tue Sep 11 
14:13:20 2018
@@ -0,0 +1,52 @@
+//===-- ExprMutationAnalyzer.h 
===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
+
+#include 
+
+#include "clang/AST/AST.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+/// Analyzes whether any mutative operations are applied to an expression 
within
+/// a given statement.
+class ExprMutationAnalyzer {
+public:
+  ExprMutationAnalyzer(const Stmt , ASTContext )
+  : Stm(Stm), Context(Context) {}
+
+  bool isMutated(const Decl *Dec) { return findDeclMutation(Dec) != nullptr; }
+  bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
+  const Stmt *findMutation(const Expr *Exp);
+
+private:
+  bool isUnevaluated(const Expr *Exp);
+
+  const Stmt *findExprMutation(ArrayRef Matches);
+  const Stmt *findDeclMutation(ArrayRef Matches);
+  const Stmt *findDeclMutation(const Decl *Dec);
+
+  const Stmt *findDirectMutation(const Expr *Exp);
+  const Stmt *findMemberMutation(const Expr *Exp);
+  const Stmt *findArrayElementMutation(const Expr *Exp);
+  const Stmt *findCastMutation(const Expr *Exp);
+  const Stmt *findRangeLoopMutation(const Expr *Exp);
+  const Stmt *findReferenceMutation(const Expr *Exp);
+
+  const Stmt 
+  ASTContext 
+  llvm::DenseMap Results;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=341994=341993=341994=diff
==
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Tue Sep 11 14:13:20 2018
@@ -15,6 +15,7 @@ add_clang_library(clangAnalysis
   Consumed.cpp
   CodeInjector.cpp
   Dominators.cpp
+  ExprMutationAnalyzer.cpp
   FormatString.cpp
   LiveVariables.cpp
   OSLog.cpp

Added: cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp?rev=341994=auto
==
--- cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp (added)
+++ cfe/trunk/lib/Analysis/ExprMutationAnalyzer.cpp Tue Sep 11 14:13:20 2018
@@ -0,0 +1,308 @@
+//===-- ExprMutationAnalyzer.cpp 
--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+using namespace ast_matchers;
+
+namespace {
+
+AST_MATCHER_P(LambdaExpr, hasCaptureInit, const Expr *, E) {
+  return llvm::is_contained(Node.capture_inits(), E);
+}
+
+AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  const DeclStmt *const Range = Node.getRangeStmt();
+  return InnerMatcher.matches(*Range, Finder, Builder);
+}

[clang-tools-extra] r341986 - [clang-tidy] Handle sugared reference types in ExprMutationAnalyzer

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 13:05:37 2018
New Revision: 341986

URL: http://llvm.org/viewvc/llvm-project?rev=341986=rev
Log:
[clang-tidy] Handle sugared reference types in ExprMutationAnalyzer

Summary:
This handles cases like this:
```
typedef int& IntRef;
void mutate(IntRef);
void f() {
  int x;
  mutate(x);
}
```
where the param type is a sugared type (`TypedefType`) instead of a
reference type directly.

Note that another category of similar but different cases are already
handled properly before:
```
typedef int Int;
void mutate(Int&);
void f() {
  int x;
  mutate(x);
}
```

Reviewers: aaron.ballman, alexfh, george.karpenkov

Subscribers: xazax.hun, a.sidorin, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D50953

Modified:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=341986=341985=341986=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Tue Sep 
11 13:05:37 2018
@@ -48,11 +48,13 @@ AST_MATCHER_P(GenericSelectionExpr, hasC
 }
 
 const auto nonConstReferenceType = [] {
-  return referenceType(pointee(unless(isConstQualified(;
+  return hasUnqualifiedDesugaredType(
+  referenceType(pointee(unless(isConstQualified();
 };
 
 const auto nonConstPointerType = [] {
-  return pointerType(pointee(unless(isConstQualified(;
+  return hasUnqualifiedDesugaredType(
+  pointerType(pointee(unless(isConstQualified();
 };
 
 const auto isMoveOnly = [] {
@@ -185,12 +187,11 @@ const Stmt *ExprMutationAnalyzer::findDi
   // Treat calling `operator->()` of move-only classes as taking address.
   // These are typically smart pointers with unique ownership so we treat
   // mutation of pointee as mutation of the smart pointer itself.
-  const auto AsOperatorArrowThis = cxxOperatorCallExpr(
-  hasOverloadedOperatorName("->"),
-  callee(cxxMethodDecl(
-  ofClass(isMoveOnly()),
-  returns(hasUnqualifiedDesugaredType(nonConstPointerType(),
-  argumentCountIs(1), hasArgument(0, equalsNode(Exp)));
+  const auto AsOperatorArrowThis =
+  cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
+  callee(cxxMethodDecl(ofClass(isMoveOnly()),
+   
returns(nonConstPointerType(,
+  argumentCountIs(1), hasArgument(0, 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.

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp?rev=341986=341985=341986=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
(original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
Tue Sep 11 13:05:37 2018
@@ -168,6 +168,15 @@ TEST(ExprMutationAnalyzerTest, ByValueAr
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
 
+  AST = tooling::buildASTFromCode("void g(int*); void f() { int* x; g(x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST = tooling::buildASTFromCode("typedef int* IntPtr;"
+  "void g(IntPtr); void f() { int* x; g(x); 
}");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
   AST = tooling::buildASTFromCode(
   "void f() { struct A {}; A operator+(A, int); A x; x + 1; }");
   Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
@@ -184,6 +193,40 @@ TEST(ExprMutationAnalyzerTest, ByValueAr
   EXPECT_FALSE(isMutated(Results, AST.get()));
 }
 
+TEST(ExprMutationAnalyzerTest, ByConstValueArgument) {
+  auto AST =
+  tooling::buildASTFromCode("void g(const int); void f() { int x; g(x); 
}");
+  auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST = tooling::buildASTFromCode(
+  "void g(int* const); void f() { int* x; g(x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST =
+  tooling::buildASTFromCode("typedef 

[clang-tools-extra] r341967 - [clang-tidy] Handle unique owning smart pointers in ExprMutationAnalyzer

2018-09-11 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Sep 11 10:33:12 2018
New Revision: 341967

URL: http://llvm.org/viewvc/llvm-project?rev=341967=rev
Log:
[clang-tidy] Handle unique owning smart pointers in ExprMutationAnalyzer

Summary:
For smart pointers like std::unique_ptr which uniquely owns the
underlying object, treat the mutation of the pointee as mutation of the
smart pointer itself.

This gives better behavior for cases like this:
```
void f(std::vector> v) { // undesirable analyze result of 
`v` as not mutated.
  for (auto& p : v) {
  p->mutate(); // only const member function `operator->` is invoked on `p`
  }
}
```

Reviewers: hokein, george.karpenkov

Subscribers: xazax.hun, a.sidorin, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D50883

Modified:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=341967=341966=341967=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Tue Sep 
11 10:33:12 2018
@@ -51,6 +51,20 @@ const auto nonConstReferenceType = [] {
   return referenceType(pointee(unless(isConstQualified(;
 };
 
+const auto nonConstPointerType = [] {
+  return pointerType(pointee(unless(isConstQualified(;
+};
+
+const auto isMoveOnly = [] {
+  return cxxRecordDecl(
+  hasMethod(cxxConstructorDecl(isMoveConstructor(), unless(isDeleted(,
+  hasMethod(cxxMethodDecl(isMoveAssignmentOperator(), 
unless(isDeleted(,
+  unless(anyOf(hasMethod(cxxConstructorDecl(isCopyConstructor(),
+unless(isDeleted(,
+   hasMethod(cxxMethodDecl(isCopyAssignmentOperator(),
+   unless(isDeleted()));
+};
+
 } // namespace
 
 const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) {
@@ -168,6 +182,15 @@ const Stmt *ExprMutationAnalyzer::findDi
   const auto AsPointerFromArrayDecay =
   castExpr(hasCastKind(CK_ArrayToPointerDecay),
unless(hasParent(arraySubscriptExpr())), has(equalsNode(Exp)));
+  // Treat calling `operator->()` of move-only classes as taking address.
+  // These are typically smart pointers with unique ownership so we treat
+  // mutation of pointee as mutation of the smart pointer itself.
+  const auto AsOperatorArrowThis = cxxOperatorCallExpr(
+  hasOverloadedOperatorName("->"),
+  callee(cxxMethodDecl(
+  ofClass(isMoveOnly()),
+  returns(hasUnqualifiedDesugaredType(nonConstPointerType(),
+  argumentCountIs(1), hasArgument(0, 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.
@@ -197,8 +220,8 @@ const Stmt *ExprMutationAnalyzer::findDi
   const auto Matches =
   match(findAll(stmt(anyOf(AsAssignmentLhs, AsIncDecOperand, 
AsNonConstThis,
AsAmpersandOperand, AsPointerFromArrayDecay,
-   AsNonConstRefArg, AsLambdaRefCaptureInit,
-   AsNonConstRefReturn))
+   AsOperatorArrowThis, AsNonConstRefArg,
+   AsLambdaRefCaptureInit, AsNonConstRefReturn))
 .bind("stmt")),
 Stm, Context);
   return selectFirst("stmt", Matches);
@@ -250,6 +273,21 @@ const Stmt *ExprMutationAnalyzer::findRa
 }
 
 const Stmt *ExprMutationAnalyzer::findReferenceMutation(const Expr *Exp) {
+  // Follow non-const reference returned by `operator*()` of move-only classes.
+  // These are typically smart pointers with unique ownership so we treat
+  // mutation of pointee as mutation of the smart pointer itself.
+  const auto Ref = match(
+  findAll(cxxOperatorCallExpr(
+  hasOverloadedOperatorName("*"),
+  callee(cxxMethodDecl(ofClass(isMoveOnly()),
+   returns(hasUnqualifiedDesugaredType(
+   nonConstReferenceType(),
+  argumentCountIs(1), hasArgument(0, equalsNode(Exp)))
+  .bind("expr")),
+  Stm, Context);
+  if (const Stmt *S = findExprMutation(Ref))
+return S;
+
   // If 'Exp' is bound to a non-const reference, check all declRefExpr to that.
   const auto Refs = match(
   stmt(forEachDescendant(

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
URL: 

[clang-tools-extra] r341891 - Revert "Revert "[clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer""

2018-09-10 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 10 19:23:35 2018
New Revision: 341891

URL: http://llvm.org/viewvc/llvm-project?rev=341891=rev
Log:
Revert "Revert "[clang-tidy] Handle unresolved expressions in 
ExprMutationAnalyzer""

This is the same as D50619 plus fixes for buildbot failures on windows.
The test failures on windows are caused by -fdelayed-template-parsing
and is fixed by forcing -fno-delayed-template-parsing on test cases that
requires AST for uninstantiated templates.

Modified:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=341891=341890=341891=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Mon Sep 
10 19:23:35 2018
@@ -145,11 +145,16 @@ const Stmt *ExprMutationAnalyzer::findDi
 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);
+ hasArgument(0, equalsNode(Exp))),
+ callExpr(callee(expr(anyOf(
+ 
unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))),
+ cxxDependentScopeMemberExpr(
+ hasObjectExpression(equalsNode(Exp);
 
   // Taking address of 'Exp'.
   // We're assuming 'Exp' is mutated as soon as its address is taken, though in
@@ -165,10 +170,16 @@ const Stmt *ExprMutationAnalyzer::findDi
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));
+  const auto AsNonConstRefArg = anyOf(
+  callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam),
+  callExpr(callee(expr(anyOf(unresolvedLookupExpr(), 
unresolvedMemberExpr(),
+ cxxDependentScopeMemberExpr(),
+ hasType(templateTypeParmType(),
+   hasAnyArgument(equalsNode(Exp))),
+  cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp;
 
   // Captured by a lambda by reference.
   // If we're initializing a capture with 'Exp' directly then we're 
initializing
@@ -195,9 +206,12 @@ const Stmt *ExprMutationAnalyzer::findDi
 
 const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) {
   // Check whether any member of 'Exp' is mutated.
-  const auto MemberExprs = match(
-  findAll(memberExpr(hasObjectExpression(equalsNode(Exp))).bind("expr")),
-  Stm, Context);
+  const auto MemberExprs =
+  
match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))),
+   cxxDependentScopeMemberExpr(
+   hasObjectExpression(equalsNode(Exp)
+.bind("expr")),
+Stm, Context);
   return findExprMutation(MemberExprs);
 }
 

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp?rev=341891=341890=341891=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
(original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
Mon Sep 10 19:23:35 2018
@@ -114,6 +114,29 @@ TEST(ExprMutationAnalyzerTest, NonConstM
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
 }
 
+TEST(ExprMutationAnalyzerTest, AssumedNonConstMemberFunc) {
+  auto AST = tooling::buildASTFromCodeWithArgs(
+  "struct X { template  void mf(); };"
+  "template  void f() { X x; x.mf(); }",
+  {"-fno-delayed-template-parsing"});
+  auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
+
+  AST = tooling::buildASTFromCodeWithArgs(
+  

[clang-tools-extra] r341886 - Revert "[clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer"

2018-09-10 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 10 16:58:04 2018
New Revision: 341886

URL: http://llvm.org/viewvc/llvm-project?rev=341886=rev
Log:
Revert "[clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer"

Summary:
Tests somehow break on windows (and only on windows)
http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/builds/13003
http://lab.llvm.org:8011/builders/clang-x86-windows-msvc2015/builds/13747

I have yet figure out why so reverting to unbreak first.

Reviewers: george.karpenkov

Subscribers: xazax.hun, a.sidorin, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D51898

Modified:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=341886=341885=341886=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Mon Sep 
10 16:58:04 2018
@@ -145,16 +145,11 @@ const Stmt *ExprMutationAnalyzer::findDi
 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 @@ const Stmt *ExprMutationAnalyzer::findDi
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::findDi
 
 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);
 }
 

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp?rev=341886=341885=341886=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
(original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
Mon Sep 10 16:58:04 2018
@@ -114,26 +114,6 @@ TEST(ExprMutationAnalyzerTest, NonConstM
   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, 

[clang-tools-extra] r341848 - [clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer

2018-09-10 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Mon Sep 10 11:05:13 2018
New Revision: 341848

URL: http://llvm.org/viewvc/llvm-project?rev=341848=rev
Log:
[clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer

Summary:
- If a function is unresolved, assume it mutates its arguments
- Follow unresolved member expressions for nested mutations

Reviewers: aaron.ballman, JonasToth, george.karpenkov

Subscribers: xazax.hun, a.sidorin, cfe-commits

Differential Revision: https://reviews.llvm.org/D50619

Modified:
clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp?rev=341848=341847=341848=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/ExprMutationAnalyzer.cpp Mon Sep 
10 11:05:13 2018
@@ -145,11 +145,16 @@ const Stmt *ExprMutationAnalyzer::findDi
 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);
+ hasArgument(0, equalsNode(Exp))),
+ callExpr(callee(expr(anyOf(
+ 
unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))),
+ cxxDependentScopeMemberExpr(
+ hasObjectExpression(equalsNode(Exp);
 
   // Taking address of 'Exp'.
   // We're assuming 'Exp' is mutated as soon as its address is taken, though in
@@ -165,10 +170,16 @@ const Stmt *ExprMutationAnalyzer::findDi
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));
+  const auto AsNonConstRefArg = anyOf(
+  callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam),
+  callExpr(callee(expr(anyOf(unresolvedLookupExpr(), 
unresolvedMemberExpr(),
+ cxxDependentScopeMemberExpr(),
+ hasType(templateTypeParmType(),
+   hasAnyArgument(equalsNode(Exp))),
+  cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp;
 
   // Captured by a lambda by reference.
   // If we're initializing a capture with 'Exp' directly then we're 
initializing
@@ -195,9 +206,12 @@ const Stmt *ExprMutationAnalyzer::findDi
 
 const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) {
   // Check whether any member of 'Exp' is mutated.
-  const auto MemberExprs = match(
-  findAll(memberExpr(hasObjectExpression(equalsNode(Exp))).bind("expr")),
-  *Stm, *Context);
+  const auto MemberExprs =
+  
match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))),
+   cxxDependentScopeMemberExpr(
+   hasObjectExpression(equalsNode(Exp)
+.bind("expr")),
+*Stm, *Context);
   return findExprMutation(MemberExprs);
 }
 

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp?rev=341848=341847=341848=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
(original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ExprMutationAnalyzerTest.cpp 
Mon Sep 10 11:05:13 2018
@@ -114,6 +114,26 @@ TEST(ExprMutationAnalyzerTest, NonConstM
   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(); 
}");
+  

r340547 - [ASTMatchers] Let hasObjectExpression also support UnresolvedMemberExpr, CXXDependentScopeMemberExpr

2018-08-23 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Thu Aug 23 10:16:06 2018
New Revision: 340547

URL: http://llvm.org/viewvc/llvm-project?rev=340547=rev
Log:
[ASTMatchers] Let hasObjectExpression also support UnresolvedMemberExpr, 
CXXDependentScopeMemberExpr

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D50617

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=340547=340546=340547=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Thu Aug 23 10:16:06 2018
@@ -4668,6 +4668,20 @@ with withInitializer matching (1)
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html;>CXXDependentScopeMemberExprhasObjectExpressionMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches a 
member expression where the object expression is
+matched by a given matcher.
+
+Given
+  struct X { int m; };
+  void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))
+  matches "x.m" and "m"
+with hasObjectExpression(...)
+  matching "x" and the implicit object expression of "m" which has type X*.
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html;>CXXForRangeStmthasBodyMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>Stmt 
InnerMatcher
 Matches a 'for', 'while', 
'do while' statement or a function
 definition that has a given body.
@@ -6692,6 +6706,20 @@ Example matches true (matcher = hasUnary
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html;>UnresolvedMemberExprhasObjectExpressionMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches a 
member expression where the object expression is
+matched by a given matcher.
+
+Given
+  struct X { int m; };
+  void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))
+  matches "x.m" and "m"
+with hasObjectExpression(...)
+  matching "x" and the implicit object expression of "m" which has type X*.
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html;>UnresolvedUsingTypehasDeclarationconst Matcherhttp://clang.llvm.org/doxygen/classclang_1_1Decl.html;>Decl  
InnerMatcher
 Matches a node if 
the declaration associated with that node
 matches the given matcher.

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=340547=340546=340547=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Aug 23 10:16:06 2018
@@ -4825,8 +4825,17 @@ AST_MATCHER_P(MemberExpr, member,
 ///   matches "x.m" and "m"
 /// with hasObjectExpression(...)
 ///   matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(MemberExpr, hasObjectExpression,
-  internal::Matcher, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+hasObjectExpression,
+AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+CXXDependentScopeMemberExpr),
+internal::Matcher, InnerMatcher) {
+  if (const auto *E = dyn_cast())
+if (E->isImplicitAccess())
+  return false;
+  if (const auto *E = dyn_cast())
+if (E->isImplicitAccess())
+  return false;
   return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
 }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=340547=340546=340547=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Thu Aug 23 
10:16:06 2018
@@ -1517,6 +1517,26 @@ TEST(HasObjectExpression, MatchesBaseOfV
 "struct X { int m; }; void f(X* x) { x->m; }",
 memberExpr(hasObjectExpression(
   hasType(pointsTo(recordDecl(hasName("X";
+  EXPECT_TRUE(matches("template  struct X { void f() { T t; t.m; } 
};",
+  cxxDependentScopeMemberExpr(hasObjectExpression(
+  declRefExpr(to(namedDecl(hasName("t";
+  EXPECT_TRUE(
+  matches("template  struct X { void f() { T t; t->m; } };",
+  cxxDependentScopeMemberExpr(hasObjectExpression(
+  

r339530 - [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sun Aug 12 16:30:05 2018
New Revision: 339530

URL: http://llvm.org/viewvc/llvm-project?rev=339530=rev
Log:
[ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D50605

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=339530=339529=339530=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Sun Aug 12 16:30:05 2018
@@ -4854,6 +4854,25 @@ match Base.
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html;>CXXUnresolvedConstructExprhasAnyArgumentMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches any argument 
of a call expression or a constructor call
+expression, or an ObjC-message-send expression.
+
+Given
+  void x(int, int, int) { int y; x(1, y, 42); }
+callExpr(hasAnyArgument(declRefExpr()))
+  matches x(1, y, 42)
+with hasAnyArgument(...)
+  matching y
+
+For ObjectiveC, given
+  @interface I - (void) f:(int) y; @end
+  void foo(I *i) { [i f:12]; }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
+  matches [i f:12]
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1CallExpr.html;>CallExprcalleeMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Decl.html;>Decl 
InnerMatcher
 Matches if the call 
expression's callee's declaration matches the
 given matcher.
@@ -5938,8 +5957,8 @@ nestedNameSpecifier(specifiesType(
 
 
 
-Matcherhttp://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasAnyArgumentMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
-Matches any argument 
of a call expression or a constructor call
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasAnyArgumentMatcherhttp://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches any argument 
of a call expression or a constructor call
 expression, or an ObjC-message-send expression.
 
 Given

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=339530=339529=339530=diff
==
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sun Aug 12 16:30:05 2018
@@ -3426,16 +3426,22 @@ public:
   unsigned arg_size() const { return NumArgs; }
 
   using arg_iterator = Expr **;
+  using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
   arg_iterator arg_end() { return arg_begin() + NumArgs; }
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
 
   using const_arg_iterator = const Expr* const *;
+  using const_arg_range = llvm::iterator_range;
 
   const_arg_iterator arg_begin() const { return getTrailingObjects(); }
   const_arg_iterator arg_end() const {
 return arg_begin() + NumArgs;
   }
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
+  }
 
   Expr *getArg(unsigned I) {
 assert(I < NumArgs && "Argument index out-of-range");

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=339530=339529=339530=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sun Aug 12 16:30:05 2018
@@ -3565,9 +3565,9 @@ AST_MATCHER(CXXCtorInitializer, isMember
 /// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
 ///   matches [i f:12]
 AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
-  AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
-  CXXConstructExpr,
-  ObjCMessageExpr),
+  AST_POLYMORPHIC_SUPPORTED_TYPES(
+  CallExpr, CXXConstructExpr,
+  CXXUnresolvedConstructExpr, ObjCMessageExpr),
   internal::Matcher, InnerMatcher) {
   for (const Expr *Arg : Node.arguments()) {
 BoundNodesTreeBuilder Result(*Builder);

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=339530=339529=339530=diff

r339522 - [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sun Aug 12 10:34:36 2018
New Revision: 339522

URL: http://llvm.org/viewvc/llvm-project?rev=339522=rev
Log:
[ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D50606

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=339522=339521=339522=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Sun Aug 12 10:34:36 2018
@@ -866,6 +866,17 @@ cxxDeleteExpr()
 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxDependentScopeMemberExprMatcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html;>CXXDependentScopeMemberExpr...
+Matches 
member expressions where the actual member referenced could not be
+resolved because the base expression or the member name was dependent.
+
+Given
+  template class T void f() { T t; t.g(); }
+cxxDependentScopeMemberExpr()
+  matches t.g
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxDynamicCastExprMatcherhttp://clang.llvm.org/doxygen/classclang_1_1CXXDynamicCastExpr.html;>CXXDynamicCastExpr...
 Matches a 
dynamic_cast expression.
 
@@ -1455,6 +1466,20 @@ unresolvedLookupExpr()
   matches fooT() 
 
 
+Matcherhttp://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtunresolvedMemberExprMatcherhttp://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html;>UnresolvedMemberExpr...
+Matches 
unresolved member expressions.
+
+Given
+  struct X {
+template class T void f();
+void g();
+  };
+  template class T void h() { X x; x.fT(); x.g(); }
+unresolvedMemberExpr()
+  matches x.fT
+
+
+
 Matcherhttp://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtuserDefinedLiteralMatcherhttp://clang.llvm.org/doxygen/classclang_1_1UserDefinedLiteral.html;>UserDefinedLiteral...
 Matches user 
defined literal operator call.
 
@@ -1598,7 +1623,7 @@ Given:
   short i = 1;
   int j = 42;
   decltype(i + j) result = i + j;
-decltypeType() 
+decltypeType()
   matches "decltype(i + j)"
 
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=339522=339521=339522=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sun Aug 12 10:34:36 2018
@@ -1141,6 +1141,34 @@ extern const internal::VariadicDynCastAl
 ///   matches this->x, x, y.x, a, this->b
 extern const internal::VariadicDynCastAllOfMatcher 
memberExpr;
 
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+///   struct X {
+/// template  void f();
+/// void g();
+///   };
+///   template  void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+///   matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the member name was dependent.
+///
+/// Given
+/// \code
+///   template  void f() { T t; t.g(); }
+/// \endcode
+/// cxxDependentScopeMemberExpr()
+///   matches t.g
+extern const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
+
 /// Matches call expressions.
 ///
 /// Example matches x.y() and y()

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=339522=339521=339522=diff
==
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Sun Aug 12 10:34:36 2018
@@ -610,6 +610,10 @@ const internal::VariadicDynCastAllOfMatc
 const internal::VariadicAllOfMatcher stmt;
 const internal::VariadicDynCastAllOfMatcher declStmt;
 const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
 const internal::VariadicDynCastAllOfMatcher callExpr;
 const internal::VariadicDynCastAllOfMatcher lambdaExpr;
 const internal::VariadicDynCastAllOfMatcher

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: 

[clang-tools-extra] r338903 - Use ExprMutationAnalyzer in performance-unnecessary-value-param

2018-08-03 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Fri Aug  3 10:23:37 2018
New Revision: 338903

URL: http://llvm.org/viewvc/llvm-project?rev=338903=rev
Log:
Use ExprMutationAnalyzer in performance-unnecessary-value-param

Summary:
This yields better recall as ExprMutationAnalyzer is more accurate.

One common pattern this check is now able to catch is:
```
void foo(std::vector v) {
  for (const auto& elm : v) {
// ...
  }
}
```

Reviewers: george.karpenkov

Subscribers: a.sidorin, cfe-commits

Differential Revision: https://reviews.llvm.org/D50102

Modified:

clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp

clang-tools-extra/trunk/test/clang-tidy/performance-unnecessary-value-param.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp?rev=338903=338902=338903=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
Fri Aug  3 10:23:37 2018
@@ -10,6 +10,7 @@
 #include "UnnecessaryValueParamCheck.h"
 
 #include "../utils/DeclRefExprUtils.h"
+#include "../utils/ExprMutationAnalyzer.h"
 #include "../utils/FixItHintUtils.h"
 #include "../utils/Matchers.h"
 #include "../utils/TypeTraits.h"
@@ -31,14 +32,6 @@ std::string paramNameOrIndex(StringRef N
   .str();
 }
 
-template 
-bool isSubset(const S , const S ) {
-  for (const auto  : SubsetCandidate)
-if (SupersetCandidate.count(E) == 0)
-  return false;
-  return true;
-}
-
 bool isReferencedOutsideOfCallExpr(const FunctionDecl ,
ASTContext ) {
   auto Matches = match(declRefExpr(to(functionDecl(equalsNode())),
@@ -98,43 +91,55 @@ void UnnecessaryValueParamCheck::registe
 void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult ) 
{
   const auto *Param = Result.Nodes.getNodeAs("param");
   const auto *Function = Result.Nodes.getNodeAs("functionDecl");
-  const size_t Index = std::find(Function->parameters().begin(),
- Function->parameters().end(), Param) -
-   Function->parameters().begin();
-  bool IsConstQualified =
-  Param->getType().getCanonicalType().isConstQualified();
 
-  auto AllDeclRefExprs = utils::decl_ref_expr::allDeclRefExprs(
-  *Param, *Function, *Result.Context);
-  auto ConstDeclRefExprs = utils::decl_ref_expr::constReferenceDeclRefExprs(
-  *Param, *Function, *Result.Context);
-
-  // Do not trigger on non-const value parameters when they are not only used 
as
-  // const.
-  if (!isSubset(AllDeclRefExprs, ConstDeclRefExprs))
+  // Do not trigger on non-const value parameters when they are mutated either
+  // within the function body or within init expression(s) when the function is
+  // a ctor.
+  if (utils::ExprMutationAnalyzer(Function->getBody(), Result.Context)
+  .isMutated(Param))
 return;
+  // CXXCtorInitializer might also mutate Param but they're not part of 
function
+  // body, so check them separately here.
+  if (const auto *Ctor = dyn_cast(Function)) {
+for (const auto *Init : Ctor->inits()) {
+  if (utils::ExprMutationAnalyzer(Init->getInit(), Result.Context)
+  .isMutated(Param))
+return;
+}
+  }
+
+  const bool IsConstQualified =
+  Param->getType().getCanonicalType().isConstQualified();
 
   // If the parameter is non-const, check if it has a move constructor and is
   // only referenced once to copy-construct another object or whether it has a
   // move assignment operator and is only referenced once when copy-assigned.
   // In this case wrap DeclRefExpr with std::move() to avoid the unnecessary
   // copy.
-  if (!IsConstQualified && AllDeclRefExprs.size() == 1) {
-auto CanonicalType = Param->getType().getCanonicalType();
-const auto   = **AllDeclRefExprs.begin();
-
-if (!hasLoopStmtAncestor(DeclRefExpr, *Function, *Result.Context) &&
-((utils::type_traits::hasNonTrivialMoveConstructor(CanonicalType) &&
-  utils::decl_ref_expr::isCopyConstructorArgument(
-  DeclRefExpr, *Function, *Result.Context)) ||
- (utils::type_traits::hasNonTrivialMoveAssignment(CanonicalType) &&
-  utils::decl_ref_expr::isCopyAssignmentArgument(
-  DeclRefExpr, *Function, *Result.Context {
-  handleMoveFix(*Param, DeclRefExpr, *Result.Context);
-  return;
+  if (!IsConstQualified) {
+auto AllDeclRefExprs = utils::decl_ref_expr::allDeclRefExprs(
+*Param, *Function, *Result.Context);
+if (AllDeclRefExprs.size() == 1) {
+  auto CanonicalType = Param->getType().getCanonicalType();
+  const auto  = **AllDeclRefExprs.begin();
+
+  if (!hasLoopStmtAncestor(DeclRefExpr, *Function, *Result.Context) 

[clang-tools-extra] r336737 - Use ExprMutationAnalyzer in performance-for-range-copy

2018-07-10 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Tue Jul 10 15:51:06 2018
New Revision: 336737

URL: http://llvm.org/viewvc/llvm-project?rev=336737=rev
Log:
Use ExprMutationAnalyzer in performance-for-range-copy

Summary:
This gives better coverage to the check as ExprMutationAnalyzer is more
accurate comparing to isOnlyUsedAsConst.

Majority of wins come from const usage of member field, e.g.:
for (auto widget : container) { // copy of loop variable
  if (widget.type == BUTTON) { // const usage only recognized by 
ExprMutationAnalyzer
// ...
  }
}

Reviewers: george.karpenkov

Subscribers: a.sidorin, cfe-commits

Differential Revision: https://reviews.llvm.org/D48854

Modified:
clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp

Modified: clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp?rev=336737=336736=336737=diff
==
--- clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp Tue 
Jul 10 15:51:06 2018
@@ -8,7 +8,7 @@
 
//===--===//
 
 #include "ForRangeCopyCheck.h"
-#include "../utils/DeclRefExprUtils.h"
+#include "../utils/ExprMutationAnalyzer.h"
 #include "../utils/FixItHintUtils.h"
 #include "../utils/TypeTraits.h"
 
@@ -79,8 +79,8 @@ bool ForRangeCopyCheck::handleCopyIsOnly
   utils::type_traits::isExpensiveToCopy(LoopVar.getType(), Context);
   if (LoopVar.getType().isConstQualified() || !Expensive || !*Expensive)
 return false;
-  if (!utils::decl_ref_expr::isOnlyUsedAsConst(LoopVar, *ForRange.getBody(),
-   Context))
+  if (utils::ExprMutationAnalyzer(ForRange.getBody(), )
+  .isMutated())
 return false;
   diag(LoopVar.getLocation(),
"loop variable is copied but only used as const reference; consider "

Modified: clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp?rev=336737=336736=336737=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp 
(original)
+++ clang-tools-extra/trunk/test/clang-tidy/performance-for-range-copy.cpp Tue 
Jul 10 15:51:06 2018
@@ -117,6 +117,11 @@ struct Mutable {
   ~Mutable() {}
 };
 
+struct Point {
+  ~Point() {}
+  int x, y;
+};
+
 Mutable& operator<<(Mutable , bool B) {
   Out.setBool(B);
   return Out;
@@ -214,6 +219,15 @@ void positiveOnlyUsedAsConstArguments()
   }
 }
 
+void positiveOnlyAccessedFieldAsConst() {
+  for (auto UsedAsConst : View>()) {
+// CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but 
only used as const reference; consider making it a const reference 
[performance-for-range-copy]
+// CHECK-FIXES: for (const auto& UsedAsConst : View>()) {
+use(UsedAsConst.x);
+use(UsedAsConst.y);
+  }
+}
+
 void positiveOnlyUsedInCopyConstructor() {
   for (auto A : View>()) {
 // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but 
only used as const reference; consider making it a const reference 
[performance-for-range-copy]


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D17586: Add a new check, readability-redundant-string-init, that checks unnecessary string initializations.

2016-02-25 Thread Shuai Wang via cfe-commits
shuaiwang marked an inline comment as done.
shuaiwang added a comment.

http://reviews.llvm.org/D17586



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D17586: Add a new check, readability-redundant-string-init, that checks unnecessary string initializations.

2016-02-25 Thread Shuai Wang via cfe-commits
shuaiwang updated this revision to Diff 49114.
shuaiwang added a comment.

CHECK-FIXES for macro tests


http://reviews.llvm.org/D17586

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantStringInitCheck.cpp
  clang-tidy/readability/RedundantStringInitCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-string-init.rst
  test/clang-tidy/readability-redundant-string-init.cpp

Index: test/clang-tidy/readability-redundant-string-init.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-string-init.cpp
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template 
+class allocator {};
+template 
+class char_traits {};
+template , typename A = std::allocator>
+struct basic_string {
+  basic_string();
+  basic_string(const basic_string&);
+  basic_string(const C *, const A  = A());
+  ~basic_string();
+};
+typedef basic_string string;
+typedef basic_string wstring;
+}
+
+void f() {
+  std::string a = "";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+  // CHECK-FIXES: std::string a;
+  std::string b("");
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string b;
+  std::string c = R"()";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string c;
+  std::string d(R"()");
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string d;
+
+  std::string u = "u";
+  std::string w("w");
+  std::string x = R"(x)";
+  std::string y(R"(y)");
+  std::string z;
+}
+
+void g() {
+  std::wstring a = L"";
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring a;
+  std::wstring b(L"");
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring b;
+  std::wstring c = LR"()";
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring c;
+  std::wstring d(LR"()");
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring d;
+
+  std::wstring u = L"u";
+  std::wstring w(L"w");
+  std::wstring x = LR"(x)";
+  std::wstring y(LR"(y)");
+  std::wstring z;
+}
+
+template 
+void templ() {
+  std::string s = "";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string s;
+}
+
+#define M(x) x
+#define N { std::string s = ""; }
+// CHECK-FIXES: #define N { std::string s = ""; }
+
+void h() {
+  templ();
+  templ();
+
+  M({ std::string s = ""; })
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
+  // CHECK-FIXES: M({ std::string s; })
+
+  N
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+  // CHECK-FIXES: N
+  N
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+  // CHECK-FIXES: N
+}
Index: docs/clang-tidy/checks/readability-redundant-string-init.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-string-init.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-string-init
+
+readability-redundant-string-init
+=
+
+
+Finds unnecessary string initializations.
+
+Examples:
+
+.. code:: c++
+
+  // Initializing string with empty string literal is unnecessary.
+  std::string a = "";
+  std::string b("");
+
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -99,5 +99,6 @@
readability-redundant-control-flow
readability-redundant-smartptr-get
readability-redundant-string-cstr
+   readability-redundant-string-init
readability-simplify-boolean-expr
readability-uniqueptr-delete-release
Index: clang-tidy/readability/RedundantStringInitCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantStringInitCheck.h
@@ -0,0 +1,32 @@
+//===- RedundantStringInitCheck.h - clang-tidy --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
+#define 

Re: [PATCH] D17586: Add a new check, readability-redundant-string-init, that checks unnecessary string initializations.

2016-02-25 Thread Shuai Wang via cfe-commits
shuaiwang updated this revision to Diff 49108.
shuaiwang added a comment.

more test cases


http://reviews.llvm.org/D17586

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantStringInitCheck.cpp
  clang-tidy/readability/RedundantStringInitCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-string-init.rst
  test/clang-tidy/readability-redundant-string-init.cpp

Index: test/clang-tidy/readability-redundant-string-init.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-string-init.cpp
@@ -0,0 +1,83 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template 
+class allocator {};
+template 
+class char_traits {};
+template , typename A = std::allocator>
+struct basic_string {
+  basic_string();
+  basic_string(const basic_string&);
+  basic_string(const C *, const A  = A());
+  ~basic_string();
+};
+typedef basic_string string;
+typedef basic_string wstring;
+}
+
+void f() {
+  std::string a = "";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+  // CHECK-FIXES: std::string a;
+  std::string b("");
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string b;
+  std::string c = R"()";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string c;
+  std::string d(R"()");
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string d;
+
+  std::string u = "u";
+  std::string w("w");
+  std::string x = R"(x)";
+  std::string y(R"(y)");
+  std::string z;
+}
+
+void g() {
+  std::wstring a = L"";
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring a;
+  std::wstring b(L"");
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring b;
+  std::wstring c = LR"()";
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring c;
+  std::wstring d(LR"()");
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES: std::wstring d;
+
+  std::wstring u = L"u";
+  std::wstring w(L"w");
+  std::wstring x = LR"(x)";
+  std::wstring y(LR"(y)");
+  std::wstring z;
+}
+
+template 
+void templ() {
+  std::string s = "";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string s;
+}
+
+#define M(x) x
+#define N { std::string s = ""; }
+
+void h() {
+  templ();
+  templ();
+
+  M({ std::string s = ""; })
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
+  // CHECK-FIXES: M({ std::string s; })
+
+  N
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+  N
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
+}
Index: docs/clang-tidy/checks/readability-redundant-string-init.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-string-init.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-string-init
+
+readability-redundant-string-init
+=
+
+
+Finds unnecessary string initializations.
+
+Examples:
+
+.. code:: c++
+
+  // Initializing string with empty string literal is unnecessary.
+  std::string a = "";
+  std::string b("");
+
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -99,5 +99,6 @@
readability-redundant-control-flow
readability-redundant-smartptr-get
readability-redundant-string-cstr
+   readability-redundant-string-init
readability-simplify-boolean-expr
readability-uniqueptr-delete-release
Index: clang-tidy/readability/RedundantStringInitCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantStringInitCheck.h
@@ -0,0 +1,32 @@
+//===- RedundantStringInitCheck.h - clang-tidy --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace