Merge pull request #2404 from jbj/signed-overflow-macro

C++: Fix SignedOverflowCheck.ql performance
This commit is contained in:
Geoffrey White
2019-11-25 15:15:57 +00:00
committed by GitHub
2 changed files with 14 additions and 6 deletions

View File

@@ -14,6 +14,7 @@
import cpp
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.commons.Exclusions
from RelationalOperation ro, AddExpr add, Expr expr1, Expr expr2
where
@@ -22,7 +23,7 @@ where
ro.getAnOperand() = expr2 and
globalValueNumber(expr1) = globalValueNumber(expr2) and
add.getUnspecifiedType().(IntegralType).isSigned() and
not exists(MacroInvocation mi | mi.getAnAffectedElement() = add) and
not isFromMacroDefinition(ro) and
exprMightOverflowPositively(add) and
exists(Compilation c | c.getAFileCompiled() = ro.getFile() |
not c.getAnArgument() = "-fwrapv" and

View File

@@ -94,11 +94,18 @@ predicate functionContainsPreprocCode(Function f) {
* ```
*/
predicate isFromMacroDefinition(Element e) {
exists(MacroInvocation mi |
// e is in mi
exists(MacroInvocation mi, Location eLocation, Location miLocation |
mi.getAnExpandedElement() = e and
// and e was apparently not passed in as a macro parameter
e.getLocation().getStartLine() = mi.getLocation().getStartLine() and
e.getLocation().getStartColumn() = mi.getLocation().getStartColumn()
eLocation = e.getLocation() and
miLocation = mi.getLocation() and
// If the location of `e` coincides with the macro invocation, then `e` did
// not come from a macro argument. The inequalities here could also be
// equalities, but that confuses the join orderer into joining on the source
// locations too early.
// There are cases where the start location of a non-argument element comes
// right after the invocation's open parenthesis, so it appears to be more
// robust to match on the end location instead.
eLocation.getEndLine() >= miLocation.getEndLine() and
eLocation.getEndColumn() >= miLocation.getEndColumn()
)
}