CPP: Improve accuracy of AutogeneratedFile.qll.

This commit is contained in:
Geoffrey White
2019-01-11 19:10:58 +00:00
parent f474fdd0f9
commit e3056ca96c

View File

@@ -3,11 +3,30 @@ import semmle.code.cpp.File
import semmle.code.cpp.Preprocessor
/**
* Holds if `c` is a comment which is usually seen in autogenerated files.
* For example, comments containing 'autogenerated' or 'generated by'.
* Holds if comment `c` indicates that it might be in an auto-generated file, for
* example because it contains the text "auto-generated by".
*/
predicate isAutogeneratedComment(Comment c) {
c.getContents().regexpMatch("(?si).*(?:auto[ -]?generated|generated (?:by|file)|changes made in this file will be lost).*")
private predicate autogeneratedComment(Comment c) {
// ?s = include newlines in anything (`.`)
// ?i = ignore case
// auto-generated, automatically generated etc.
c.getContents().regexpMatch("(?si).*(auto[\\w-]*\\s*?generated).*") or
// generated by (not used mid-sentence)
c.getContents().regexpMatch("(?si).*[^a-zA-Z\\s\\*\\r\\n][\\s\\*\\r\\n]*(generated by).*") or
// generated file
c.getContents().regexpMatch("(?si).*(generated file).*") or
// file [is] generated
c.getContents().regexpMatch("(?si).*(file( is)? generated).*") or
// changes made in this file will be lost
c.getContents().regexpMatch("(?si).*(changes made in this file will be lost).*") or
// do not edit/modify
c.getContents().regexpMatch("(?si).*(do(n't|nt| not) (edit|modify)).*")
}
/**
@@ -25,6 +44,17 @@ predicate hasPragmaDifferentFile(File f) {
)
}
/**
* The maximum line number we consider to be "near the beginning" of file `f`.
*/
private int fileHeaderLimit(File f) {
result = max(int head, int line |
head <= 5 and
locations_default(_, underlyingElement(f), head, _, line, _) |
line
) + 5
}
/**
* Holds if the file is probably an autogenerated file.
*
@@ -36,12 +66,10 @@ predicate hasPragmaDifferentFile(File f) {
*/
class AutogeneratedFile extends File {
cached AutogeneratedFile() {
exists(int limit, int head |
head <= 5 and
limit = max(int line | locations_default(_, underlyingElement(this), head, _, line, _)) + 5
|
exists (Comment c | c.getFile() = this and c.getLocation().getStartLine() <= limit and isAutogeneratedComment(c))
)
or hasPragmaDifferentFile(this)
exists(Comment c |
c.getFile() = this and
c.getLocation().getStartLine() <= fileHeaderLimit(this) and
autogeneratedComment(c)
) or hasPragmaDifferentFile(this)
}
}