[PATCH] clang-tidy checker that enforce proper parentheses in macros
Daniel Marjamäki
daniel.marjamaki at evidente.se
Tue Jun 2 11:28:47 PDT 2015
> Did you encounter any cases when the code broke after applying fixes?
No I did not. The projects compiled fine after the fixes.
> How many instances of the warning does the latest version of the check produce on the same set of projects where you saw 47k warnings initially?
I can't say exactly right now. It's a little less as far as I know.
> I would also like to see an estimate of the false positive rate (from a random sample of 100 warnings).
I fixed 300 warnings with -fix and saw no compiler warnings.
However I looked at 100 random warnings and saw 5 fp (for type definitions)! I can try to write a heuristic for some of those.
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:141
@@ +140,3 @@
+
+ // Dont warn after hash/hashhash or before hashhash.
+ if (Prev == tok::hash || Prev == tok::hashhash || Next == tok::hashhash)
----------------
alexfh wrote:
> nit: "Don't"
Fixed
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:149
@@ +148,3 @@
+
+ // String concatenation
+ if (isStringLiteral(Prev) || isStringLiteral(Next))
----------------
alexfh wrote:
> nit: Add a trailing period.
Fixed.
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:158
@@ +157,3 @@
+
+ // Initialisation.
+ if (Next == tok::l_paren)
----------------
alexfh wrote:
> nit: Initialization.
ah.. I missed this.. I'll fix it immediately locally..
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:68
@@ +67,3 @@
+ } else if (Indent <= 0 &&
+ (Tok.is(tok::plus) || Tok.is(tok::minus) || Tok.is(tok::star) ||
+ Tok.is(tok::slash) || Tok.is(tok::percent) ||
----------------
alexfh wrote:
> This looks like a reason to move isOneOf from clang::format::FormatToken (tools/clang/lib/Format/FormatToken.h) to clang::Token. It would greatly simplify this and similar conditions.
Yes... I added a new patch today where this code was rewritten. I did not move isOneOf.. do you still I should do it?
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:77
@@ +76,3 @@
+ !Tok.is(tok::minus) && (TI + 1) != TE &&
+ (TI + 1)->is(tok::numeric_constant) && (TI + 2) == TE) {
+ return;
----------------
danielmarjamaki wrote:
> danielmarjamaki wrote:
> > danielmarjamaki wrote:
> > > alexfh wrote:
> > > > danielmarjamaki wrote:
> > > > > alexfh wrote:
> > > > > > `TI + 2 == TE` implies `TI + 1 != TE`. I'd also put it next to `TI == MI->tokens_begin()`.
> > > > > Yes that is implied. But are you sure it's not UB? I wanted to avoid undefined behaviour when creating an out-of-bounds pointer (calculating TI+2 without checking TI+1). is the buffer always padded with extra elements after TE?
> > > > Why does the buffer need to be padded with something when you compare iterators without dereferencing them? I didn't find any violation of the preconditions for random access iterators (http://en.cppreference.com/w/cpp/concept/RandomAccessIterator).
> > > TI is a pointer.
> > >
> > > I refer to 6.5.6.8 in the C standard (about pointer addition):
> > >
> > > If both the pointer operand and the result point to elements of the same array object, or one past the last
> > > element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
> > >
> > hmm.. maybe I was confused. I thought it was a pointer addition.. however random access iterators should not overflow neither as far as I know..
> I can't find that TI+2 is UB right now in the specification.
>
> However for information this sample code:
>
>
> ```
> #include <vector>
>
> int main() {
> std::vector<int> x;
> x.push_back(123);
> std::vector<int>::iterator it = x.begin();
> if (it+2 == x.end()) {}
> return 0;
> }
> ```
>
> When I compile and run it with the STL assertions turned on I get a fault..
>
> ```
> danielm at debian:~$ g++ -D_GLIBCXX_DEBUG -g bad-stl.cpp -o bad-stl
> danielm at debian:~$ ./bad-stl
> /usr/include/c++/4.7/debug/safe_iterator.h:359:error: attempt to advance a
> dereferenceable (start-of-sequence) iterator 2 steps, which falls
> outside its valid range.
>
> ```
>
This code has been rewritten.
================
Comment at: clang-tidy/misc/MacroParenthesesCheck.cpp:86
@@ +85,3 @@
+ if (Err) {
+ SourceLocation Loc = MI->tokens_begin()->getLocation();
+ Check->diag(Loc,
----------------
alexfh wrote:
> nit: No need for a variable here, just use the expression below.
Fixed
http://reviews.llvm.org/D9528
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the cfe-commits
mailing list