On Thu, Jun 01, 2017 at 04:17:24PM -0600, Martin Sebor wrote:
> Very nice.  I think David already suggested handling other statements
> besides if (do/while), so let me just add for and switch (as in:
> 'switch (1) case SWAP (i, j);')

How's that one problematic, though?

> The location in the warning look like it could be improved to extend
> from just the first column to the whole macro argument but I don't
> suppose that's under the direct control of your patch.

Well, for e.g. the "in expasion" message we have a good location range:
  SWAP
  ^~~~
so do you mean this?
tmp = x;
^
?  But yea, it's outside the scope of this patch.

> Besides the statements already mentioned above, here are a couple
> of corner cases I noticed are not handled while playing with the
> patch:
> 
>   define M(x) x
> 
>   int f (int i)
>   {
>     if (i)
>       M (--i; --i);   // can this be handled?
> 
>     return i;
>   }
> 
> and
> 
>   define M(x) x; x
> 
>   int f (int i)
>   {
>     if (i)
>       M (--i; --i);   // seems like this should be handled
> 
>     return i;
>   }

Hmm, I was hoping my patch would warn for both examples, but it doesn't.  I'll
have to get back to this a ponder more.

> As an aside since it's outside the subset of the bigger problem
> you chose to solve, there is a related issue with macros that
> expand to an unparenthesized binary (and even some unary)
> expression:
> 
>   #define sum(x, y) x + y
> 
>   int n = 2 * sum (3, 5);
> 
> I'm not very familiar with this area of the parser but I would
> expect it to be relatively straightforward to extend your solution
> to handle this problem as well.

It'd certainly be useful to warn here.  But it doesn't seem to be an
easy warning to implement, to me.  E.g. warning for

  int n = 2 + sum (3, 5);

would be annoying, I suspect.

> > For this I had to dive into line_maps, macro maps, etc., so CCing David to 
> > check
> > if my understanding of that is reasonable (hadn't worked with them before).
> > 
> > I've included this warning in -Wall, because there should be no false 
> > positives
> > (fingers crossed) and for most cases the warning should be pretty cheap.
> > 
> > I probably should've added a fix-it hint for good measure, too ("you better 
> > wrap
> > the damn macro in do {} while (0)"), but that can be done as a follow-up.
> 
> A hint I'm sure would be helpful to a lot of users.  One caveat
> to be aware of is that wrapping an expression in a 'do { } while
> (0)' is not a viable solution when the value of the last statement
> is used.  In those cases, using the comma expression instead (in
> parentheses) is often the way to go.  I'd expect determining which
> to offer to be less than trivial.

This didn't occur to me at all.  Well, I still think we could just suggest
adding "do while (0)" and get away with that.

Thanks for taking a look!

        Marek

Reply via email to