mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge remote-tracking branch 'upstream/rc/1.18' into mergeback-20180921_104253
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user