diff options
author | Anna Zaks <ganna@apple.com> | 2011-12-15 02:28:16 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-12-15 02:28:16 +0000 |
commit | 2135ebb83179ee87910afdebc1bc091e17a7d1eb (patch) | |
tree | 33df03451f7e179e5fa30345167dfbb7491801c3 | |
parent | 62d829abaf61d70483a5a584059440a549a306bf (diff) |
Add support for matching one or more (aka regex +) diagnostic messages with -verify.
Ex:
// expected-warning + {{tainted}
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146633 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Frontend/VerifyDiagnosticConsumer.cpp | 15 | ||||
-rw-r--r-- | test/Analysis/taint-tester.c | 66 |
2 files changed, 47 insertions, 34 deletions
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp index 5eeb696582..ef5459c233 100644 --- a/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -82,6 +82,9 @@ public: static Directive* Create(bool RegexKind, const SourceLocation &Location, const std::string &Text, unsigned Count); public: + /// Constant representing one or more matches aka regex "+". + static const unsigned OneOrMoreCount = UINT_MAX; + SourceLocation Location; const std::string Text; unsigned Count; @@ -276,10 +279,14 @@ static void ParseDirective(const char *CommentStart, unsigned CommentLen, // skip optional whitespace PH.SkipWhitespace(); - // next optional token: positive integer + // next optional token: positive integer or a '+'. unsigned Count = 1; if (PH.Next(Count)) PH.Advance(); + else if (PH.Next("+")) { + Count = Directive::OneOrMoreCount; + PH.Advance(); + } // skip optional whitespace PH.SkipWhitespace(); @@ -420,6 +427,7 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) { Directive& D = **I; unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.Location); + bool FoundOnce = false; for (unsigned i = 0; i < D.Count; ++i) { DiagList::iterator II, IE; @@ -433,11 +441,16 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, break; } if (II == IE) { + if (D.Count == D.OneOrMoreCount && FoundOnce) { + // We are only interested in at least one match and we found one. + break; + } // Not found. LeftOnly.push_back(*I); } else { // Found. The same cannot be found twice. Right.erase(II); + FoundOnce = true; } } } diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c index e3c6723d4e..476027f31b 100644 --- a/test/Analysis/taint-tester.c +++ b/test/Analysis/taint-tester.c @@ -18,48 +18,48 @@ void taintTracking(int x) { int n; int *addr = &Buffer[0]; scanf("%d", &n); - addr += n;// expected-warning 2 {{tainted}} - *addr = n; // expected-warning 3 {{tainted}} + addr += n;// expected-warning + {{tainted}} + *addr = n; // expected-warning + {{tainted}} - double tdiv = n / 30; // expected-warning 3 {{tainted}} - char *loc_cast = (char *) n; // expected-warning {{tainted}} - char tinc = tdiv++; // expected-warning {{tainted}} - int tincdec = (char)tinc--; // expected-warning 2 {{tainted}} + double tdiv = n / 30; // expected-warning+ {{tainted}} + char *loc_cast = (char *) n; // expected-warning +{{tainted}} + char tinc = tdiv++; // expected-warning + {{tainted}} + int tincdec = (char)tinc--; // expected-warning+{{tainted}} // Tainted ptr arithmetic/array element address. - int tprtarithmetic1 = *(addr+1); // expected-warning 2 {{tainted}} + int tprtarithmetic1 = *(addr+1); // expected-warning + {{tainted}} // Dereference. int *ptr; scanf("%p", &ptr); - int ptrDeref = *ptr; // expected-warning 2 {{tainted}} - int _ptrDeref = ptrDeref + 13; // expected-warning 2 {{tainted}} + int ptrDeref = *ptr; // expected-warning + {{tainted}} + int _ptrDeref = ptrDeref + 13; // expected-warning + {{tainted}} // Pointer arithmetic + dereferencing. // FIXME: We fail to propagate the taint here because RegionStore does not // handle ElementRegions with symbolic indexes. - int addrDeref = *addr; // expected-warning {{tainted}} + int addrDeref = *addr; // expected-warning + {{tainted}} int _addrDeref = addrDeref; // Tainted struct address, casts. struct XYStruct *xyPtr = 0; scanf("%p", &xyPtr); - void *tXYStructPtr = xyPtr; // expected-warning 2 {{tainted}} - struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning 2 {{tainted}} - int ptrtx = xyPtr->x;// expected-warning 2 {{tainted}} - int ptrty = xyPtr->y;// expected-warning 2 {{tainted}} + void *tXYStructPtr = xyPtr; // expected-warning + {{tainted}} + struct XYStruct *xyPtrCopy = tXYStructPtr; // expected-warning + {{tainted}} + int ptrtx = xyPtr->x;// expected-warning + {{tainted}} + int ptrty = xyPtr->y;// expected-warning + {{tainted}} // Taint on fields of a struct. struct XYStruct xy = {2, 3, 11}; scanf("%d", &xy.y); scanf("%d", &xy.x); - int tx = xy.x; // expected-warning {{tainted}} + int tx = xy.x; // expected-warning + {{tainted}} int ty = xy.y; // FIXME: This should be tainted as well. char ntz = xy.z;// no warning // Now, scanf scans both. scanf("%d %d", &xy.y, &xy.x); - int ttx = xy.x; // expected-warning {{tainted}} - int tty = xy.y; // expected-warning {{tainted}} + int ttx = xy.x; // expected-warning + {{tainted}} + int tty = xy.y; // expected-warning + {{tainted}} } void BitwiseOp(int in, char inn) { @@ -67,22 +67,22 @@ void BitwiseOp(int in, char inn) { int m; int x = 0; scanf("%d", &x); - int y = (in << (x << in)) * 5;// expected-warning 4 {{tainted}} + int y = (in << (x << in)) * 5;// expected-warning + {{tainted}} // The next line tests integer to integer cast. - int z = y & inn; // expected-warning 2 {{tainted}} - if (y == 5) // expected-warning 2 {{tainted}} - m = z | z;// expected-warning 4 {{tainted}} + int z = y & inn; // expected-warning + {{tainted}} + if (y == 5) // expected-warning + {{tainted}} + m = z | z;// expected-warning + {{tainted}} else m = inn; - int mm = m; // expected-warning {{tainted}} + int mm = m; // expected-warning + {{tainted}} } // Test getenv. char *getenv(const char *name); void getenvTest(char *home) { - home = getenv("HOME"); // expected-warning 2 {{tainted}} - if (home != 0) { // expected-warning 2 {{tainted}} - char d = home[0]; // expected-warning 2 {{tainted}} + home = getenv("HOME"); // expected-warning + {{tainted}} + if (home != 0) { // expected-warning + {{tainted}} + char d = home[0]; // expected-warning + {{tainted}} } } @@ -104,21 +104,21 @@ int fscanfTest(void) { fscanf(stdin, "%s %d", s, &t); // Note, here, s is not tainted, but the data s points to is tainted. char *ts = s; - char tss = s[0]; // expected-warning 1 {{tainted}} - int tt = t; // expected-warning 1 {{tainted}} - if((fp=fopen("test", "w")) == 0) // expected-warning 3 {{tainted}} + char tss = s[0]; // expected-warning + {{tainted}} + int tt = t; // expected-warning + {{tainted}} + if((fp=fopen("test", "w")) == 0) // expected-warning + {{tainted}} return 1; - fprintf(fp, "%s %d", s, t); // expected-warning 2 {{tainted}} - fclose(fp); // expected-warning 1 {{tainted}} + fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}} + fclose(fp); // expected-warning + {{tainted}} // Check if we propagate taint from stdin when it's used in an assignment. FILE *pfstd = stdin; fscanf(pfstd, "%s %d", s, &t); // TODO: This should be tainted as well. // Test fscanf and fopen. - if((fp=fopen("test","r")) == 0) // expected-warning 3 {{tainted}} + if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}} return 1; - fscanf(fp, "%s%d", s, &t); // expected-warning 1 {{tainted}} - fprintf(stdout, "%s %d", s, t); // expected-warning 1 {{tainted}} + fscanf(fp, "%s%d", s, &t); // expected-warning + {{tainted}} + fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}} return 0; } |