<div dir="ltr"><div>Hello again,</div><div><br></div>I'm working on putenv->setenv rewrite as a way to get my feet wet with clang-tidy<div><br></div><div>I managed to get detection working fine. Now I'm starting working on recommending fixes and I'd like to reduce the matches to what I'm able to rewrite.</div><div>The first should capture a simple putenv("VAR=VALUE"). The following works in clang-query:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>clang-query> let p callee(functionDecl(hasName(":<wbr>:putenv")))</div></div><div><div>clang-query> match callExpr(p, argumentCountIs(1), hasArgument(0, stringLiteral().bind("arg")))</div></div><div><div><br></div></div><div><div>Match #1:</div></div><div><div><br></div></div><div><div>/tmp/mav_clang/build/../third_<wbr>party/clang-tools-extra/test/c<wbr>lang-tidy/misc-putenv.cpp:7:10<wbr>: note: "arg" binds here</div></div><div><div>  putenv("VAR=VALUE");</div></div><div><div>         ^~~~~~~~~~~</div></div><div><div>/tmp/mav_clang/build/../third_<wbr>party/clang-tools-extra/test/c<wbr>lang-tidy/misc-putenv.cpp:7:3: note: "root" binds here</div></div><div><div>  putenv("VAR=VALUE");</div></div><div><div>  ^~~~~~~~~~~~~~~~~~~</div></div><div><div>1 match.</div></div></blockquote><div><br></div><div>But when I convert it to code in a clang-tidy check, as in:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>  auto putenvCallee = callee(functionDecl(hasName(":<wbr>:putenv")));</div></div><div><div><br></div></div><div><div>  auto putenvConstantCallMatcher =</div></div><div><div>      callExpr(putenvCallee, argumentCountIs(1),</div></div><div><div>                   hasArgument(0, stringLiteral().bind("putenv_a<wbr>rg")))</div></div><div><div>          .bind("putenv_call");</div></div><div><br></div><div>  Finder->addMatcher(putenvConstantCallMatcher, this);<br></div><div><br></div></blockquote><div>the match fails.</div><div><br></div><div>I'm a bit puzzled by clang-query behaving differently from the compiled checker.</div><div><br></div><div>If I replace the stringLiteral() matcher with expr(), then it does match, but it is too loose of a match.</div><div><br></div><div>I'm probably missing something obvious and I would appreciate any help.</div><div>[feel free to throw away my matchers and show me the proper way to match ::putenv("a string") and not ::putenv(a_char_ptr_var)]</div><div><br></div><div>Thanks a lot,</div><div><br></div><div>   Maurizio</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 13, 2017 at 11:51 AM, Richard via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">[Please reply *only* to the list and do not include my email directly<br>
in the To: or Cc: of your reply; otherwise I will not see your reply.<br>
Thanks.]<br>
<br>
In article <<a href="mailto:CAAeLbQKtKAHE5RAweH2a0n%2BDq8EwOKmjy8n2n1bMVYrDCdhQOQ@mail.gmail.com" target="_blank">CAAeLbQKtKAHE5RAweH2a0n+Dq8Ew<wbr>OKmjy8n2n1bMVYrDCdhQOQ@mail.gm<wbr>ail.com</a>>,<br>
<span>    Maurizio Vitale via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> writes:<br>
<br>
> The idea is to find all uses of putenv and replace them w/ setenv. This<br>
> requires analyzing the argument to discover constant parts in it (setenv<br>
> require a separate variable name). It also require to check that the<br>
> argument is not modified (or such modifications need also to be replaces w/<br>
> setenvs).<br>
<br>
</span>In addition to what's already been mentioned, I would recommend<br>
implementing your check in stages:<br>
<br>
1. Constant string arguments<br>
<br>
    putenv("FOO=bar");<br>
<br>
    =><br>
<br>
    setenv("FOO", "bar", 1);<br>
<br>
2. Constant environment variable names<br>
<br>
    char buff[256];<br>
    sprintf(buff, "FOO=%d", value);<br>
    putenv(buff);<br>
<br>
    =><br>
<br>
    char buff[256];<br>
    sprintf(buff, "%d", value);<br>
    setenv("FOO", buff, 1);<br>
<br>
3. Varying environment variable names<br>
<br>
    .... you get the idea :)<br>
<br>
Basically start with the simplest case and get that working and then<br>
enhance for subsequent cases.  You can even submit incremental work<br>
for review and incorporation into clang-tidy this way.  It is better<br>
to have a working check that handles simple cases and does no harm on<br>
complex cases than to wait for a check that covers 100% of everything.<br>
<span class="gmail-m_6485977864535989160m_6626702274774866228m_-3622005460291744178HOEnZb"><font color="#888888">--<br>
"The Direct3D Graphics Pipeline" free book <<a href="http://tinyurl.com/d3d-pipeline" rel="noreferrer" target="_blank">http://tinyurl.com/d3d-pipeli<wbr>ne</a>><br>
            The Terminals Wiki <<a href="http://terminals-wiki.org" rel="noreferrer" target="_blank">http://terminals-wiki.org</a>><br>
     The Computer Graphics Museum <<a href="http://ComputerGraphicsMuseum.org" rel="noreferrer" target="_blank">http://ComputerGraphicsMuseum<wbr>.org</a>><br>
  Legalize Adulthood! (my blog) <<a href="http://LegalizeAdulthood.wordpress.com" rel="noreferrer" target="_blank">http://LegalizeAdulthood.word<wbr>press.com</a>><br>
</font></span><div class="gmail-m_6485977864535989160m_6626702274774866228m_-3622005460291744178HOEnZb"><div class="gmail-m_6485977864535989160m_6626702274774866228m_-3622005460291744178h5">______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div></div>