Merge remote-tracking branch 'upstream/rc/1.18' into mergeback-20180921_104253

This commit is contained in:
Jonas Jensen
2018-09-21 10:45:54 +02:00
23 changed files with 328 additions and 55 deletions

View File

@@ -68,10 +68,9 @@ class Parameter extends LocalScopeVariable, @parameter {
*/
private VariableDeclarationEntry getAnEffectiveDeclarationEntry() {
if getFunction().isConstructedFrom(_)
then exists (Parameter prototype
| prototype = result.getVariable() and
prototype.getIndex() = getIndex() and
getFunction().isConstructedFrom(prototype.getFunction()))
then exists (Function prototypeInstantiation
| prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and
getFunction().isConstructedFrom(prototypeInstantiation))
else result = getADeclarationEntry()
}

View File

@@ -1,23 +1,31 @@
import semmle.code.cpp.Type
/** Holds if `d` is a complete class named `name`. */
pragma[noinline]
private string getTopLevelClassName(@usertype c) {
isClass(c) and
usertypes(c, result, _) and
not namespacembrs(_, c) and // not in a namespace
not member(_, _, c) and // not in some structure
not class_instantiation(c, _) // not a template instantiation
}
/** Holds if `d` is a unique complete class named `name`. */
pragma[noinline]
private predicate existsCompleteWithName(string name, @usertype d) {
isClass(d) and
is_complete(d) and
usertypes(d, name, _)
name = getTopLevelClassName(d) and
strictcount(@usertype other | is_complete(other) and getTopLevelClassName(other) = name) = 1
}
/** Holds if `c` is an incomplete class named `name`. */
pragma[noinline]
private predicate existsIncompleteWithName(string name, @usertype c) {
isClass(c) and
not is_complete(c) and
usertypes(c, name, _)
name = getTopLevelClassName(c)
}
/**
* Holds if `c` is an incomplete class, and there exists a complete class `d`
* Holds if `c` is an incomplete class, and there exists a unique complete class `d`
* with the same name.
*/
private predicate hasCompleteTwin(@usertype c, @usertype d) {
@@ -30,10 +38,8 @@ private predicate hasCompleteTwin(@usertype c, @usertype d) {
import Cached
cached private module Cached {
/**
* If `c` is incomplete, and there exists a complete class with the same name,
* then the result is that complete class. Otherwise, the result is `c`. If
* multiple complete classes have the same name, this predicate may have
* multiple results.
* If `c` is incomplete, and there exists a unique complete class with the same name,
* then the result is that complete class. Otherwise, the result is `c`.
*/
cached @usertype resolveClass(@usertype c) {
hasCompleteTwin(c, result)

View File

@@ -270,7 +270,7 @@ newtype TTranslatedElement =
not ignoreExpr(initList) and
isFirstValueInitializedElementInRange(initList, elementIndex) and
elementCount =
getNextExplicitlyInitializedElementAfter(initList, elementIndex) -
getEndOfValueInitializedRange(initList, elementIndex) -
elementIndex
} or
// The initialization of a base class from within a constructor.
@@ -322,23 +322,30 @@ newtype TTranslatedElement =
/**
* Gets the index of the first explicitly initialized element in `initList`
* whose index is greater than `afterElementIndex`. If there are no remaining
* explicitly initialized elements in `initList`, the result is the total number
* of elements in the array being initialized.
* whose index is greater than `afterElementIndex`, where `afterElementIndex`
* is a first value-initialized element in a value-initialized range in
* `initList`. If there are no remaining explicitly initialized elements in
* `initList`, the result is the total number of elements in the array being
* initialized.
*/
private int getNextExplicitlyInitializedElementAfter(
ArrayAggregateLiteral initList, int afterElementIndex) {
if exists(int x |
x > afterElementIndex and
exists(initList.getElementExpr(x)))
then (
if exists(initList.getElementExpr(afterElementIndex + 1))
then result = afterElementIndex + 1
else result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex+1))
else
result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize() and
// required for binding
initList.isInitialized(afterElementIndex)
private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int afterElementIndex) {
result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)
or
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
not exists(getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)) and
result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize()
}
/**
* Gets the index of the first explicitly initialized element in `initList`
* whose index is greater than `afterElementIndex`, where `afterElementIndex`
* is a first value-initialized element in a value-initialized range in
* `initList`.
*/
private int getNextExplicitlyInitializedElementAfter(
ArrayAggregateLiteral initList, int afterElementIndex) {
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
result = min(int i | exists(initList.getElementExpr(i)) and i > afterElementIndex)
}
/**