<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks for the info! I'd be happy to port my current implementation to a clang-tidy checker if that would be a better fit.<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Nathan, to offer a bit more detail, the current implementation is very much tuned toward finding logic bugs that are likely to affect program behavior and to avoid warning on patterns that evaluate in an unexpected order but give the expected result anyway,
like the TWO + 2 example. There's a large room for debate as to which patterns we report or don't, and the right tuning for a clang warning or clang-tidy check is likely to be different than my current implementation. I think what I have right now is probably
over-tuned toward avoiding warning on possible-but-less-likely bugs. I'll be happy to accept feedback and tweak the check as necessary.<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I've attached a clang -verify test file for the current implementation that covers many interesting cases. I have three different warning types for evaluation purposes - the warnings containing '(hard)' are the most serious. The warnings containing '(latent)'
and '(cast)' are for patterns that are less likely to cause a problem - in the final implementation these would not be reported but they're useful to see while I'm evaluating the warnings on large codebases.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Regards,<br>
Brad<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Andi-Bogdan Postelnicu <andi@mozilla.com><br>
<b>Sent:</b> Sunday, February 14, 2021 4:46 PM<br>
<b>To:</b> Nathan James <n.james93@hotmail.co.uk><br>
<b>Cc:</b> Brad Moody <brad.moody@oracle.com>; Clang Dev <cfe-dev@lists.llvm.org><br>
<b>Subject:</b> [External] : Re: [cfe-dev] Misleading macro evaluation warning</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hello,<br>
<br>
Nathan thanks for bringing clang-tidy into discussion. I would highly prefer to have this as a clang-tidy checker due to the ease flexibility that clang-tooling is provided.<br>
Also if this will land to clang-tidy there could be also room to have a fixhint.<br>
<br>
Thanks,<br>
Andi<br>
<br>
> On 14 Feb 2021, at 07:06, Nathan James via cfe-dev <cfe-dev@lists.llvm.org> wrote:<br>
> <br>
> Hi Brad,<br>
> <br>
> Just for the record clang-tidy has a check, bugprone-macro-parentheses.<br>
> This check operates just on the preprocessor stage. It will flag macro<br>
> replacements where they expand to expressions which look like they<br>
> would be safer wrapped in parens. For your example this check wouldn't<br>
> flag the `TWO * 2` line, instead it flags `#define TWO 1 + 1`, This<br>
> obviously has some issues especially if that macro comes from a header<br>
> the user doesn't control.<br>
> <br>
> I'm split on whether this belongs in clang as a warning or as a clang-<br>
> tidy check. Where ever this warning goes some requirements for<br>
> upstreaming are:<br>
> - Create tests.<br>
> - Add diagnostic flags to control the warning(clang only).<br>
> - Test the warning on large code bases, llvm itself is the defacto<br>
> target to test against here. It'd be interesting to see how it handles<br>
> nested macro expansions, thats where false positives or false negatives<br>
> are likely to show up.<br>
> - *Optionally offer some fix-its to either suppress the warning or<br>
> change the code to what was likely intended. Maybe wrap parens around<br>
> the expression to silence the warning, or wrap parens around the macro<br>
> token for intended behaviour.<br>
> <br>
> There's also some potential corner cases to consider:<br>
> #define TWO 1 + 1<br>
> auto X = TWO + 2; // Should this warn??<br>
> auto Y = FloatVariable + TWO; // What about this, wrapping TWO in<br>
> parens can affect the result.<br>
> auto Z = TemplatedVar + TWO; // This should probably always warn.<br>
> <br>
> <br>
> ~Nathan James<br>
> <br>
>> On Sun, 2021-02-14 at 02:39 +0000, Brad Moody via cfe-dev wrote:<br>
>> Hi all,<br>
>> <br>
>> I have an implementation for a new clang compiler warning that I'd<br>
>> like to upstream and I'm looking for guidance on how to get the<br>
>> process started.<br>
>> <br>
>> The warning reports expressions inside macro expansions that evaluate<br>
>> in an unexpected way due to missing parens, either around a macro<br>
>> argument name or around the entire macro body. This is a super common<br>
>> mistake that has probably been made by anyone who has written a C<br>
>> macro in their life, but I'm not aware of any compilers or other<br>
>> tools that help catch these bugs.<br>
>> <br>
>> An example:<br>
>> #define TWO 1 + 1<br>
>> int f() {<br>
>> return TWO * 2; // Actually returns 3<br>
>> }<br>
>> <br>
>> Clang output:<br>
>> a.c:1:15: warning: misleading evaluation of expression in<br>
>> expansion of macro TWO due to missing parentheses<br>
>> #define TWO 1 + 1<br>
>> ^<br>
>> a.c:3:16: note: expression has higher precedence than expression<br>
>> inside macro body<br>
>> return TWO * 2;<br>
>> ^<br>
>> a.c:3:12: note: low precedence expression is hidden by expansion<br>
>> of macro TWO<br>
>> return TWO * 2;<br>
>> ^<br>
>> 1 warning generated.<br>
>> <br>
>> We've been using this warning internally for about a year now, but<br>
>> mostly on closed code so unfortunately I can't show those results<br>
>> here. I'm in the process of gathering results on open-source code now<br>
>> for evaluation purposes.<br>
>> <br>
>> So, what should be my next steps?<br>
>> <br>
>> Thanks,<br>
>> Brad Moody<br>
>> _______________________________________________<br>
>> cfe-dev mailing list<br>
>> cfe-dev@lists.llvm.org<br>
>> <a href="https://urldefense.com/v3/__https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev__;!!GqivPVa7Brio!KdVFc67UAK5P4yYIwTCJerEacXkvhYxywa3ABBbZcG-ir4qxPLWZLbHCZVg6X07m$">
https://urldefense.com/v3/__https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev__;!!GqivPVa7Brio!KdVFc67UAK5P4yYIwTCJerEacXkvhYxywa3ABBbZcG-ir4qxPLWZLbHCZVg6X07m$</a>
<br>
> <br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> cfe-dev@lists.llvm.org<br>
> <a href="https://urldefense.com/v3/__https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev__;!!GqivPVa7Brio!KdVFc67UAK5P4yYIwTCJerEacXkvhYxywa3ABBbZcG-ir4qxPLWZLbHCZVg6X07m$">
https://urldefense.com/v3/__https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev__;!!GqivPVa7Brio!KdVFc67UAK5P4yYIwTCJerEacXkvhYxywa3ABBbZcG-ir4qxPLWZLbHCZVg6X07m$</a>
<br>
</div>
</span></font></div>
</body>
</html>