mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
C++: fix implicit this
This commit is contained in:
committed by
Mathias Vorreiter Pedersen
parent
b2e4276bc8
commit
fe891746bf
18
cpp/ql/lib/external/ExternalArtifact.qll
vendored
18
cpp/ql/lib/external/ExternalArtifact.qll
vendored
@@ -15,7 +15,7 @@ class ExternalData extends @externalDataElement {
|
||||
* Gets the path of the file this data was loaded from, with its
|
||||
* extension replaced by `.ql`.
|
||||
*/
|
||||
string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
|
||||
string getQueryPath() { result = this.getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
|
||||
|
||||
/** Gets the number of fields in this data item. */
|
||||
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
|
||||
@@ -24,22 +24,22 @@ class ExternalData extends @externalDataElement {
|
||||
string getField(int i) { externalData(this, _, i, result) }
|
||||
|
||||
/** Gets the integer value of the `i`th field of this data item. */
|
||||
int getFieldAsInt(int i) { result = getField(i).toInt() }
|
||||
int getFieldAsInt(int i) { result = this.getField(i).toInt() }
|
||||
|
||||
/** Gets the floating-point value of the `i`th field of this data item. */
|
||||
float getFieldAsFloat(int i) { result = getField(i).toFloat() }
|
||||
float getFieldAsFloat(int i) { result = this.getField(i).toFloat() }
|
||||
|
||||
/** Gets the value of the `i`th field of this data item, interpreted as a date. */
|
||||
date getFieldAsDate(int i) { result = getField(i).toDate() }
|
||||
date getFieldAsDate(int i) { result = this.getField(i).toDate() }
|
||||
|
||||
/** Gets a textual representation of this data item. */
|
||||
string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
|
||||
string toString() { result = this.getQueryPath() + ": " + this.buildTupleString(0) }
|
||||
|
||||
/** Gets a textual representation of this data item, starting with the `n`th field. */
|
||||
private string buildTupleString(int n) {
|
||||
n = getNumFields() - 1 and result = getField(n)
|
||||
n = this.getNumFields() - 1 and result = this.getField(n)
|
||||
or
|
||||
n < getNumFields() - 1 and result = getField(n) + "," + buildTupleString(n + 1)
|
||||
n < this.getNumFields() - 1 and result = this.getField(n) + "," + this.buildTupleString(n + 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ class DefectExternalData extends ExternalData {
|
||||
}
|
||||
|
||||
/** Gets the URL associated with this data item. */
|
||||
string getURL() { result = getField(0) }
|
||||
string getURL() { result = this.getField(0) }
|
||||
|
||||
/** Gets the message associated with this data item. */
|
||||
string getMessage() { result = getField(1) }
|
||||
string getMessage() { result = this.getField(1) }
|
||||
}
|
||||
|
||||
@@ -269,13 +269,13 @@ class Class extends UserType {
|
||||
* DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that
|
||||
* `= default` members are no longer included.
|
||||
*/
|
||||
deprecated predicate hasGeneratedCopyConstructor() { hasImplicitCopyConstructor() }
|
||||
deprecated predicate hasGeneratedCopyConstructor() { this.hasImplicitCopyConstructor() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to
|
||||
* reflect that `= default` members are no longer included.
|
||||
*/
|
||||
deprecated predicate hasGeneratedCopyAssignmentOperator() { hasImplicitCopyConstructor() }
|
||||
deprecated predicate hasGeneratedCopyAssignmentOperator() { this.hasImplicitCopyConstructor() }
|
||||
|
||||
/**
|
||||
* Holds if this class, struct or union has an implicitly-declared copy
|
||||
@@ -487,7 +487,7 @@ class Class extends UserType {
|
||||
exists(ClassDerivation cd |
|
||||
// Add the offset of the direct base class and the offset of `baseClass`
|
||||
// within that direct base class.
|
||||
cd = getADerivation() and
|
||||
cd = this.getADerivation() and
|
||||
result = cd.getBaseClass().getANonVirtualBaseClassByteOffset(baseClass) + cd.getByteOffset()
|
||||
)
|
||||
}
|
||||
@@ -502,12 +502,12 @@ class Class extends UserType {
|
||||
*/
|
||||
int getABaseClassByteOffset(Class baseClass) {
|
||||
// Handle the non-virtual case.
|
||||
result = getANonVirtualBaseClassByteOffset(baseClass)
|
||||
result = this.getANonVirtualBaseClassByteOffset(baseClass)
|
||||
or
|
||||
exists(Class virtualBaseClass, int virtualBaseOffset, int offsetFromVirtualBase |
|
||||
// Look for the base class as a non-virtual base of a direct or indirect
|
||||
// virtual base, adding the two offsets.
|
||||
getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and
|
||||
this.getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and
|
||||
offsetFromVirtualBase = virtualBaseClass.getANonVirtualBaseClassByteOffset(baseClass) and
|
||||
result = virtualBaseOffset + offsetFromVirtualBase
|
||||
)
|
||||
@@ -623,11 +623,11 @@ class Class extends UserType {
|
||||
* inherits one).
|
||||
*/
|
||||
predicate isPolymorphic() {
|
||||
exists(MemberFunction f | f.getDeclaringType() = getABaseClass*() and f.isVirtual())
|
||||
exists(MemberFunction f | f.getDeclaringType() = this.getABaseClass*() and f.isVirtual())
|
||||
}
|
||||
|
||||
override predicate involvesTemplateParameter() {
|
||||
getATemplateArgument().(Type).involvesTemplateParameter()
|
||||
this.getATemplateArgument().(Type).involvesTemplateParameter()
|
||||
}
|
||||
|
||||
/** Holds if this class, struct or union was declared 'final'. */
|
||||
@@ -765,7 +765,7 @@ class ClassDerivation extends Locatable, @derivation {
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
Class getBaseClass() { result = getBaseType().getUnderlyingType() }
|
||||
Class getBaseClass() { result = this.getBaseType().getUnderlyingType() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ClassDerivation" }
|
||||
|
||||
@@ -818,7 +818,7 @@ class ClassDerivation extends Locatable, @derivation {
|
||||
predicate hasSpecifier(string s) { this.getASpecifier().hasName(s) }
|
||||
|
||||
/** Holds if the derivation is for a virtual base class. */
|
||||
predicate isVirtual() { hasSpecifier("virtual") }
|
||||
predicate isVirtual() { this.hasSpecifier("virtual") }
|
||||
|
||||
/** Gets the location of the derivation. */
|
||||
override Location getLocation() { derivations(underlyingElement(this), _, _, _, result) }
|
||||
@@ -846,7 +846,7 @@ class ClassDerivation extends Locatable, @derivation {
|
||||
* ```
|
||||
*/
|
||||
class LocalClass extends Class {
|
||||
LocalClass() { isLocal() }
|
||||
LocalClass() { this.isLocal() }
|
||||
|
||||
override string getAPrimaryQlClass() { not this instanceof LocalStruct and result = "LocalClass" }
|
||||
|
||||
@@ -989,9 +989,9 @@ class ClassTemplateSpecialization extends Class {
|
||||
TemplateClass getPrimaryTemplate() {
|
||||
// Ignoring template arguments, the primary template has the same name
|
||||
// as each of its specializations.
|
||||
result.getSimpleName() = getSimpleName() and
|
||||
result.getSimpleName() = this.getSimpleName() and
|
||||
// It is in the same namespace as its specializations.
|
||||
result.getNamespace() = getNamespace() and
|
||||
result.getNamespace() = this.getNamespace() and
|
||||
// It is distinguished by the fact that each of its template arguments
|
||||
// is a distinct template parameter.
|
||||
count(TemplateParameter tp | tp = result.getATemplateArgument()) =
|
||||
@@ -1108,7 +1108,7 @@ deprecated class Interface extends Class {
|
||||
* ```
|
||||
*/
|
||||
class VirtualClassDerivation extends ClassDerivation {
|
||||
VirtualClassDerivation() { hasSpecifier("virtual") }
|
||||
VirtualClassDerivation() { this.hasSpecifier("virtual") }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "VirtualClassDerivation" }
|
||||
}
|
||||
@@ -1136,7 +1136,7 @@ class VirtualBaseClass extends Class {
|
||||
VirtualClassDerivation getAVirtualDerivation() { result.getBaseClass() = this }
|
||||
|
||||
/** A class/struct that is derived from this one using virtual inheritance. */
|
||||
Class getAVirtuallyDerivedClass() { result = getAVirtualDerivation().getDerivedClass() }
|
||||
Class getAVirtuallyDerivedClass() { result = this.getAVirtualDerivation().getDerivedClass() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1155,7 +1155,7 @@ class ProxyClass extends UserType {
|
||||
override string getAPrimaryQlClass() { result = "ProxyClass" }
|
||||
|
||||
/** Gets the location of the proxy class. */
|
||||
override Location getLocation() { result = getTemplateParameter().getDefinitionLocation() }
|
||||
override Location getLocation() { result = this.getTemplateParameter().getDefinitionLocation() }
|
||||
|
||||
/** Gets the template parameter for which this is the proxy class. */
|
||||
TemplateParameter getTemplateParameter() {
|
||||
|
||||
@@ -184,7 +184,7 @@ class Declaration extends Locatable, @declaration {
|
||||
predicate hasDefinition() { exists(this.getDefinition()) }
|
||||
|
||||
/** DEPRECATED: Use `hasDefinition` instead. */
|
||||
predicate isDefined() { hasDefinition() }
|
||||
predicate isDefined() { this.hasDefinition() }
|
||||
|
||||
/** Gets the preferred location of this declaration, if any. */
|
||||
override Location getLocation() { none() }
|
||||
@@ -209,7 +209,7 @@ class Declaration extends Locatable, @declaration {
|
||||
predicate isStatic() { this.hasSpecifier("static") }
|
||||
|
||||
/** Holds if this declaration is a member of a class/struct/union. */
|
||||
predicate isMember() { hasDeclaringType() }
|
||||
predicate isMember() { this.hasDeclaringType() }
|
||||
|
||||
/** Holds if this declaration is a member of a class/struct/union. */
|
||||
predicate hasDeclaringType() { exists(this.getDeclaringType()) }
|
||||
@@ -226,14 +226,14 @@ class Declaration extends Locatable, @declaration {
|
||||
* When called on a template, this will return a template parameter type for
|
||||
* both typed and non-typed parameters.
|
||||
*/
|
||||
final Locatable getATemplateArgument() { result = getTemplateArgument(_) }
|
||||
final Locatable getATemplateArgument() { result = this.getTemplateArgument(_) }
|
||||
|
||||
/**
|
||||
* Gets a template argument used to instantiate this declaration from a template.
|
||||
* When called on a template, this will return a non-typed template
|
||||
* parameter value.
|
||||
*/
|
||||
final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) }
|
||||
final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th template argument used to instantiate this declaration from a
|
||||
@@ -252,9 +252,9 @@ class Declaration extends Locatable, @declaration {
|
||||
* `getTemplateArgument(1)` return `1`.
|
||||
*/
|
||||
final Locatable getTemplateArgument(int index) {
|
||||
if exists(getTemplateArgumentValue(index))
|
||||
then result = getTemplateArgumentValue(index)
|
||||
else result = getTemplateArgumentType(index)
|
||||
if exists(this.getTemplateArgumentValue(index))
|
||||
then result = this.getTemplateArgumentValue(index)
|
||||
else result = this.getTemplateArgumentType(index)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,13 +275,13 @@ class Declaration extends Locatable, @declaration {
|
||||
* `getTemplateArgumentKind(0)`.
|
||||
*/
|
||||
final Locatable getTemplateArgumentKind(int index) {
|
||||
exists(getTemplateArgumentValue(index)) and
|
||||
result = getTemplateArgumentType(index)
|
||||
exists(this.getTemplateArgumentValue(index)) and
|
||||
result = this.getTemplateArgumentType(index)
|
||||
}
|
||||
|
||||
/** Gets the number of template arguments for this declaration. */
|
||||
final int getNumberOfTemplateArguments() {
|
||||
result = count(int i | exists(getTemplateArgument(i)))
|
||||
result = count(int i | exists(this.getTemplateArgument(i)))
|
||||
}
|
||||
|
||||
private Type getTemplateArgumentType(int index) {
|
||||
@@ -327,9 +327,9 @@ class DeclarationEntry extends Locatable, TDeclarationEntry {
|
||||
* available), or the name declared by this entry otherwise.
|
||||
*/
|
||||
string getCanonicalName() {
|
||||
if getDeclaration().hasDefinition()
|
||||
then result = getDeclaration().getDefinition().getName()
|
||||
else result = getName()
|
||||
if this.getDeclaration().hasDefinition()
|
||||
then result = this.getDeclaration().getDefinition().getName()
|
||||
else result = this.getName()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,18 +370,18 @@ class DeclarationEntry extends Locatable, TDeclarationEntry {
|
||||
/**
|
||||
* Holds if this declaration entry has a specifier with the given name.
|
||||
*/
|
||||
predicate hasSpecifier(string specifier) { getASpecifier() = specifier }
|
||||
predicate hasSpecifier(string specifier) { this.getASpecifier() = specifier }
|
||||
|
||||
/** Holds if this declaration entry is a definition. */
|
||||
predicate isDefinition() { none() } // overridden in subclasses
|
||||
|
||||
override string toString() {
|
||||
if isDefinition()
|
||||
then result = "definition of " + getName()
|
||||
if this.isDefinition()
|
||||
then result = "definition of " + this.getName()
|
||||
else
|
||||
if getName() = getCanonicalName()
|
||||
then result = "declaration of " + getName()
|
||||
else result = "declaration of " + getCanonicalName() + " as " + getName()
|
||||
if this.getName() = this.getCanonicalName()
|
||||
then result = "declaration of " + this.getName()
|
||||
else result = "declaration of " + this.getCanonicalName() + " as " + this.getName()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ private class DirectAccessHolder extends Element {
|
||||
// transitive closure with a restricted base case.
|
||||
this.thisCanAccessClassStep(base, derived)
|
||||
or
|
||||
exists(Class between | thisCanAccessClassTrans(base, between) |
|
||||
exists(Class between | this.thisCanAccessClassTrans(base, between) |
|
||||
isDirectPublicBaseOf(between, derived) or
|
||||
this.thisCanAccessClassStep(between, derived)
|
||||
)
|
||||
|
||||
@@ -61,7 +61,7 @@ class ElementBase extends @element {
|
||||
/**
|
||||
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
*/
|
||||
final string getPrimaryQlClasses() { result = concat(getAPrimaryQlClass(), ",") }
|
||||
final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
|
||||
|
||||
/**
|
||||
* Gets the name of a primary CodeQL class to which this element belongs.
|
||||
@@ -206,9 +206,9 @@ class Element extends ElementBase {
|
||||
/** Gets the closest `Element` enclosing this one. */
|
||||
cached
|
||||
Element getEnclosingElement() {
|
||||
result = getEnclosingElementPref()
|
||||
result = this.getEnclosingElementPref()
|
||||
or
|
||||
not exists(getEnclosingElementPref()) and
|
||||
not exists(this.getEnclosingElementPref()) and
|
||||
(
|
||||
this = result.(Class).getAMember()
|
||||
or
|
||||
@@ -281,7 +281,7 @@ private predicate isFromUninstantiatedTemplateRec(Element e, Element template) {
|
||||
* ```
|
||||
*/
|
||||
class StaticAssert extends Locatable, @static_assert {
|
||||
override string toString() { result = "static_assert(..., \"" + getMessage() + "\")" }
|
||||
override string toString() { result = "static_assert(..., \"" + this.getMessage() + "\")" }
|
||||
|
||||
/**
|
||||
* Gets the expression which this static assertion ensures is true.
|
||||
|
||||
@@ -85,7 +85,7 @@ class Enum extends UserType, IntegralOrEnumType {
|
||||
* ```
|
||||
*/
|
||||
class LocalEnum extends Enum {
|
||||
LocalEnum() { isLocal() }
|
||||
LocalEnum() { this.isLocal() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LocalEnum" }
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class Container extends Locatable, @container {
|
||||
*/
|
||||
string getRelativePath() {
|
||||
exists(string absPath, string pref |
|
||||
absPath = getAbsolutePath() and sourceLocationPrefix(pref)
|
||||
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
||||
|
|
||||
absPath = pref and result = ""
|
||||
or
|
||||
@@ -79,7 +79,7 @@ class Container extends Locatable, @container {
|
||||
* </table>
|
||||
*/
|
||||
string getBaseName() {
|
||||
result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
|
||||
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,9 @@ class Container extends Locatable, @container {
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
|
||||
string getExtension() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stem of this container, that is, the prefix of its base name up to
|
||||
@@ -124,7 +126,9 @@ class Container extends Locatable, @container {
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
|
||||
string getStem() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
|
||||
}
|
||||
|
||||
/** Gets the parent container of this file or folder, if any. */
|
||||
Container getParentContainer() {
|
||||
@@ -135,20 +139,20 @@ class Container extends Locatable, @container {
|
||||
Container getAChildContainer() { this = result.getParentContainer() }
|
||||
|
||||
/** Gets a file in this container. */
|
||||
File getAFile() { result = getAChildContainer() }
|
||||
File getAFile() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the file in this container that has the given `baseName`, if any. */
|
||||
File getFile(string baseName) {
|
||||
result = getAFile() and
|
||||
result = this.getAFile() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
/** Gets a sub-folder in this container. */
|
||||
Folder getAFolder() { result = getAChildContainer() }
|
||||
Folder getAFolder() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
|
||||
Folder getFolder(string baseName) {
|
||||
result = getAFolder() and
|
||||
result = this.getAFolder() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
@@ -157,7 +161,7 @@ class Container extends Locatable, @container {
|
||||
*
|
||||
* This is the absolute path of the container.
|
||||
*/
|
||||
override string toString() { result = getAbsolutePath() }
|
||||
override string toString() { result = this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,26 +43,26 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
*/
|
||||
string getFullSignature() {
|
||||
exists(string name, string templateArgs, string args |
|
||||
result = name + templateArgs + args + " -> " + getType().toString() and
|
||||
name = getQualifiedName() and
|
||||
result = name + templateArgs + args + " -> " + this.getType().toString() and
|
||||
name = this.getQualifiedName() and
|
||||
(
|
||||
if exists(getATemplateArgument())
|
||||
if exists(this.getATemplateArgument())
|
||||
then
|
||||
templateArgs =
|
||||
"<" +
|
||||
concat(int i |
|
||||
exists(getTemplateArgument(i))
|
||||
exists(this.getTemplateArgument(i))
|
||||
|
|
||||
getTemplateArgument(i).toString(), ", " order by i
|
||||
this.getTemplateArgument(i).toString(), ", " order by i
|
||||
) + ">"
|
||||
else templateArgs = ""
|
||||
) and
|
||||
args =
|
||||
"(" +
|
||||
concat(int i |
|
||||
exists(getParameter(i))
|
||||
exists(this.getParameter(i))
|
||||
|
|
||||
getParameter(i).getType().toString(), ", " order by i
|
||||
this.getParameter(i).getType().toString(), ", " order by i
|
||||
) + ")"
|
||||
)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
/** Gets a specifier of this function. */
|
||||
override Specifier getASpecifier() {
|
||||
funspecifiers(underlyingElement(this), unresolveElement(result)) or
|
||||
result.hasName(getADeclarationEntry().getASpecifier())
|
||||
result.hasName(this.getADeclarationEntry().getASpecifier())
|
||||
}
|
||||
|
||||
/** Gets an attribute of this function. */
|
||||
@@ -149,7 +149,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* Holds if this function is declared with `__attribute__((naked))` or
|
||||
* `__declspec(naked)`.
|
||||
*/
|
||||
predicate isNaked() { getAnAttribute().hasName("naked") }
|
||||
predicate isNaked() { this.getAnAttribute().hasName("naked") }
|
||||
|
||||
/**
|
||||
* Holds if this function has a trailing return type.
|
||||
@@ -172,7 +172,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* Gets the return type of this function after specifiers have been deeply
|
||||
* stripped and typedefs have been resolved.
|
||||
*/
|
||||
Type getUnspecifiedType() { result = getType().getUnspecifiedType() }
|
||||
Type getUnspecifiedType() { result = this.getType().getUnspecifiedType() }
|
||||
|
||||
/**
|
||||
* Gets the nth parameter of this function. There is no result for the
|
||||
@@ -206,7 +206,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
int getEffectiveNumberOfParameters() {
|
||||
// This method is overridden in `MemberFunction`, where the result is
|
||||
// adjusted to account for the implicit `this` parameter.
|
||||
result = getNumberOfParameters()
|
||||
result = this.getNumberOfParameters()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +216,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* return `int p1, int p2`.
|
||||
*/
|
||||
string getParameterString() {
|
||||
result = concat(int i | | min(getParameter(i).getTypedName()), ", " order by i)
|
||||
result = concat(int i | | min(this.getParameter(i).getTypedName()), ", " order by i)
|
||||
}
|
||||
|
||||
/** Gets a call to this function. */
|
||||
@@ -229,7 +229,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
*/
|
||||
override FunctionDeclarationEntry getADeclarationEntry() {
|
||||
if fun_decls(_, underlyingElement(this), _, _, _)
|
||||
then declEntry(result)
|
||||
then this.declEntry(result)
|
||||
else
|
||||
exists(Function f |
|
||||
this.isConstructedFrom(f) and
|
||||
@@ -250,7 +250,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* Gets the location of a `FunctionDeclarationEntry` corresponding to this
|
||||
* declaration.
|
||||
*/
|
||||
override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
|
||||
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
|
||||
|
||||
/** Holds if this Function is a Template specialization. */
|
||||
predicate isSpecialization() {
|
||||
@@ -265,14 +265,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* definition, if any.
|
||||
*/
|
||||
override FunctionDeclarationEntry getDefinition() {
|
||||
result = getADeclarationEntry() and
|
||||
result = this.getADeclarationEntry() and
|
||||
result.isDefinition()
|
||||
}
|
||||
|
||||
/** Gets the location of the definition, if any. */
|
||||
override Location getDefinitionLocation() {
|
||||
if exists(getDefinition())
|
||||
then result = getDefinition().getLocation()
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinition().getLocation()
|
||||
else exists(Function f | this.isConstructedFrom(f) and result = f.getDefinition().getLocation())
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* definition, if possible.)
|
||||
*/
|
||||
override Location getLocation() {
|
||||
if exists(getDefinition())
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinitionLocation()
|
||||
else result = this.getADeclarationLocation()
|
||||
}
|
||||
@@ -299,7 +299,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
BlockStmt getBlock() { result.getParentScope() = this }
|
||||
|
||||
/** Holds if this function has an entry point. */
|
||||
predicate hasEntryPoint() { exists(getEntryPoint()) }
|
||||
predicate hasEntryPoint() { exists(this.getEntryPoint()) }
|
||||
|
||||
/**
|
||||
* Gets the first node in this function's control flow graph.
|
||||
@@ -392,7 +392,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* Holds if this function has C linkage, as specified by one of its
|
||||
* declaration entries. For example: `extern "C" void foo();`.
|
||||
*/
|
||||
predicate hasCLinkage() { getADeclarationEntry().hasCLinkage() }
|
||||
predicate hasCLinkage() { this.getADeclarationEntry().hasCLinkage() }
|
||||
|
||||
/**
|
||||
* Holds if this function is constructed from `f` as a result
|
||||
@@ -409,27 +409,27 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* several functions that are not linked together have been compiled. An
|
||||
* example would be a project with many 'main' functions.
|
||||
*/
|
||||
predicate isMultiplyDefined() { strictcount(getFile()) > 1 }
|
||||
predicate isMultiplyDefined() { strictcount(this.getFile()) > 1 }
|
||||
|
||||
/** Holds if this function is a varargs function. */
|
||||
predicate isVarargs() { hasSpecifier("varargs") }
|
||||
predicate isVarargs() { this.hasSpecifier("varargs") }
|
||||
|
||||
/** Gets a type that is specified to be thrown by the function. */
|
||||
Type getAThrownType() { result = getADeclarationEntry().getAThrownType() }
|
||||
Type getAThrownType() { result = this.getADeclarationEntry().getAThrownType() }
|
||||
|
||||
/**
|
||||
* Gets the `i`th type specified to be thrown by the function.
|
||||
*/
|
||||
Type getThrownType(int i) { result = getADeclarationEntry().getThrownType(i) }
|
||||
Type getThrownType(int i) { result = this.getADeclarationEntry().getThrownType(i) }
|
||||
|
||||
/** Holds if the function has an exception specification. */
|
||||
predicate hasExceptionSpecification() { getADeclarationEntry().hasExceptionSpecification() }
|
||||
predicate hasExceptionSpecification() { this.getADeclarationEntry().hasExceptionSpecification() }
|
||||
|
||||
/** Holds if this function has a `throw()` exception specification. */
|
||||
predicate isNoThrow() { getADeclarationEntry().isNoThrow() }
|
||||
predicate isNoThrow() { this.getADeclarationEntry().isNoThrow() }
|
||||
|
||||
/** Holds if this function has a `noexcept` exception specification. */
|
||||
predicate isNoExcept() { getADeclarationEntry().isNoExcept() }
|
||||
predicate isNoExcept() { this.getADeclarationEntry().isNoExcept() }
|
||||
|
||||
/**
|
||||
* Gets a function that overloads this one.
|
||||
@@ -539,7 +539,7 @@ private predicate candGetAnOverloadNonMember(string name, Namespace namespace, F
|
||||
*/
|
||||
class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
/** Gets the function which is being declared or defined. */
|
||||
override Function getDeclaration() { result = getFunction() }
|
||||
override Function getDeclaration() { result = this.getFunction() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FunctionDeclarationEntry" }
|
||||
|
||||
@@ -586,7 +586,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
* case, catch) plus the number of branching expressions (`?`, `&&`,
|
||||
* `||`) plus one.
|
||||
*/
|
||||
int getCyclomaticComplexity() { result = 1 + cyclomaticComplexityBranches(getBlock()) }
|
||||
int getCyclomaticComplexity() { result = 1 + cyclomaticComplexityBranches(this.getBlock()) }
|
||||
|
||||
/**
|
||||
* If this is a function definition, get the block containing the
|
||||
@@ -594,7 +594,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
*/
|
||||
BlockStmt getBlock() {
|
||||
this.isDefinition() and
|
||||
result = getFunction().getBlock() and
|
||||
result = this.getFunction().getBlock() and
|
||||
result.getFile() = this.getFile()
|
||||
}
|
||||
|
||||
@@ -604,7 +604,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
*/
|
||||
pragma[noopt]
|
||||
int getNumberOfLines() {
|
||||
exists(BlockStmt b, Location l, int start, int end, int diff | b = getBlock() |
|
||||
exists(BlockStmt b, Location l, int start, int end, int diff | b = this.getBlock() |
|
||||
l = b.getLocation() and
|
||||
start = l.getStartLine() and
|
||||
end = l.getEndLine() and
|
||||
@@ -618,7 +618,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
* declaration.
|
||||
*/
|
||||
ParameterDeclarationEntry getAParameterDeclarationEntry() {
|
||||
result = getParameterDeclarationEntry(_)
|
||||
result = this.getParameterDeclarationEntry(_)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -639,7 +639,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
* return 'int p1, int p2'.
|
||||
*/
|
||||
string getParameterString() {
|
||||
result = concat(int i | | min(getParameterDeclarationEntry(i).getTypedName()), ", " order by i)
|
||||
result =
|
||||
concat(int i | | min(this.getParameterDeclarationEntry(i).getTypedName()), ", " order by i)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -647,10 +648,10 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
*
|
||||
* `extern "C" void foo();`
|
||||
*/
|
||||
predicate hasCLinkage() { getASpecifier() = "c_linkage" }
|
||||
predicate hasCLinkage() { this.getASpecifier() = "c_linkage" }
|
||||
|
||||
/** Holds if this declaration entry has a void parameter list. */
|
||||
predicate hasVoidParamList() { getASpecifier() = "void_param_list" }
|
||||
predicate hasVoidParamList() { this.getASpecifier() = "void_param_list" }
|
||||
|
||||
/** Holds if this declaration is also a definition of its function. */
|
||||
override predicate isDefinition() { fun_def(underlyingElement(this)) }
|
||||
@@ -665,7 +666,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
predicate isImplicit() { fun_implicit(underlyingElement(this)) }
|
||||
|
||||
/** Gets a type that is specified to be thrown by the declared function. */
|
||||
Type getAThrownType() { result = getThrownType(_) }
|
||||
Type getAThrownType() { result = this.getThrownType(_) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th type specified to be thrown by the declared function
|
||||
@@ -690,8 +691,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
predicate hasExceptionSpecification() {
|
||||
fun_decl_throws(underlyingElement(this), _, _) or
|
||||
fun_decl_noexcept(underlyingElement(this), _) or
|
||||
isNoThrow() or
|
||||
isNoExcept()
|
||||
this.isNoThrow() or
|
||||
this.isNoExcept()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -763,7 +764,7 @@ class Operator extends Function {
|
||||
*/
|
||||
class TemplateFunction extends Function {
|
||||
TemplateFunction() {
|
||||
is_function_template(underlyingElement(this)) and exists(getATemplateArgument())
|
||||
is_function_template(underlyingElement(this)) and exists(this.getATemplateArgument())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TemplateFunction" }
|
||||
|
||||
@@ -23,7 +23,7 @@ class Include extends PreprocessorDirective, @ppd_include {
|
||||
* Gets the token which occurs after `#include`, for example `"filename"`
|
||||
* or `<filename>`.
|
||||
*/
|
||||
string getIncludeText() { result = getHead() }
|
||||
string getIncludeText() { result = this.getHead() }
|
||||
|
||||
/** Gets the file directly included by this `#include`. */
|
||||
File getIncludedFile() { includes(underlyingElement(this), unresolveElement(result)) }
|
||||
@@ -53,7 +53,7 @@ class Include extends PreprocessorDirective, @ppd_include {
|
||||
* ```
|
||||
*/
|
||||
class IncludeNext extends Include, @ppd_include_next {
|
||||
override string toString() { result = "#include_next " + getIncludeText() }
|
||||
override string toString() { result = "#include_next " + this.getIncludeText() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,5 +65,5 @@ class IncludeNext extends Include, @ppd_include_next {
|
||||
* ```
|
||||
*/
|
||||
class Import extends Include, @ppd_objc_import {
|
||||
override string toString() { result = "#import " + getIncludeText() }
|
||||
override string toString() { result = "#import " + this.getIncludeText() }
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ class Initializer extends ControlFlowNode, @initialiser {
|
||||
override predicate fromSource() { not this.getLocation() instanceof UnknownLocation }
|
||||
|
||||
override string toString() {
|
||||
if exists(getDeclaration())
|
||||
then result = "initializer for " + max(getDeclaration().getName())
|
||||
if exists(this.getDeclaration())
|
||||
then result = "initializer for " + max(this.getDeclaration().getName())
|
||||
else result = "initializer"
|
||||
}
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ class Location extends @location {
|
||||
|
||||
/** Holds if location `l` is completely contained within this one. */
|
||||
predicate subsumes(Location l) {
|
||||
exists(File f | f = getFile() |
|
||||
exists(int thisStart, int thisEnd | charLoc(f, thisStart, thisEnd) |
|
||||
exists(File f | f = this.getFile() |
|
||||
exists(int thisStart, int thisEnd | this.charLoc(f, thisStart, thisEnd) |
|
||||
exists(int lStart, int lEnd | l.charLoc(f, lStart, lEnd) |
|
||||
thisStart <= lStart and lEnd <= thisEnd
|
||||
)
|
||||
@@ -97,10 +97,10 @@ class Location extends @location {
|
||||
* see `subsumes`.
|
||||
*/
|
||||
predicate charLoc(File f, int start, int end) {
|
||||
f = getFile() and
|
||||
f = this.getFile() and
|
||||
exists(int maxCols | maxCols = maxCols(f) |
|
||||
start = getStartLine() * maxCols + getStartColumn() and
|
||||
end = getEndLine() * maxCols + getEndColumn()
|
||||
start = this.getStartLine() * maxCols + this.getStartColumn() and
|
||||
end = this.getEndLine() * maxCols + this.getEndColumn()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ class Locatable extends Element { }
|
||||
* expressions, one for statements and one for other program elements.
|
||||
*/
|
||||
class UnknownLocation extends Location {
|
||||
UnknownLocation() { getFile().getAbsolutePath() = "" }
|
||||
UnknownLocation() { this.getFile().getAbsolutePath() = "" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,10 +44,10 @@ class Macro extends PreprocessorDirective, @ppd_define {
|
||||
* Gets the name of the macro. For example, `MAX` in
|
||||
* `#define MAX(x,y) (((x)>(y))?(x):(y))`.
|
||||
*/
|
||||
string getName() { result = getHead().splitAt("(", 0) }
|
||||
string getName() { result = this.getHead().splitAt("(", 0) }
|
||||
|
||||
/** Holds if the macro has name `name`. */
|
||||
predicate hasName(string name) { getName() = name }
|
||||
predicate hasName(string name) { this.getName() = name }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +130,7 @@ class MacroAccess extends Locatable, @macroinvocation {
|
||||
override string toString() { result = this.getMacro().getHead() }
|
||||
|
||||
/** Gets the name of the accessed macro. */
|
||||
string getMacroName() { result = getMacro().getName() }
|
||||
string getMacroName() { result = this.getMacro().getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,8 +197,8 @@ class MacroInvocation extends MacroAccess {
|
||||
* expression. In other cases, it may have multiple results or no results.
|
||||
*/
|
||||
Expr getExpr() {
|
||||
result = getAnExpandedElement() and
|
||||
not result.getParent() = getAnExpandedElement() and
|
||||
result = this.getAnExpandedElement() and
|
||||
not result.getParent() = this.getAnExpandedElement() and
|
||||
not result instanceof Conversion
|
||||
}
|
||||
|
||||
@@ -208,8 +208,8 @@ class MacroInvocation extends MacroAccess {
|
||||
* element is not a statement (for example if it is an expression).
|
||||
*/
|
||||
Stmt getStmt() {
|
||||
result = getAnExpandedElement() and
|
||||
not result.getParent() = getAnExpandedElement()
|
||||
result = this.getAnExpandedElement() and
|
||||
not result.getParent() = this.getAnExpandedElement()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,7 +278,7 @@ deprecated class MacroInvocationExpr extends Expr {
|
||||
MacroInvocation getInvocation() { result.getExpr() = this }
|
||||
|
||||
/** Gets the name of the invoked macro. */
|
||||
string getMacroName() { result = getInvocation().getMacroName() }
|
||||
string getMacroName() { result = this.getInvocation().getMacroName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +298,7 @@ deprecated class MacroInvocationStmt extends Stmt {
|
||||
MacroInvocation getInvocation() { result.getStmt() = this }
|
||||
|
||||
/** Gets the name of the invoked macro. */
|
||||
string getMacroName() { result = getInvocation().getMacroName() }
|
||||
string getMacroName() { result = this.getInvocation().getMacroName() }
|
||||
}
|
||||
|
||||
/** Holds if `l` is the location of a macro. */
|
||||
|
||||
@@ -36,7 +36,9 @@ class MemberFunction extends Function {
|
||||
* `this` parameter.
|
||||
*/
|
||||
override int getEffectiveNumberOfParameters() {
|
||||
if isStatic() then result = getNumberOfParameters() else result = getNumberOfParameters() + 1
|
||||
if this.isStatic()
|
||||
then result = this.getNumberOfParameters()
|
||||
else result = this.getNumberOfParameters() + 1
|
||||
}
|
||||
|
||||
/** Holds if this member is private. */
|
||||
@@ -49,13 +51,13 @@ class MemberFunction extends Function {
|
||||
predicate isPublic() { this.hasSpecifier("public") }
|
||||
|
||||
/** Holds if this declaration has the lvalue ref-qualifier */
|
||||
predicate isLValueRefQualified() { hasSpecifier("&") }
|
||||
predicate isLValueRefQualified() { this.hasSpecifier("&") }
|
||||
|
||||
/** Holds if this declaration has the rvalue ref-qualifier */
|
||||
predicate isRValueRefQualified() { hasSpecifier("&&") }
|
||||
predicate isRValueRefQualified() { this.hasSpecifier("&&") }
|
||||
|
||||
/** Holds if this declaration has a ref-qualifier */
|
||||
predicate isRefQualified() { isLValueRefQualified() or isRValueRefQualified() }
|
||||
predicate isRefQualified() { this.isLValueRefQualified() or this.isRValueRefQualified() }
|
||||
|
||||
/** Holds if this function overrides that function. */
|
||||
predicate overrides(MemberFunction that) {
|
||||
@@ -73,10 +75,10 @@ class MemberFunction extends Function {
|
||||
* class body.
|
||||
*/
|
||||
FunctionDeclarationEntry getClassBodyDeclarationEntry() {
|
||||
if strictcount(getADeclarationEntry()) = 1
|
||||
then result = getDefinition()
|
||||
if strictcount(this.getADeclarationEntry()) = 1
|
||||
then result = this.getDefinition()
|
||||
else (
|
||||
result = getADeclarationEntry() and result != getDefinition()
|
||||
result = this.getADeclarationEntry() and result != this.getDefinition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -198,7 +200,7 @@ class Constructor extends MemberFunction {
|
||||
* compiler-generated action which initializes a base class or member
|
||||
* variable.
|
||||
*/
|
||||
ConstructorInit getAnInitializer() { result = getInitializer(_) }
|
||||
ConstructorInit getAnInitializer() { result = this.getInitializer(_) }
|
||||
|
||||
/**
|
||||
* Gets an entry in the constructor's initializer list, or a
|
||||
@@ -220,8 +222,8 @@ class ImplicitConversionFunction extends MemberFunction {
|
||||
functions(underlyingElement(this), _, 4)
|
||||
or
|
||||
// ConversionConstructor (deprecated)
|
||||
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
|
||||
not hasSpecifier("explicit")
|
||||
strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
|
||||
not this.hasSpecifier("explicit")
|
||||
}
|
||||
|
||||
/** Gets the type this `ImplicitConversionFunction` takes as input. */
|
||||
@@ -248,8 +250,8 @@ class ImplicitConversionFunction extends MemberFunction {
|
||||
*/
|
||||
deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction {
|
||||
ConversionConstructor() {
|
||||
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
|
||||
not hasSpecifier("explicit")
|
||||
strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
|
||||
not this.hasSpecifier("explicit")
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -301,15 +303,15 @@ class CopyConstructor extends Constructor {
|
||||
hasCopySignature(this) and
|
||||
(
|
||||
// The rest of the parameters all have default values
|
||||
forall(int i | i > 0 and exists(getParameter(i)) | getParameter(i).hasInitializer())
|
||||
forall(int i | i > 0 and exists(this.getParameter(i)) | this.getParameter(i).hasInitializer())
|
||||
or
|
||||
// or this is a template class, in which case the default values have
|
||||
// not been extracted even if they exist. In that case, we assume that
|
||||
// there are default values present since that is the most common case
|
||||
// in real-world code.
|
||||
getDeclaringType() instanceof TemplateClass
|
||||
this.getDeclaringType() instanceof TemplateClass
|
||||
) and
|
||||
not exists(getATemplateArgument())
|
||||
not exists(this.getATemplateArgument())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "CopyConstructor" }
|
||||
@@ -325,8 +327,8 @@ class CopyConstructor extends Constructor {
|
||||
// type-checked for each template instantiation; if an argument in an
|
||||
// instantiation fails to type-check then the corresponding parameter has
|
||||
// no default argument in the instantiation.
|
||||
getDeclaringType() instanceof TemplateClass and
|
||||
getNumberOfParameters() > 1
|
||||
this.getDeclaringType() instanceof TemplateClass and
|
||||
this.getNumberOfParameters() > 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,15 +360,15 @@ class MoveConstructor extends Constructor {
|
||||
hasMoveSignature(this) and
|
||||
(
|
||||
// The rest of the parameters all have default values
|
||||
forall(int i | i > 0 and exists(getParameter(i)) | getParameter(i).hasInitializer())
|
||||
forall(int i | i > 0 and exists(this.getParameter(i)) | this.getParameter(i).hasInitializer())
|
||||
or
|
||||
// or this is a template class, in which case the default values have
|
||||
// not been extracted even if they exist. In that case, we assume that
|
||||
// there are default values present since that is the most common case
|
||||
// in real-world code.
|
||||
getDeclaringType() instanceof TemplateClass
|
||||
this.getDeclaringType() instanceof TemplateClass
|
||||
) and
|
||||
not exists(getATemplateArgument())
|
||||
not exists(this.getATemplateArgument())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MoveConstructor" }
|
||||
@@ -382,8 +384,8 @@ class MoveConstructor extends Constructor {
|
||||
// type-checked for each template instantiation; if an argument in an
|
||||
// instantiation fails to type-check then the corresponding parameter has
|
||||
// no default argument in the instantiation.
|
||||
getDeclaringType() instanceof TemplateClass and
|
||||
getNumberOfParameters() > 1
|
||||
this.getDeclaringType() instanceof TemplateClass and
|
||||
this.getNumberOfParameters() > 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +428,7 @@ class Destructor extends MemberFunction {
|
||||
* Gets a compiler-generated action which destructs a base class or member
|
||||
* variable.
|
||||
*/
|
||||
DestructorDestruction getADestruction() { result = getDestruction(_) }
|
||||
DestructorDestruction getADestruction() { result = this.getDestruction(_) }
|
||||
|
||||
/**
|
||||
* Gets a compiler-generated action which destructs a base class or member
|
||||
@@ -475,16 +477,16 @@ class ConversionOperator extends MemberFunction, ImplicitConversionFunction {
|
||||
*/
|
||||
class CopyAssignmentOperator extends Operator {
|
||||
CopyAssignmentOperator() {
|
||||
hasName("operator=") and
|
||||
this.hasName("operator=") and
|
||||
(
|
||||
hasCopySignature(this)
|
||||
or
|
||||
// Unlike CopyConstructor, this member allows a non-reference
|
||||
// parameter.
|
||||
getParameter(0).getUnspecifiedType() = getDeclaringType()
|
||||
this.getParameter(0).getUnspecifiedType() = this.getDeclaringType()
|
||||
) and
|
||||
not exists(this.getParameter(1)) and
|
||||
not exists(getATemplateArgument())
|
||||
not exists(this.getATemplateArgument())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "CopyAssignmentOperator" }
|
||||
@@ -507,10 +509,10 @@ class CopyAssignmentOperator extends Operator {
|
||||
*/
|
||||
class MoveAssignmentOperator extends Operator {
|
||||
MoveAssignmentOperator() {
|
||||
hasName("operator=") and
|
||||
this.hasName("operator=") and
|
||||
hasMoveSignature(this) and
|
||||
not exists(this.getParameter(1)) and
|
||||
not exists(getATemplateArgument())
|
||||
not exists(this.getATemplateArgument())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MoveAssignmentOperator" }
|
||||
|
||||
@@ -38,8 +38,8 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
* unless the namespace has exactly one declaration entry.
|
||||
*/
|
||||
override Location getLocation() {
|
||||
if strictcount(getADeclarationEntry()) = 1
|
||||
then result = getADeclarationEntry().getLocation()
|
||||
if strictcount(this.getADeclarationEntry()) = 1
|
||||
then result = this.getADeclarationEntry().getLocation()
|
||||
else result instanceof UnknownDefaultLocation
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
predicate hasName(string name) { name = this.getName() }
|
||||
|
||||
/** Holds if this namespace is anonymous. */
|
||||
predicate isAnonymous() { hasName("(unnamed namespace)") }
|
||||
predicate isAnonymous() { this.hasName("(unnamed namespace)") }
|
||||
|
||||
/** Gets the name of the parent namespace, if it exists. */
|
||||
private string getParentName() {
|
||||
@@ -60,9 +60,9 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
|
||||
/** Gets the qualified name of this namespace. For example: `a::b`. */
|
||||
string getQualifiedName() {
|
||||
if exists(getParentName())
|
||||
then result = getParentNamespace().getQualifiedName() + "::" + getName()
|
||||
else result = getName()
|
||||
if exists(this.getParentName())
|
||||
then result = this.getParentNamespace().getQualifiedName() + "::" + this.getName()
|
||||
else result = this.getName()
|
||||
}
|
||||
|
||||
/** Gets the parent namespace, if any. */
|
||||
@@ -99,7 +99,7 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
/** Gets a version of the `QualifiedName` that is more suitable for display purposes. */
|
||||
string getFriendlyName() { result = this.getQualifiedName() }
|
||||
|
||||
final override string toString() { result = getFriendlyName() }
|
||||
final override string toString() { result = this.getFriendlyName() }
|
||||
|
||||
/** Gets a declaration of (part of) this namespace. */
|
||||
NamespaceDeclarationEntry getADeclarationEntry() { result.getNamespace() = this }
|
||||
|
||||
@@ -40,12 +40,12 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
*/
|
||||
override string getName() {
|
||||
exists(VariableDeclarationEntry vde |
|
||||
vde = getANamedDeclarationEntry() and result = vde.getName()
|
||||
vde = this.getANamedDeclarationEntry() and result = vde.getName()
|
||||
|
|
||||
vde.isDefinition() or not getANamedDeclarationEntry().isDefinition()
|
||||
vde.isDefinition() or not this.getANamedDeclarationEntry().isDefinition()
|
||||
)
|
||||
or
|
||||
not exists(getANamedDeclarationEntry()) and
|
||||
not exists(this.getANamedDeclarationEntry()) and
|
||||
result = "(unnamed parameter " + this.getIndex().toString() + ")"
|
||||
}
|
||||
|
||||
@@ -58,8 +58,12 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
*/
|
||||
string getTypedName() {
|
||||
exists(string typeString, string nameString |
|
||||
(if exists(getType().getName()) then typeString = getType().getName() else typeString = "") and
|
||||
(if exists(getName()) then nameString = getName() else nameString = "") and
|
||||
(
|
||||
if exists(this.getType().getName())
|
||||
then typeString = this.getType().getName()
|
||||
else typeString = ""
|
||||
) and
|
||||
(if exists(this.getName()) then nameString = this.getName() else nameString = "") and
|
||||
(
|
||||
if typeString != "" and nameString != ""
|
||||
then result = typeString + " " + nameString
|
||||
@@ -69,7 +73,7 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
}
|
||||
|
||||
private VariableDeclarationEntry getANamedDeclarationEntry() {
|
||||
result = getAnEffectiveDeclarationEntry() and result.getName() != ""
|
||||
result = this.getAnEffectiveDeclarationEntry() and result.getName() != ""
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,13 +86,13 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
* own).
|
||||
*/
|
||||
private VariableDeclarationEntry getAnEffectiveDeclarationEntry() {
|
||||
if getFunction().isConstructedFrom(_)
|
||||
if this.getFunction().isConstructedFrom(_)
|
||||
then
|
||||
exists(Function prototypeInstantiation |
|
||||
prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and
|
||||
getFunction().isConstructedFrom(prototypeInstantiation)
|
||||
prototypeInstantiation.getParameter(this.getIndex()) = result.getVariable() and
|
||||
this.getFunction().isConstructedFrom(prototypeInstantiation)
|
||||
)
|
||||
else result = getADeclarationEntry()
|
||||
else result = this.getADeclarationEntry()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +118,7 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
* `getName()` is not "(unnamed parameter i)" (where `i` is the index
|
||||
* of the parameter).
|
||||
*/
|
||||
predicate isNamed() { exists(getANamedDeclarationEntry()) }
|
||||
predicate isNamed() { exists(this.getANamedDeclarationEntry()) }
|
||||
|
||||
/**
|
||||
* Gets the function to which this parameter belongs, if it is a function
|
||||
@@ -157,9 +161,9 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
*/
|
||||
override Location getLocation() {
|
||||
exists(VariableDeclarationEntry vde |
|
||||
vde = getAnEffectiveDeclarationEntry() and result = vde.getLocation()
|
||||
vde = this.getAnEffectiveDeclarationEntry() and result = vde.getLocation()
|
||||
|
|
||||
vde.isDefinition() or not getAnEffectiveDeclarationEntry().isDefinition()
|
||||
vde.isDefinition() or not this.getAnEffectiveDeclarationEntry().isDefinition()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ class PreprocessorDirective extends Locatable, @preprocdirect {
|
||||
PreprocessorBranch getAGuard() {
|
||||
exists(PreprocessorEndif e, int line |
|
||||
result.getEndIf() = e and
|
||||
e.getFile() = getFile() and
|
||||
result.getFile() = getFile() and
|
||||
e.getFile() = this.getFile() and
|
||||
result.getFile() = this.getFile() and
|
||||
line = this.getLocation().getStartLine() and
|
||||
result.getLocation().getStartLine() < line and
|
||||
line < e.getLocation().getEndLine()
|
||||
@@ -69,7 +69,9 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
|
||||
* directives in different translation units, then there can be more than
|
||||
* one result.
|
||||
*/
|
||||
PreprocessorEndif getEndIf() { preprocpair(unresolveElement(getIf()), unresolveElement(result)) }
|
||||
PreprocessorEndif getEndIf() {
|
||||
preprocpair(unresolveElement(this.getIf()), unresolveElement(result))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next `#elif`, `#else` or `#endif` matching this branching
|
||||
@@ -137,7 +139,7 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
|
||||
* which evaluated it, or was not taken by any translation unit which
|
||||
* evaluated it.
|
||||
*/
|
||||
predicate wasPredictable() { not (wasTaken() and wasNotTaken()) }
|
||||
predicate wasPredictable() { not (this.wasTaken() and this.wasNotTaken()) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +270,7 @@ class PreprocessorUndef extends PreprocessorDirective, @ppd_undef {
|
||||
/**
|
||||
* Gets the name of the macro that is undefined.
|
||||
*/
|
||||
string getName() { result = getHead() }
|
||||
string getName() { result = this.getHead() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -105,8 +105,8 @@ private class DumpType extends Type {
|
||||
// for a `SpecifiedType`, insert the qualifiers after
|
||||
// `getDeclaratorSuffixBeforeQualifiers()`.
|
||||
result =
|
||||
getTypeSpecifier() + getDeclaratorPrefix() + getDeclaratorSuffixBeforeQualifiers() +
|
||||
getDeclaratorSuffix()
|
||||
this.getTypeSpecifier() + this.getDeclaratorPrefix() +
|
||||
this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,29 +147,35 @@ private class DumpType extends Type {
|
||||
}
|
||||
|
||||
private class BuiltInDumpType extends DumpType, BuiltInType {
|
||||
override string getTypeSpecifier() { result = toString() }
|
||||
override string getTypeSpecifier() { result = this.toString() }
|
||||
}
|
||||
|
||||
private class IntegralDumpType extends BuiltInDumpType, IntegralType {
|
||||
override string getTypeSpecifier() { result = getCanonicalArithmeticType().toString() }
|
||||
override string getTypeSpecifier() { result = this.getCanonicalArithmeticType().toString() }
|
||||
}
|
||||
|
||||
private class DerivedDumpType extends DumpType, DerivedType {
|
||||
override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
|
||||
override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
|
||||
override string getDeclaratorSuffix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class DecltypeDumpType extends DumpType, Decltype {
|
||||
override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
|
||||
override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
|
||||
|
||||
override string getDeclaratorPrefix() { result = getBaseType().(DumpType).getDeclaratorPrefix() }
|
||||
override string getDeclaratorPrefix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
|
||||
override string getDeclaratorSuffix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class PointerIshDumpType extends DerivedDumpType {
|
||||
@@ -180,10 +186,10 @@ private class PointerIshDumpType extends DerivedDumpType {
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator |
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
|
||||
if getBaseType().getUnspecifiedType() instanceof ArrayType
|
||||
then declarator = "(" + getDeclaratorToken() + ")"
|
||||
else declarator = getDeclaratorToken()
|
||||
result = this.getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
|
||||
if this.getBaseType().getUnspecifiedType() instanceof ArrayType
|
||||
then declarator = "(" + this.getDeclaratorToken() + ")"
|
||||
else declarator = this.getDeclaratorToken()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -206,13 +212,13 @@ private class RValueReferenceDumpType extends PointerIshDumpType, RValueReferenc
|
||||
}
|
||||
|
||||
private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
|
||||
override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
|
||||
override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator, string parenDeclarator, Type baseType |
|
||||
declarator = getClass().(DumpType).getTypeIdentityString() + "::*" and
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
declarator = this.getClass().(DumpType).getTypeIdentityString() + "::*" and
|
||||
result = this.getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
|
||||
baseType = this.getBaseType().getUnspecifiedType() and
|
||||
if baseType instanceof ArrayType or baseType instanceof RoutineType
|
||||
then parenDeclarator = "(" + declarator
|
||||
else parenDeclarator = declarator
|
||||
@@ -221,38 +227,44 @@ private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(Type baseType |
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
baseType = this.getBaseType().getUnspecifiedType() and
|
||||
if baseType instanceof ArrayType or baseType instanceof RoutineType
|
||||
then result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
then result = ")" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else result = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
|
||||
override string getDeclaratorSuffix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class ArrayDumpType extends DerivedDumpType, ArrayType {
|
||||
override string getDeclaratorPrefix() { result = getBaseType().(DumpType).getDeclaratorPrefix() }
|
||||
override string getDeclaratorPrefix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
if exists(getArraySize())
|
||||
if exists(this.getArraySize())
|
||||
then
|
||||
result =
|
||||
"[" + getArraySize().toString() + "]" +
|
||||
getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else result = "[]" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
"[" + this.getArraySize().toString() + "]" +
|
||||
this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else result = "[]" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
}
|
||||
|
||||
private class FunctionPointerIshDumpType extends DerivedDumpType, FunctionPointerIshType {
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
result = ")" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
|
||||
override string getDeclaratorSuffix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + "(" + getDeclaratorToken()
|
||||
result = this.getBaseType().(DumpType).getDeclaratorPrefix() + "(" + this.getDeclaratorToken()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,10 +286,10 @@ private class BlockDumpType extends FunctionPointerIshDumpType, BlockType {
|
||||
}
|
||||
|
||||
private class RoutineDumpType extends DumpType, RoutineType {
|
||||
override string getTypeSpecifier() { result = getReturnType().(DumpType).getTypeSpecifier() }
|
||||
override string getTypeSpecifier() { result = this.getReturnType().(DumpType).getTypeSpecifier() }
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getReturnType().(DumpType).getDeclaratorPrefix()
|
||||
result = this.getReturnType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
@@ -285,39 +297,41 @@ private class RoutineDumpType extends DumpType, RoutineType {
|
||||
result =
|
||||
"(" +
|
||||
concat(int i |
|
||||
exists(getParameterType(i))
|
||||
exists(this.getParameterType(i))
|
||||
|
|
||||
getParameterTypeString(getParameterType(i)), ", " order by i
|
||||
getParameterTypeString(this.getParameterType(i)), ", " order by i
|
||||
) + ")"
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result =
|
||||
getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
|
||||
getReturnType().(DumpType).getDeclaratorSuffix()
|
||||
this.getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
|
||||
this.getReturnType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string basePrefix |
|
||||
basePrefix = getBaseType().(DumpType).getDeclaratorPrefix() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType
|
||||
basePrefix = this.getBaseType().(DumpType).getDeclaratorPrefix() and
|
||||
if this.getBaseType().getUnspecifiedType() instanceof RoutineType
|
||||
then result = basePrefix
|
||||
else result = basePrefix + " " + getSpecifierString()
|
||||
else result = basePrefix + " " + this.getSpecifierString()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(string baseSuffix |
|
||||
baseSuffix = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType
|
||||
then result = baseSuffix + " " + getSpecifierString()
|
||||
baseSuffix = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
|
||||
if this.getBaseType().getUnspecifiedType() instanceof RoutineType
|
||||
then result = baseSuffix + " " + this.getSpecifierString()
|
||||
else result = baseSuffix
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
|
||||
override string getDeclaratorSuffix() {
|
||||
result = this.getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class UserDumpType extends DumpType, DumpDeclaration, UserType {
|
||||
@@ -330,18 +344,18 @@ private class UserDumpType extends DumpType, DumpDeclaration, UserType {
|
||||
// "lambda [] type at line 12, col. 40"
|
||||
// Use `min(getSimpleName())` to work around an extractor bug where a lambda can have different names
|
||||
// from different compilation units.
|
||||
simpleName = "(" + min(getSimpleName()) + ")"
|
||||
else simpleName = getSimpleName()
|
||||
simpleName = "(" + min(this.getSimpleName()) + ")"
|
||||
else simpleName = this.getSimpleName()
|
||||
) and
|
||||
result = getScopePrefix(this) + simpleName + getTemplateArgumentsString()
|
||||
result = getScopePrefix(this) + simpleName + this.getTemplateArgumentsString()
|
||||
)
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() { result = getIdentityString() }
|
||||
override string getTypeSpecifier() { result = this.getIdentityString() }
|
||||
}
|
||||
|
||||
private class DumpProxyClass extends UserDumpType, ProxyClass {
|
||||
override string getIdentityString() { result = getName() }
|
||||
override string getIdentityString() { result = this.getName() }
|
||||
}
|
||||
|
||||
private class DumpVariable extends DumpDeclaration, Variable {
|
||||
@@ -360,9 +374,9 @@ private class DumpVariable extends DumpDeclaration, Variable {
|
||||
private class DumpFunction extends DumpDeclaration, Function {
|
||||
override string getIdentityString() {
|
||||
result =
|
||||
getType().(DumpType).getTypeSpecifier() + getType().(DumpType).getDeclaratorPrefix() + " " +
|
||||
getScopePrefix(this) + getName() + getTemplateArgumentsString() +
|
||||
getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
|
||||
this.getType().(DumpType).getTypeSpecifier() + this.getType().(DumpType).getDeclaratorPrefix()
|
||||
+ " " + getScopePrefix(this) + this.getName() + this.getTemplateArgumentsString() +
|
||||
this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
@@ -370,28 +384,29 @@ private class DumpFunction extends DumpDeclaration, Function {
|
||||
result =
|
||||
"(" +
|
||||
concat(int i |
|
||||
exists(getParameter(i).getType())
|
||||
exists(this.getParameter(i).getType())
|
||||
|
|
||||
getParameterTypeString(getParameter(i).getType()), ", " order by i
|
||||
) + ")" + getQualifierString()
|
||||
getParameterTypeString(this.getParameter(i).getType()), ", " order by i
|
||||
) + ")" + this.getQualifierString()
|
||||
}
|
||||
|
||||
private string getQualifierString() {
|
||||
if exists(getACVQualifier())
|
||||
if exists(this.getACVQualifier())
|
||||
then
|
||||
result = " " + strictconcat(string qualifier | qualifier = getACVQualifier() | qualifier, " ")
|
||||
result =
|
||||
" " + strictconcat(string qualifier | qualifier = this.getACVQualifier() | qualifier, " ")
|
||||
else result = ""
|
||||
}
|
||||
|
||||
private string getACVQualifier() {
|
||||
result = getASpecifier().getName() and
|
||||
result = this.getASpecifier().getName() and
|
||||
result = ["const", "volatile"]
|
||||
}
|
||||
|
||||
private string getDeclaratorSuffix() {
|
||||
result =
|
||||
getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
|
||||
getType().(DumpType).getDeclaratorSuffix()
|
||||
this.getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
|
||||
this.getType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ class Attribute extends Element, @attribute {
|
||||
AttributeArgument getArgument(int i) { result.getAttribute() = this and result.getIndex() = i }
|
||||
|
||||
/** Gets an argument of the attribute. */
|
||||
AttributeArgument getAnArgument() { result = getArgument(_) }
|
||||
AttributeArgument getAnArgument() { result = this.getArgument(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +166,7 @@ class StdAttribute extends Attribute, @stdattribute {
|
||||
* Holds if this attribute has the given namespace and name.
|
||||
*/
|
||||
predicate hasQualifiedName(string namespace, string name) {
|
||||
namespace = getNamespace() and hasName(name)
|
||||
namespace = this.getNamespace() and this.hasName(name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ class Declspec extends Attribute, @declspec { }
|
||||
*/
|
||||
class MicrosoftAttribute extends Attribute, @msattribute {
|
||||
AttributeArgument getNamedArgument(string name) {
|
||||
result = getAnArgument() and result.getName() = name
|
||||
result = this.getAnArgument() and result.getName() = name
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,13 +212,13 @@ class AlignAs extends Attribute, @alignas {
|
||||
* ```
|
||||
*/
|
||||
class FormatAttribute extends GnuAttribute {
|
||||
FormatAttribute() { getName() = "format" }
|
||||
FormatAttribute() { this.getName() = "format" }
|
||||
|
||||
/**
|
||||
* Gets the archetype of this format attribute, for example
|
||||
* `"printf"`.
|
||||
*/
|
||||
string getArchetype() { result = getArgument(0).getValueText() }
|
||||
string getArchetype() { result = this.getArgument(0).getValueText() }
|
||||
|
||||
/**
|
||||
* Gets the index in (1-based) format attribute notation associated
|
||||
@@ -236,7 +236,7 @@ class FormatAttribute extends GnuAttribute {
|
||||
* Gets the (0-based) index of the format string,
|
||||
* according to this attribute.
|
||||
*/
|
||||
int getFormatIndex() { result = getArgument(1).getValueInt() - firstArgumentNumber() }
|
||||
int getFormatIndex() { result = this.getArgument(1).getValueInt() - this.firstArgumentNumber() }
|
||||
|
||||
/**
|
||||
* Gets the (0-based) index of the first format argument (if any),
|
||||
@@ -244,8 +244,8 @@ class FormatAttribute extends GnuAttribute {
|
||||
*/
|
||||
int getFirstFormatArgIndex() {
|
||||
exists(int val |
|
||||
val = getArgument(2).getValueInt() and
|
||||
result = val - firstArgumentNumber() and
|
||||
val = this.getArgument(2).getValueInt() and
|
||||
result = val - this.firstArgumentNumber() and
|
||||
not val = 0 // indicates a `vprintf` style format function with arguments not directly available.
|
||||
)
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class AttributeArgument extends Element, @attribute_arg {
|
||||
/**
|
||||
* Gets the value of this argument, if its value is integral.
|
||||
*/
|
||||
int getValueInt() { result = getValueText().toInt() }
|
||||
int getValueInt() { result = this.getValueText().toInt() }
|
||||
|
||||
/**
|
||||
* Gets the value of this argument, if its value is a type.
|
||||
@@ -304,11 +304,11 @@ class AttributeArgument extends Element, @attribute_arg {
|
||||
then result = "empty argument"
|
||||
else
|
||||
exists(string prefix, string tail |
|
||||
(if exists(getName()) then prefix = getName() + "=" else prefix = "") and
|
||||
(if exists(this.getName()) then prefix = this.getName() + "=" else prefix = "") and
|
||||
(
|
||||
if exists(@attribute_arg_type self | self = underlyingElement(this))
|
||||
then tail = getValueType().getName()
|
||||
else tail = getValueText()
|
||||
then tail = this.getValueType().getName()
|
||||
else tail = this.getValueText()
|
||||
) and
|
||||
result = prefix + tail
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ class Struct extends Class {
|
||||
* ```
|
||||
*/
|
||||
class LocalStruct extends Struct {
|
||||
LocalStruct() { isLocal() }
|
||||
LocalStruct() { this.isLocal() }
|
||||
|
||||
override string getAPrimaryQlClass() { not this instanceof LocalUnion and result = "LocalStruct" }
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import semmle.code.cpp.File
|
||||
*/
|
||||
private class GoogleTestHeader extends File {
|
||||
GoogleTestHeader() {
|
||||
getBaseName() = "gtest.h" and
|
||||
getParentContainer().getBaseName() = "gtest"
|
||||
this.getBaseName() = "gtest.h" and
|
||||
this.getParentContainer().getBaseName() = "gtest"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ private class GoogleTest extends MacroInvocation {
|
||||
*/
|
||||
private class BoostTestFolder extends Folder {
|
||||
BoostTestFolder() {
|
||||
getBaseName() = "test" and
|
||||
getParentContainer().getBaseName() = "boost"
|
||||
this.getBaseName() = "test" and
|
||||
this.getParentContainer().getBaseName() = "boost"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ private class BoostTest extends MacroInvocation {
|
||||
* The `cppunit` directory.
|
||||
*/
|
||||
private class CppUnitFolder extends Folder {
|
||||
CppUnitFolder() { getBaseName() = "cppunit" }
|
||||
CppUnitFolder() { this.getBaseName() = "cppunit" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,8 +57,8 @@ private class CppUnitFolder extends Folder {
|
||||
*/
|
||||
private class CppUnitClass extends Class {
|
||||
CppUnitClass() {
|
||||
getFile().getParentContainer+() instanceof CppUnitFolder and
|
||||
getNamespace().getParentNamespace*().getName() = "CppUnit"
|
||||
this.getFile().getParentContainer+() instanceof CppUnitFolder and
|
||||
this.getNamespace().getParentNamespace*().getName() = "CppUnit"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class Type extends Locatable, @type {
|
||||
* Holds if this type refers to type `t` (by default,
|
||||
* a type always refers to itself).
|
||||
*/
|
||||
predicate refersTo(Type t) { refersToDirectly*(t) }
|
||||
predicate refersTo(Type t) { this.refersToDirectly*(t) }
|
||||
|
||||
/**
|
||||
* Holds if this type refers to type `t` directly.
|
||||
@@ -1080,11 +1080,11 @@ class DerivedType extends Type, @derivedtype {
|
||||
|
||||
override predicate refersToDirectly(Type t) { t = this.getBaseType() }
|
||||
|
||||
override predicate involvesReference() { getBaseType().involvesReference() }
|
||||
override predicate involvesReference() { this.getBaseType().involvesReference() }
|
||||
|
||||
override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
|
||||
override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
|
||||
|
||||
override Type stripType() { result = getBaseType().stripType() }
|
||||
override Type stripType() { result = this.getBaseType().stripType() }
|
||||
|
||||
/**
|
||||
* Holds if this type has the `__autoreleasing` specifier or if it points to
|
||||
@@ -1165,33 +1165,35 @@ class Decltype extends Type, @decltype {
|
||||
*/
|
||||
predicate parenthesesWouldChangeMeaning() { decltypes(underlyingElement(this), _, _, true) }
|
||||
|
||||
override Type getUnderlyingType() { result = getBaseType().getUnderlyingType() }
|
||||
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }
|
||||
|
||||
override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
|
||||
override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
|
||||
|
||||
override Type stripType() { result = getBaseType().stripType() }
|
||||
override Type stripType() { result = this.getBaseType().stripType() }
|
||||
|
||||
override Type resolveTypedefs() { result = getBaseType().resolveTypedefs() }
|
||||
override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
|
||||
|
||||
override Location getLocation() { result = getExpr().getLocation() }
|
||||
override Location getLocation() { result = this.getExpr().getLocation() }
|
||||
|
||||
override string toString() { result = "decltype(...)" }
|
||||
|
||||
override string getName() { none() }
|
||||
|
||||
override int getSize() { result = getBaseType().getSize() }
|
||||
override int getSize() { result = this.getBaseType().getSize() }
|
||||
|
||||
override int getAlignment() { result = getBaseType().getAlignment() }
|
||||
override int getAlignment() { result = this.getBaseType().getAlignment() }
|
||||
|
||||
override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
|
||||
override int getPointerIndirectionLevel() {
|
||||
result = this.getBaseType().getPointerIndirectionLevel()
|
||||
}
|
||||
|
||||
override string explain() {
|
||||
result = "decltype resulting in {" + this.getBaseType().explain() + "}"
|
||||
}
|
||||
|
||||
override predicate involvesReference() { getBaseType().involvesReference() }
|
||||
override predicate involvesReference() { this.getBaseType().involvesReference() }
|
||||
|
||||
override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
|
||||
override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
|
||||
|
||||
override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() }
|
||||
|
||||
@@ -1223,7 +1225,7 @@ class PointerType extends DerivedType {
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
|
||||
override Type resolveTypedefs() {
|
||||
result.(PointerType).getBaseType() = getBaseType().resolveTypedefs()
|
||||
result.(PointerType).getBaseType() = this.getBaseType().resolveTypedefs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1240,7 +1242,9 @@ class ReferenceType extends DerivedType {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ReferenceType" }
|
||||
|
||||
override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
|
||||
override int getPointerIndirectionLevel() {
|
||||
result = this.getBaseType().getPointerIndirectionLevel()
|
||||
}
|
||||
|
||||
override string explain() { result = "reference to {" + this.getBaseType().explain() + "}" }
|
||||
|
||||
@@ -1251,7 +1255,7 @@ class ReferenceType extends DerivedType {
|
||||
override predicate involvesReference() { any() }
|
||||
|
||||
override Type resolveTypedefs() {
|
||||
result.(ReferenceType).getBaseType() = getBaseType().resolveTypedefs()
|
||||
result.(ReferenceType).getBaseType() = this.getBaseType().resolveTypedefs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1330,11 +1334,11 @@ class SpecifiedType extends DerivedType {
|
||||
}
|
||||
|
||||
override Type resolveTypedefs() {
|
||||
result.(SpecifiedType).getBaseType() = getBaseType().resolveTypedefs() and
|
||||
result.getASpecifier() = getASpecifier()
|
||||
result.(SpecifiedType).getBaseType() = this.getBaseType().resolveTypedefs() and
|
||||
result.getASpecifier() = this.getASpecifier()
|
||||
}
|
||||
|
||||
override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
|
||||
override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1433,7 +1437,8 @@ class GNUVectorType extends DerivedType {
|
||||
override int getAlignment() { arraysizes(underlyingElement(this), _, _, result) }
|
||||
|
||||
override string explain() {
|
||||
result = "GNU " + getNumElements() + " element vector of {" + this.getBaseType().explain() + "}"
|
||||
result =
|
||||
"GNU " + this.getNumElements() + " element vector of {" + this.getBaseType().explain() + "}"
|
||||
}
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
@@ -1468,7 +1473,9 @@ class FunctionReferenceType extends FunctionPointerIshType {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FunctionReferenceType" }
|
||||
|
||||
override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
|
||||
override int getPointerIndirectionLevel() {
|
||||
result = this.getBaseType().getPointerIndirectionLevel()
|
||||
}
|
||||
|
||||
override string explain() {
|
||||
result = "reference to {" + this.getBaseType().(RoutineType).explain() + "}"
|
||||
@@ -1535,8 +1542,8 @@ class FunctionPointerIshType extends DerivedType {
|
||||
int getNumberOfParameters() { result = count(int i | exists(this.getParameterType(i))) }
|
||||
|
||||
override predicate involvesTemplateParameter() {
|
||||
getReturnType().involvesTemplateParameter() or
|
||||
getAParameterType().involvesTemplateParameter()
|
||||
this.getReturnType().involvesTemplateParameter() or
|
||||
this.getAParameterType().involvesTemplateParameter()
|
||||
}
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
@@ -1581,7 +1588,7 @@ class PointerToMemberType extends Type, @ptrtomember {
|
||||
this.getBaseType().explain() + "}"
|
||||
}
|
||||
|
||||
override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
|
||||
override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
}
|
||||
@@ -1670,8 +1677,8 @@ class RoutineType extends Type, @routinetype {
|
||||
override predicate isDeeplyConstBelow() { none() } // Current limitation: no such thing as a const routine type
|
||||
|
||||
override predicate involvesTemplateParameter() {
|
||||
getReturnType().involvesTemplateParameter() or
|
||||
getAParameterType().involvesTemplateParameter()
|
||||
this.getReturnType().involvesTemplateParameter() or
|
||||
this.getAParameterType().involvesTemplateParameter()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class TypedefType extends UserType {
|
||||
|
||||
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }
|
||||
|
||||
override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
|
||||
override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
|
||||
|
||||
override int getSize() { result = this.getBaseType().getSize() }
|
||||
|
||||
@@ -43,11 +43,11 @@ class TypedefType extends UserType {
|
||||
result = this.getBaseType().getASpecifier()
|
||||
}
|
||||
|
||||
override predicate involvesReference() { getBaseType().involvesReference() }
|
||||
override predicate involvesReference() { this.getBaseType().involvesReference() }
|
||||
|
||||
override Type resolveTypedefs() { result = getBaseType().resolveTypedefs() }
|
||||
override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
|
||||
|
||||
override Type stripType() { result = getBaseType().stripType() }
|
||||
override Type stripType() { result = this.getBaseType().stripType() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +90,7 @@ class UsingAliasTypedefType extends TypedefType {
|
||||
* ```
|
||||
*/
|
||||
class LocalTypedefType extends TypedefType {
|
||||
LocalTypedefType() { isLocal() }
|
||||
LocalTypedefType() { this.isLocal() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LocalTypedefType" }
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Union extends Struct {
|
||||
* ```
|
||||
*/
|
||||
class LocalUnion extends Union {
|
||||
LocalUnion() { isLocal() }
|
||||
LocalUnion() { this.isLocal() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LocalUnion" }
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
* Gets the simple name of this type, without any template parameters. For example
|
||||
* if the name of the type is `"myType<int>"`, the simple name is just `"myType"`.
|
||||
*/
|
||||
string getSimpleName() { result = getName().regexpReplaceAll("<.*", "") }
|
||||
string getSimpleName() { result = this.getName().regexpReplaceAll("<.*", "") }
|
||||
|
||||
override predicate hasName(string name) { usertypes(underlyingElement(this), name, _) }
|
||||
|
||||
/** Holds if this type is anonymous. */
|
||||
predicate isAnonymous() { getName().matches("(unnamed%") }
|
||||
predicate isAnonymous() { this.getName().matches("(unnamed%") }
|
||||
|
||||
override predicate hasSpecifier(string s) { Type.super.hasSpecifier(s) }
|
||||
|
||||
override Specifier getASpecifier() { result = Type.super.getASpecifier() }
|
||||
|
||||
override Location getLocation() {
|
||||
if hasDefinition()
|
||||
if this.hasDefinition()
|
||||
then result = this.getDefinitionLocation()
|
||||
else result = this.getADeclarationLocation()
|
||||
}
|
||||
@@ -53,16 +53,16 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
|
||||
}
|
||||
|
||||
override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
|
||||
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
|
||||
|
||||
override TypeDeclarationEntry getDefinition() {
|
||||
result = getADeclarationEntry() and
|
||||
result = this.getADeclarationEntry() and
|
||||
result.isDefinition()
|
||||
}
|
||||
|
||||
override Location getDefinitionLocation() {
|
||||
if exists(getDefinition())
|
||||
then result = getDefinition().getLocation()
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinition().getLocation()
|
||||
else
|
||||
exists(Class t |
|
||||
this.(Class).isConstructedFrom(t) and result = t.getDefinition().getLocation()
|
||||
@@ -80,7 +80,7 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
* Holds if this is a local type (that is, a type that has a directly-enclosing
|
||||
* function).
|
||||
*/
|
||||
predicate isLocal() { exists(getEnclosingFunction()) }
|
||||
predicate isLocal() { exists(this.getEnclosingFunction()) }
|
||||
|
||||
/*
|
||||
* Dummy implementations of inherited methods. This class must not be
|
||||
@@ -107,9 +107,9 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
* ```
|
||||
*/
|
||||
class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
|
||||
override UserType getDeclaration() { result = getType() }
|
||||
override UserType getDeclaration() { result = this.getType() }
|
||||
|
||||
override string getName() { result = getType().getName() }
|
||||
override string getName() { result = this.getType().getName() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeDeclarationEntry" }
|
||||
|
||||
|
||||
@@ -104,17 +104,17 @@ class Variable extends Declaration, @variable {
|
||||
|
||||
override VariableDeclarationEntry getADeclarationEntry() { result.getDeclaration() = this }
|
||||
|
||||
override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
|
||||
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
|
||||
|
||||
override VariableDeclarationEntry getDefinition() {
|
||||
result = getADeclarationEntry() and
|
||||
result = this.getADeclarationEntry() and
|
||||
result.isDefinition()
|
||||
}
|
||||
|
||||
override Location getDefinitionLocation() { result = getDefinition().getLocation() }
|
||||
override Location getDefinitionLocation() { result = this.getDefinition().getLocation() }
|
||||
|
||||
override Location getLocation() {
|
||||
if exists(getDefinition())
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinitionLocation()
|
||||
else result = this.getADeclarationLocation()
|
||||
}
|
||||
@@ -199,7 +199,7 @@ class Variable extends Declaration, @variable {
|
||||
* ```
|
||||
*/
|
||||
class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
|
||||
override Variable getDeclaration() { result = getVariable() }
|
||||
override Variable getDeclaration() { result = this.getVariable() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "VariableDeclarationEntry" }
|
||||
|
||||
@@ -276,32 +276,33 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
|
||||
int getIndex() { param_decl_bind(underlyingElement(this), result, _) }
|
||||
|
||||
private string getAnonymousParameterDescription() {
|
||||
not exists(getName()) and
|
||||
not exists(this.getName()) and
|
||||
exists(string idx |
|
||||
idx =
|
||||
((getIndex() + 1).toString() + "th")
|
||||
((this.getIndex() + 1).toString() + "th")
|
||||
.replaceAll("1th", "1st")
|
||||
.replaceAll("2th", "2nd")
|
||||
.replaceAll("3th", "3rd")
|
||||
.replaceAll("11st", "11th")
|
||||
.replaceAll("12nd", "12th")
|
||||
.replaceAll("13rd", "13th") and
|
||||
if exists(getCanonicalName())
|
||||
then result = "declaration of " + getCanonicalName() + " as anonymous " + idx + " parameter"
|
||||
if exists(this.getCanonicalName())
|
||||
then
|
||||
result = "declaration of " + this.getCanonicalName() + " as anonymous " + idx + " parameter"
|
||||
else result = "declaration of " + idx + " parameter"
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
isDefinition() and
|
||||
result = "definition of " + getName()
|
||||
this.isDefinition() and
|
||||
result = "definition of " + this.getName()
|
||||
or
|
||||
not isDefinition() and
|
||||
if getName() = getCanonicalName()
|
||||
then result = "declaration of " + getName()
|
||||
else result = "declaration of " + getCanonicalName() + " as " + getName()
|
||||
not this.isDefinition() and
|
||||
if this.getName() = this.getCanonicalName()
|
||||
then result = "declaration of " + this.getName()
|
||||
else result = "declaration of " + this.getCanonicalName() + " as " + this.getName()
|
||||
or
|
||||
result = getAnonymousParameterDescription()
|
||||
result = this.getAnonymousParameterDescription()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,8 +312,12 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
|
||||
*/
|
||||
string getTypedName() {
|
||||
exists(string typeString, string nameString |
|
||||
(if exists(getType().getName()) then typeString = getType().getName() else typeString = "") and
|
||||
(if exists(getName()) then nameString = getName() else nameString = "") and
|
||||
(
|
||||
if exists(this.getType().getName())
|
||||
then typeString = this.getType().getName()
|
||||
else typeString = ""
|
||||
) and
|
||||
(if exists(this.getName()) then nameString = this.getName() else nameString = "") and
|
||||
if typeString != "" and nameString != ""
|
||||
then result = typeString + " " + nameString
|
||||
else result = typeString + nameString
|
||||
@@ -540,7 +545,7 @@ class MemberVariable extends Variable, @membervariable {
|
||||
}
|
||||
|
||||
/** Holds if this member is mutable. */
|
||||
predicate isMutable() { getADeclarationEntry().hasSpecifier("mutable") }
|
||||
predicate isMutable() { this.getADeclarationEntry().hasSpecifier("mutable") }
|
||||
|
||||
private Type getAType() { membervariables(underlyingElement(this), unresolveElement(result), _) }
|
||||
}
|
||||
|
||||
@@ -375,8 +375,8 @@ class Wchar_t extends Type {
|
||||
class MicrosoftInt8Type extends IntegralType {
|
||||
MicrosoftInt8Type() {
|
||||
this instanceof CharType and
|
||||
not isExplicitlyUnsigned() and
|
||||
not isExplicitlySigned()
|
||||
not this.isExplicitlyUnsigned() and
|
||||
not this.isExplicitlySigned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,8 +391,8 @@ class MicrosoftInt8Type extends IntegralType {
|
||||
class MicrosoftInt16Type extends IntegralType {
|
||||
MicrosoftInt16Type() {
|
||||
this instanceof ShortType and
|
||||
not isExplicitlyUnsigned() and
|
||||
not isExplicitlySigned()
|
||||
not this.isExplicitlyUnsigned() and
|
||||
not this.isExplicitlySigned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,8 +407,8 @@ class MicrosoftInt16Type extends IntegralType {
|
||||
class MicrosoftInt32Type extends IntegralType {
|
||||
MicrosoftInt32Type() {
|
||||
this instanceof IntType and
|
||||
not isExplicitlyUnsigned() and
|
||||
not isExplicitlySigned()
|
||||
not this.isExplicitlyUnsigned() and
|
||||
not this.isExplicitlySigned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,8 +423,8 @@ class MicrosoftInt32Type extends IntegralType {
|
||||
class MicrosoftInt64Type extends IntegralType {
|
||||
MicrosoftInt64Type() {
|
||||
this instanceof LongLongType and
|
||||
not isExplicitlyUnsigned() and
|
||||
not isExplicitlySigned()
|
||||
not this.isExplicitlyUnsigned() and
|
||||
not this.isExplicitlySigned()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ DependencyOptions getDependencyOptions() { any() }
|
||||
class DependsSource extends Element {
|
||||
DependsSource() {
|
||||
// not inside a template instantiation
|
||||
not exists(Element other | isFromTemplateInstantiation(other)) or
|
||||
not exists(Element other | this.isFromTemplateInstantiation(other)) or
|
||||
// allow DeclarationEntrys of template specializations
|
||||
this.(DeclarationEntry).getDeclaration().(Function).isConstructedFrom(_) or
|
||||
this.(DeclarationEntry).getDeclaration().(Class).isConstructedFrom(_)
|
||||
|
||||
@@ -8,7 +8,7 @@ import semmle.code.cpp.commons.StringAnalysis
|
||||
import semmle.code.cpp.models.interfaces.FormattingFunction
|
||||
|
||||
class PrintfFormatAttribute extends FormatAttribute {
|
||||
PrintfFormatAttribute() { getArchetype() = ["printf", "__printf__"] }
|
||||
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,13 +20,13 @@ class AttributeFormattingFunction extends FormattingFunction {
|
||||
|
||||
AttributeFormattingFunction() {
|
||||
exists(PrintfFormatAttribute printf_attrib |
|
||||
printf_attrib = getAnAttribute() and
|
||||
printf_attrib = this.getAnAttribute() and
|
||||
exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions
|
||||
)
|
||||
}
|
||||
|
||||
override int getFormatParameterIndex() {
|
||||
forex(PrintfFormatAttribute printf_attrib | printf_attrib = getAnAttribute() |
|
||||
forex(PrintfFormatAttribute printf_attrib | printf_attrib = this.getAnAttribute() |
|
||||
result = printf_attrib.getFormatIndex()
|
||||
)
|
||||
}
|
||||
@@ -132,7 +132,7 @@ deprecated predicate variadicFormatter(Function f, int formatParamIndex) {
|
||||
class UserDefinedFormattingFunction extends FormattingFunction {
|
||||
override string getAPrimaryQlClass() { result = "UserDefinedFormattingFunction" }
|
||||
|
||||
UserDefinedFormattingFunction() { isVarargs() and callsVariadicFormatter(this, _, _, _) }
|
||||
UserDefinedFormattingFunction() { this.isVarargs() and callsVariadicFormatter(this, _, _, _) }
|
||||
|
||||
override int getFormatParameterIndex() { callsVariadicFormatter(this, _, result, _) }
|
||||
|
||||
@@ -191,7 +191,7 @@ class FormattingFunctionCall extends Expr {
|
||||
exists(int i |
|
||||
result = this.getArgument(i) and
|
||||
n >= 0 and
|
||||
n = i - getTarget().(FormattingFunction).getFirstFormatArgumentIndex()
|
||||
n = i - this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ class FormattingFunctionCall extends Expr {
|
||||
int getNumFormatArgument() {
|
||||
result = count(this.getFormatArgument(_)) and
|
||||
// format arguments must be known
|
||||
exists(getTarget().(FormattingFunction).getFirstFormatArgumentIndex())
|
||||
exists(this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,7 +290,7 @@ class FormatLiteral extends Literal {
|
||||
* DEPRECATED: Use getDefaultCharType() instead.
|
||||
*/
|
||||
deprecated predicate isWideCharDefault() {
|
||||
getUse().getTarget().(FormattingFunction).isWideCharDefault()
|
||||
this.getUse().getTarget().(FormattingFunction).isWideCharDefault()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +298,7 @@ class FormatLiteral extends Literal {
|
||||
* `char` or `wchar_t`.
|
||||
*/
|
||||
Type getDefaultCharType() {
|
||||
result = getUse().getTarget().(FormattingFunction).getDefaultCharType()
|
||||
result = this.getUse().getTarget().(FormattingFunction).getDefaultCharType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,7 +307,7 @@ class FormatLiteral extends Literal {
|
||||
* which is correct for a particular function.
|
||||
*/
|
||||
Type getNonDefaultCharType() {
|
||||
result = getUse().getTarget().(FormattingFunction).getNonDefaultCharType()
|
||||
result = this.getUse().getTarget().(FormattingFunction).getNonDefaultCharType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,7 +315,9 @@ class FormatLiteral extends Literal {
|
||||
* snapshots there may be multiple results where we can't tell which is correct for a
|
||||
* particular function.
|
||||
*/
|
||||
Type getWideCharType() { result = getUse().getTarget().(FormattingFunction).getWideCharType() }
|
||||
Type getWideCharType() {
|
||||
result = this.getUse().getTarget().(FormattingFunction).getWideCharType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this `FormatLiteral` is in a context that supports
|
||||
@@ -353,7 +355,7 @@ class FormatLiteral extends Literal {
|
||||
}
|
||||
|
||||
private string getFlagRegexp() {
|
||||
if isMicrosoft() then result = "[-+ #0']*" else result = "[-+ #0'I]*"
|
||||
if this.isMicrosoft() then result = "[-+ #0']*" else result = "[-+ #0'I]*"
|
||||
}
|
||||
|
||||
private string getFieldWidthRegexp() { result = "(?:[1-9][0-9]*|\\*|\\*[0-9]+\\$)?" }
|
||||
@@ -361,13 +363,13 @@ class FormatLiteral extends Literal {
|
||||
private string getPrecRegexp() { result = "(?:\\.(?:[0-9]*|\\*|\\*[0-9]+\\$))?" }
|
||||
|
||||
private string getLengthRegexp() {
|
||||
if isMicrosoft()
|
||||
if this.isMicrosoft()
|
||||
then result = "(?:hh?|ll?|L|q|j|z|t|w|I32|I64|I)?"
|
||||
else result = "(?:hh?|ll?|L|q|j|z|Z|t)?"
|
||||
}
|
||||
|
||||
private string getConvCharRegexp() {
|
||||
if isMicrosoft()
|
||||
if this.isMicrosoft()
|
||||
then result = "[aAcCdeEfFgGimnopsSuxXZ@]"
|
||||
else result = "[aAcCdeEfFgGimnopsSuxX@]"
|
||||
}
|
||||
@@ -747,16 +749,16 @@ class FormatLiteral extends Literal {
|
||||
* Gets the argument type required by the nth conversion specifier.
|
||||
*/
|
||||
Type getConversionType(int n) {
|
||||
result = getConversionType1(n) or
|
||||
result = getConversionType1b(n) or
|
||||
result = getConversionType2(n) or
|
||||
result = getConversionType3(n) or
|
||||
result = getConversionType4(n) or
|
||||
result = getConversionType6(n) or
|
||||
result = getConversionType7(n) or
|
||||
result = getConversionType8(n) or
|
||||
result = getConversionType9(n) or
|
||||
result = getConversionType10(n)
|
||||
result = this.getConversionType1(n) or
|
||||
result = this.getConversionType1b(n) or
|
||||
result = this.getConversionType2(n) or
|
||||
result = this.getConversionType3(n) or
|
||||
result = this.getConversionType4(n) or
|
||||
result = this.getConversionType6(n) or
|
||||
result = this.getConversionType7(n) or
|
||||
result = this.getConversionType8(n) or
|
||||
result = this.getConversionType9(n) or
|
||||
result = this.getConversionType10(n)
|
||||
}
|
||||
|
||||
private Type getConversionType1(int n) {
|
||||
@@ -786,15 +788,15 @@ class FormatLiteral extends Literal {
|
||||
or
|
||||
conv = ["c", "C"] and
|
||||
len = ["l", "w"] and
|
||||
result = getWideCharType()
|
||||
result = this.getWideCharType()
|
||||
or
|
||||
conv = "c" and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
result = getDefaultCharType()
|
||||
result = this.getDefaultCharType()
|
||||
or
|
||||
conv = "C" and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
result = getNonDefaultCharType()
|
||||
result = this.getNonDefaultCharType()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -831,15 +833,15 @@ class FormatLiteral extends Literal {
|
||||
or
|
||||
conv = ["s", "S"] and
|
||||
len = ["l", "w"] and
|
||||
result.(PointerType).getBaseType() = getWideCharType()
|
||||
result.(PointerType).getBaseType() = this.getWideCharType()
|
||||
or
|
||||
conv = "s" and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
result.(PointerType).getBaseType() = getDefaultCharType()
|
||||
result.(PointerType).getBaseType() = this.getDefaultCharType()
|
||||
or
|
||||
conv = "S" and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
result.(PointerType).getBaseType() = getNonDefaultCharType()
|
||||
result.(PointerType).getBaseType() = this.getNonDefaultCharType()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -894,19 +896,19 @@ class FormatLiteral extends Literal {
|
||||
exists(string len, string conv |
|
||||
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
|
||||
this.getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
|
||||
(
|
||||
conv = "c" and
|
||||
result = getNonDefaultCharType()
|
||||
result = this.getNonDefaultCharType()
|
||||
or
|
||||
conv = "C" and
|
||||
result = getDefaultCharType()
|
||||
result = this.getDefaultCharType()
|
||||
or
|
||||
conv = "s" and
|
||||
result.(PointerType).getBaseType() = getNonDefaultCharType()
|
||||
result.(PointerType).getBaseType() = this.getNonDefaultCharType()
|
||||
or
|
||||
conv = "S" and
|
||||
result.(PointerType).getBaseType() = getDefaultCharType()
|
||||
result.(PointerType).getBaseType() = this.getDefaultCharType()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -939,9 +941,13 @@ class FormatLiteral extends Literal {
|
||||
* not account for positional arguments (`$`).
|
||||
*/
|
||||
int getFormatArgumentIndexFor(int n, int mode) {
|
||||
hasFormatArgumentIndexFor(n, mode) and
|
||||
this.hasFormatArgumentIndexFor(n, mode) and
|
||||
(3 * n) + mode =
|
||||
rank[result + 1](int n2, int mode2 | hasFormatArgumentIndexFor(n2, mode2) | (3 * n2) + mode2)
|
||||
rank[result + 1](int n2, int mode2 |
|
||||
this.hasFormatArgumentIndexFor(n2, mode2)
|
||||
|
|
||||
(3 * n2) + mode2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -951,7 +957,7 @@ class FormatLiteral extends Literal {
|
||||
int getNumArgNeeded(int n) {
|
||||
exists(this.getConvSpecOffset(n)) and
|
||||
exists(this.getConversionChar(n)) and
|
||||
result = count(int mode | hasFormatArgumentIndexFor(n, mode))
|
||||
result = count(int mode | this.hasFormatArgumentIndexFor(n, mode))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -963,7 +969,7 @@ class FormatLiteral extends Literal {
|
||||
// At least one conversion specifier has a parameter field, in which case,
|
||||
// they all should have.
|
||||
result = max(string s | this.getParameterField(_) = s + "$" | s.toInt())
|
||||
else result = count(int n, int mode | hasFormatArgumentIndexFor(n, mode))
|
||||
else result = count(int n, int mode | this.hasFormatArgumentIndexFor(n, mode))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1053,10 +1059,10 @@ class FormatLiteral extends Literal {
|
||||
exists(int sizeBits |
|
||||
sizeBits =
|
||||
min(int bits |
|
||||
bits = getIntegralDisplayType(n).getSize() * 8
|
||||
bits = this.getIntegralDisplayType(n).getSize() * 8
|
||||
or
|
||||
exists(IntegralType t |
|
||||
t = getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
|
|
||||
t.isSigned() and bits = t.getSize() * 8
|
||||
)
|
||||
@@ -1071,10 +1077,10 @@ class FormatLiteral extends Literal {
|
||||
exists(int sizeBits |
|
||||
sizeBits =
|
||||
min(int bits |
|
||||
bits = getIntegralDisplayType(n).getSize() * 8
|
||||
bits = this.getIntegralDisplayType(n).getSize() * 8
|
||||
or
|
||||
exists(IntegralType t |
|
||||
t = getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
|
|
||||
t.isUnsigned() and bits = t.getSize() * 8
|
||||
)
|
||||
@@ -1089,26 +1095,26 @@ class FormatLiteral extends Literal {
|
||||
exists(int sizeBytes, int baseLen |
|
||||
sizeBytes =
|
||||
min(int bytes |
|
||||
bytes = getIntegralDisplayType(n).getSize()
|
||||
bytes = this.getIntegralDisplayType(n).getSize()
|
||||
or
|
||||
exists(IntegralType t |
|
||||
t = getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
|
|
||||
t.isUnsigned() and bytes = t.getSize()
|
||||
)
|
||||
) and
|
||||
baseLen = sizeBytes * 2 and
|
||||
(
|
||||
if hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
)
|
||||
)
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "p" and
|
||||
exists(PointerType ptrType, int baseLen |
|
||||
ptrType = getFullyConverted().getType() and
|
||||
ptrType = this.getFullyConverted().getType() and
|
||||
baseLen = max(ptrType.getSize() * 2) and // e.g. "0x1234567812345678"; exact format is platform dependent
|
||||
(
|
||||
if hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
)
|
||||
)
|
||||
or
|
||||
@@ -1117,17 +1123,17 @@ class FormatLiteral extends Literal {
|
||||
exists(int sizeBits, int baseLen |
|
||||
sizeBits =
|
||||
min(int bits |
|
||||
bits = getIntegralDisplayType(n).getSize() * 8
|
||||
bits = this.getIntegralDisplayType(n).getSize() * 8
|
||||
or
|
||||
exists(IntegralType t |
|
||||
t = getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||
|
|
||||
t.isUnsigned() and bits = t.getSize() * 8
|
||||
)
|
||||
) and
|
||||
baseLen = (sizeBits / 3.0).ceil() and
|
||||
(
|
||||
if hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
|
||||
if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
|
||||
)
|
||||
)
|
||||
or
|
||||
@@ -1150,8 +1156,8 @@ class FormatLiteral extends Literal {
|
||||
*/
|
||||
int getMaxConvertedLengthLimited(int n) {
|
||||
if this.getConversionChar(n).toLowerCase() = "f"
|
||||
then result = getMaxConvertedLength(n).minimum(8)
|
||||
else result = getMaxConvertedLength(n)
|
||||
then result = this.getMaxConvertedLength(n).minimum(8)
|
||||
else result = this.getMaxConvertedLength(n)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ abstract class ScanfFunction extends Function {
|
||||
* Holds if the default meaning of `%s` is a `wchar_t*` string
|
||||
* (rather than a `char*`).
|
||||
*/
|
||||
predicate isWideCharDefault() { exists(getName().indexOf("wscanf")) }
|
||||
predicate isWideCharDefault() { exists(this.getName().indexOf("wscanf")) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,10 +34,10 @@ class Scanf extends ScanfFunction {
|
||||
Scanf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
|
||||
hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
|
||||
hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
|
||||
hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
|
||||
this.hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
|
||||
this.hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
|
||||
this.hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
|
||||
this.hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -53,10 +53,10 @@ class Fscanf extends ScanfFunction {
|
||||
Fscanf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
|
||||
hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
|
||||
hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
|
||||
hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
|
||||
this.hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
|
||||
this.hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
|
||||
this.hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
|
||||
this.hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -72,10 +72,10 @@ class Sscanf extends ScanfFunction {
|
||||
Sscanf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
|
||||
hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
|
||||
hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
|
||||
hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
|
||||
this.hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
|
||||
this.hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
|
||||
this.hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
|
||||
this.hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -91,10 +91,10 @@ class Snscanf extends ScanfFunction {
|
||||
Snscanf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
|
||||
hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
|
||||
hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
|
||||
hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
|
||||
this.hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
|
||||
this.hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
|
||||
this.hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
|
||||
this.hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
|
||||
// note that the max_amount is not a limit on the output length, it's an input length
|
||||
// limit used with non null-terminated strings.
|
||||
)
|
||||
@@ -120,18 +120,18 @@ class ScanfFunctionCall extends FunctionCall {
|
||||
/**
|
||||
* Gets the `scanf`-like function that is called.
|
||||
*/
|
||||
ScanfFunction getScanfFunction() { result = getTarget() }
|
||||
ScanfFunction getScanfFunction() { result = this.getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the position at which the input string or stream parameter occurs,
|
||||
* if this function call does not read from standard input.
|
||||
*/
|
||||
int getInputParameterIndex() { result = getScanfFunction().getInputParameterIndex() }
|
||||
int getInputParameterIndex() { result = this.getScanfFunction().getInputParameterIndex() }
|
||||
|
||||
/**
|
||||
* Gets the position at which the format parameter occurs.
|
||||
*/
|
||||
int getFormatParameterIndex() { result = getScanfFunction().getFormatParameterIndex() }
|
||||
int getFormatParameterIndex() { result = this.getScanfFunction().getFormatParameterIndex() }
|
||||
|
||||
/**
|
||||
* Gets the format expression used in this call.
|
||||
@@ -142,7 +142,7 @@ class ScanfFunctionCall extends FunctionCall {
|
||||
* Holds if the default meaning of `%s` is a `wchar_t*` string
|
||||
* (rather than a `char*`).
|
||||
*/
|
||||
predicate isWideCharDefault() { getScanfFunction().isWideCharDefault() }
|
||||
predicate isWideCharDefault() { this.getScanfFunction().isWideCharDefault() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +158,7 @@ class ScanfFormatLiteral extends Expr {
|
||||
ScanfFunctionCall getUse() { result.getFormat() = this }
|
||||
|
||||
/** Holds if the default meaning of `%s` is a `wchar_t*` (rather than a `char*`). */
|
||||
predicate isWideCharDefault() { getUse().getTarget().(ScanfFunction).isWideCharDefault() }
|
||||
predicate isWideCharDefault() { this.getUse().getTarget().(ScanfFunction).isWideCharDefault() }
|
||||
|
||||
/**
|
||||
* Gets the format string itself, transformed as follows:
|
||||
|
||||
@@ -40,8 +40,8 @@ abstract class MutexType extends Type {
|
||||
* Gets a call that locks or tries to lock any mutex of this type.
|
||||
*/
|
||||
FunctionCall getLockAccess() {
|
||||
result = getMustlockAccess() or
|
||||
result = getTrylockAccess()
|
||||
result = this.getMustlockAccess() or
|
||||
result = this.getTrylockAccess()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,22 +63,22 @@ abstract class MutexType extends Type {
|
||||
/**
|
||||
* DEPRECATED: use mustlockAccess(fc, arg) instead.
|
||||
*/
|
||||
deprecated Function getMustlockFunction() { result = getMustlockAccess().getTarget() }
|
||||
deprecated Function getMustlockFunction() { result = this.getMustlockAccess().getTarget() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use trylockAccess(fc, arg) instead.
|
||||
*/
|
||||
deprecated Function getTrylockFunction() { result = getTrylockAccess().getTarget() }
|
||||
deprecated Function getTrylockFunction() { result = this.getTrylockAccess().getTarget() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use lockAccess(fc, arg) instead.
|
||||
*/
|
||||
deprecated Function getLockFunction() { result = getLockAccess().getTarget() }
|
||||
deprecated Function getLockFunction() { result = this.getLockAccess().getTarget() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use unlockAccess(fc, arg) instead.
|
||||
*/
|
||||
deprecated Function getUnlockFunction() { result = getUnlockAccess().getTarget() }
|
||||
deprecated Function getUnlockFunction() { result = this.getUnlockAccess().getTarget() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,17 +155,17 @@ class DefaultMutexType extends MutexType {
|
||||
|
||||
override predicate mustlockAccess(FunctionCall fc, Expr arg) {
|
||||
fc.getTarget() = mustlockCandidate() and
|
||||
lockArgType(fc, arg)
|
||||
this.lockArgType(fc, arg)
|
||||
}
|
||||
|
||||
override predicate trylockAccess(FunctionCall fc, Expr arg) {
|
||||
fc.getTarget() = trylockCandidate() and
|
||||
lockArgType(fc, arg)
|
||||
this.lockArgType(fc, arg)
|
||||
}
|
||||
|
||||
override predicate unlockAccess(FunctionCall fc, Expr arg) {
|
||||
fc.getTarget() = unlockCandidate() and
|
||||
lockArgType(fc, arg)
|
||||
this.lockArgType(fc, arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ class BasicBlock extends ControlFlowNodeBase {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)
|
||||
this.hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -276,7 +276,7 @@ class EntryBasicBlock extends BasicBlock {
|
||||
*/
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() {
|
||||
getEnd() instanceof Function or
|
||||
aborting(getEnd())
|
||||
this.getEnd() instanceof Function or
|
||||
aborting(this.getEnd())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
|
||||
*/
|
||||
ControlFlowNode getATrueSuccessor() {
|
||||
qlCFGTrueSuccessor(this, result) and
|
||||
result = getASuccessor()
|
||||
result = this.getASuccessor()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
|
||||
*/
|
||||
ControlFlowNode getAFalseSuccessor() {
|
||||
qlCFGFalseSuccessor(this, result) and
|
||||
result = getASuccessor()
|
||||
result = this.getASuccessor()
|
||||
}
|
||||
|
||||
/** Gets the `BasicBlock` containing this control-flow node. */
|
||||
|
||||
@@ -121,7 +121,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||
|
||||
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
|
||||
exists(boolean testIsTrue |
|
||||
comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
|
||||
this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||
|
||||
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
|
||||
exists(boolean testIsTrue |
|
||||
comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
|
||||
this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -147,27 +147,29 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||
private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr {
|
||||
GuardConditionFromShortCircuitNot() {
|
||||
not exists(Instruction inst | this.getFullyConverted() = inst.getAST()) and
|
||||
exists(IRGuardCondition ir | getOperand() = ir.getAST())
|
||||
exists(IRGuardCondition ir | this.getOperand() = ir.getAST())
|
||||
}
|
||||
|
||||
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
|
||||
getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot())
|
||||
this.getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
|
||||
getOperand().(GuardCondition).comparesLt(left, right, k, isLessThan, testIsTrue.booleanNot())
|
||||
this.getOperand()
|
||||
.(GuardCondition)
|
||||
.comparesLt(left, right, k, isLessThan, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
|
||||
getOperand().(GuardCondition).ensuresLt(left, right, k, block, isLessThan.booleanNot())
|
||||
this.getOperand().(GuardCondition).ensuresLt(left, right, k, block, isLessThan.booleanNot())
|
||||
}
|
||||
|
||||
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
|
||||
getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot())
|
||||
this.getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
|
||||
getOperand().(GuardCondition).ensuresEq(left, right, k, block, areEqual.booleanNot())
|
||||
this.getOperand().(GuardCondition).ensuresEq(left, right, k, block, areEqual.booleanNot())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,9 +305,9 @@ class IRGuardCondition extends Instruction {
|
||||
cached
|
||||
predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
|
||||
pred.getASuccessor() = succ and
|
||||
controls(pred, testIsTrue)
|
||||
this.controls(pred, testIsTrue)
|
||||
or
|
||||
succ = getBranchSuccessor(testIsTrue) and
|
||||
succ = this.getBranchSuccessor(testIsTrue) and
|
||||
branch.getCondition() = this and
|
||||
branch.getBlock() = pred
|
||||
}
|
||||
|
||||
@@ -73,19 +73,19 @@ abstract deprecated class LocalScopeVariableReachability extends string {
|
||||
*/
|
||||
|
||||
exists(BasicBlock bb, int i |
|
||||
isSource(source, v) and
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
|
||||
bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
|
||||
this.bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -97,11 +97,11 @@ abstract deprecated class LocalScopeVariableReachability extends string {
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
bbEntryReachesLocally(succ, v, node) and
|
||||
this.bbEntryReachesLocally(succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not isBarrier(succ.getNode(_), v) and
|
||||
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
not this.isBarrier(succ.getNode(_), v) and
|
||||
this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
isSink(node, v)
|
||||
this.isSink(node, v)
|
||||
|
|
||||
not exists(this.firstBarrierIndexIn(bb, v))
|
||||
or
|
||||
@@ -119,7 +119,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
|
||||
}
|
||||
|
||||
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
|
||||
result = min(int m | isBarrier(bb.getNode(m), v))
|
||||
result = min(int m | this.isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
|
||||
* accounts for loops where the condition is provably true upon entry.
|
||||
*/
|
||||
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
reachesTo(source, v, sink, _)
|
||||
this.reachesTo(source, v, sink, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,21 +281,21 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
|
||||
) {
|
||||
exists(ControlFlowNode def |
|
||||
actualSourceReaches(source, v, def, v0) and
|
||||
this.actualSourceReaches(source, v, def, v0) and
|
||||
LocalScopeVariableReachability.super.reaches(def, v0, sink) and
|
||||
isSinkActual(sink, v0)
|
||||
this.isSinkActual(sink, v0)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate actualSourceReaches(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
|
||||
) {
|
||||
isSourceActual(source, v) and def = source and v0 = v
|
||||
this.isSourceActual(source, v) and def = source and v0 = v
|
||||
or
|
||||
exists(ControlFlowNode source1, SemanticStackVariable v1 |
|
||||
actualSourceReaches(source, v, source1, v1)
|
||||
this.actualSourceReaches(source, v, source1, v1)
|
||||
|
|
||||
reassignment(source1, v1, def, v0)
|
||||
this.reassignment(source1, v1, def, v0)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -307,14 +307,14 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
|
||||
}
|
||||
|
||||
final override predicate isSource(ControlFlowNode node, LocalScopeVariable v) {
|
||||
isSourceActual(node, v)
|
||||
this.isSourceActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) source
|
||||
reassignment(_, _, node, v)
|
||||
this.reassignment(_, _, node, v)
|
||||
}
|
||||
|
||||
final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) {
|
||||
isSinkActual(node, v)
|
||||
this.isSinkActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) sink
|
||||
exprDefinition(_, node, v.getAnAccess())
|
||||
@@ -347,21 +347,21 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
|
||||
/** See `LocalScopeVariableReachability.reaches`. */
|
||||
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
exists(BasicBlock bb, int i |
|
||||
isSource(source, v) and
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
|
||||
k in [i .. j - 1]
|
||||
)
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
|
||||
bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
|
||||
this.bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -372,22 +372,22 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
not this.isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
|
|
||||
bbEntryReachesLocally(source, succ, v, node) and
|
||||
this.bbEntryReachesLocally(source, succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbEntryReachesLocally(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
|
||||
) {
|
||||
isSource(source, v) and
|
||||
exists(int n | node = bb.getNode(n) and isSink(node, v) |
|
||||
not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
|
||||
this.isSource(source, v) and
|
||||
exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
|
||||
not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class SsaDefinition extends ControlFlowNodeBase {
|
||||
ControlFlowNode getDefinition() { result = this }
|
||||
|
||||
/** Gets the `BasicBlock` containing this definition. */
|
||||
BasicBlock getBasicBlock() { result.contains(getDefinition()) }
|
||||
BasicBlock getBasicBlock() { result.contains(this.getDefinition()) }
|
||||
|
||||
/** Holds if this definition is a phi node for variable `v`. */
|
||||
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) }
|
||||
|
||||
@@ -72,19 +72,19 @@ abstract class StackVariableReachability extends string {
|
||||
*/
|
||||
|
||||
exists(BasicBlock bb, int i |
|
||||
isSource(source, v) and
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
|
||||
bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
|
||||
this.bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -96,11 +96,11 @@ abstract class StackVariableReachability extends string {
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
bbEntryReachesLocally(succ, v, node) and
|
||||
this.bbEntryReachesLocally(succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not isBarrier(succ.getNode(_), v) and
|
||||
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
not this.isBarrier(succ.getNode(_), v) and
|
||||
this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ abstract class StackVariableReachability extends string {
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
isSink(node, v)
|
||||
this.isSink(node, v)
|
||||
|
|
||||
not exists(this.firstBarrierIndexIn(bb, v))
|
||||
or
|
||||
@@ -118,7 +118,7 @@ abstract class StackVariableReachability extends string {
|
||||
}
|
||||
|
||||
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
|
||||
result = min(int m | isBarrier(bb.getNode(m), v))
|
||||
result = min(int m | this.isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
|
||||
* accounts for loops where the condition is provably true upon entry.
|
||||
*/
|
||||
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
reachesTo(source, v, sink, _)
|
||||
this.reachesTo(source, v, sink, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,21 +278,21 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
|
||||
) {
|
||||
exists(ControlFlowNode def |
|
||||
actualSourceReaches(source, v, def, v0) and
|
||||
this.actualSourceReaches(source, v, def, v0) and
|
||||
StackVariableReachability.super.reaches(def, v0, sink) and
|
||||
isSinkActual(sink, v0)
|
||||
this.isSinkActual(sink, v0)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate actualSourceReaches(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
|
||||
) {
|
||||
isSourceActual(source, v) and def = source and v0 = v
|
||||
this.isSourceActual(source, v) and def = source and v0 = v
|
||||
or
|
||||
exists(ControlFlowNode source1, SemanticStackVariable v1 |
|
||||
actualSourceReaches(source, v, source1, v1)
|
||||
this.actualSourceReaches(source, v, source1, v1)
|
||||
|
|
||||
reassignment(source1, v1, def, v0)
|
||||
this.reassignment(source1, v1, def, v0)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -304,14 +304,14 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
|
||||
}
|
||||
|
||||
final override predicate isSource(ControlFlowNode node, StackVariable v) {
|
||||
isSourceActual(node, v)
|
||||
this.isSourceActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) source
|
||||
reassignment(_, _, node, v)
|
||||
this.reassignment(_, _, node, v)
|
||||
}
|
||||
|
||||
final override predicate isSink(ControlFlowNode node, StackVariable v) {
|
||||
isSinkActual(node, v)
|
||||
this.isSinkActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) sink
|
||||
exprDefinition(_, node, v.getAnAccess())
|
||||
@@ -342,21 +342,21 @@ abstract class StackVariableReachabilityExt extends string {
|
||||
/** See `StackVariableReachability.reaches`. */
|
||||
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
exists(BasicBlock bb, int i |
|
||||
isSource(source, v) and
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
|
||||
k in [i .. j - 1]
|
||||
)
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
|
||||
bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
|
||||
this.bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -367,22 +367,22 @@ abstract class StackVariableReachabilityExt extends string {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
not this.isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
|
|
||||
bbEntryReachesLocally(source, succ, v, node) and
|
||||
this.bbEntryReachesLocally(source, succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbEntryReachesLocally(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
|
||||
) {
|
||||
isSource(source, v) and
|
||||
exists(int n | node = bb.getNode(n) and isSink(node, v) |
|
||||
not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
|
||||
this.isSource(source, v) and
|
||||
exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
|
||||
not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
|
||||
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
|
||||
* position.
|
||||
*/
|
||||
deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 }
|
||||
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
|
||||
|
||||
pragma[noinline]
|
||||
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
|
||||
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
|
||||
exists(BasicBlock bb |
|
||||
exists(int outerIndex |
|
||||
result = bb.getNode(outerIndex) and
|
||||
index = outerToInnerIndex(bb, outerIndex)
|
||||
index = this.outerToInnerIndex(bb, outerIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ library class ExprEvaluator extends int {
|
||||
abstract predicate interesting(Expr e);
|
||||
|
||||
/** Gets the value of (interesting) expression `e`, if any. */
|
||||
int getValue(Expr e) { result = getValueInternal(e, e) }
|
||||
int getValue(Expr e) { result = this.getValueInternal(e, e) }
|
||||
|
||||
/**
|
||||
* When evaluating a syntactic subexpression of `e`, we may
|
||||
@@ -425,9 +425,9 @@ library class ExprEvaluator extends int {
|
||||
* calculates the values bottom-up.
|
||||
*/
|
||||
predicate interestingInternal(Expr e, Expr req, boolean sub) {
|
||||
interesting(e) and req = e and sub = true
|
||||
this.interesting(e) and req = e and sub = true
|
||||
or
|
||||
exists(Expr mid | interestingInternal(e, mid, sub) |
|
||||
exists(Expr mid | this.interestingInternal(e, mid, sub) |
|
||||
req = mid.(NotExpr).getOperand() or
|
||||
req = mid.(BinaryLogicalOperation).getAnOperand() or
|
||||
req = mid.(RelationalOperation).getAnOperand() or
|
||||
@@ -442,36 +442,36 @@ library class ExprEvaluator extends int {
|
||||
)
|
||||
or
|
||||
exists(VariableAccess va, Variable v, boolean sub1 |
|
||||
interestingVariableAccess(e, va, v, sub1) and
|
||||
this.interestingVariableAccess(e, va, v, sub1) and
|
||||
req = v.getAnAssignedValue() and
|
||||
(sub1 = true implies not ignoreVariableAssignment(e, v, req)) and
|
||||
(sub1 = true implies not this.ignoreVariableAssignment(e, v, req)) and
|
||||
sub = false
|
||||
)
|
||||
or
|
||||
exists(Function f |
|
||||
interestingFunction(e, f) and
|
||||
this.interestingFunction(e, f) and
|
||||
returnStmt(f, req) and
|
||||
sub = false
|
||||
)
|
||||
}
|
||||
|
||||
private predicate interestingVariableAccess(Expr e, VariableAccess va, Variable v, boolean sub) {
|
||||
interestingInternal(e, va, sub) and
|
||||
this.interestingInternal(e, va, sub) and
|
||||
v = getVariableTarget(va) and
|
||||
(
|
||||
v.hasInitializer()
|
||||
or
|
||||
sub = true and allowVariableWithoutInitializer(e, v)
|
||||
sub = true and this.allowVariableWithoutInitializer(e, v)
|
||||
) and
|
||||
tractableVariable(v) and
|
||||
forall(StmtParent def | nonAnalyzableVariableDefinition(v, def) |
|
||||
sub = true and
|
||||
ignoreNonAnalyzableVariableDefinition(e, v, def)
|
||||
this.ignoreNonAnalyzableVariableDefinition(e, v, def)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate interestingFunction(Expr e, Function f) {
|
||||
exists(FunctionCall fc | interestingInternal(e, fc, _) |
|
||||
exists(FunctionCall fc | this.interestingInternal(e, fc, _) |
|
||||
f = fc.getTarget() and
|
||||
not obviouslyNonConstant(f) and
|
||||
not f.getUnspecifiedType() instanceof VoidType
|
||||
@@ -481,10 +481,10 @@ library class ExprEvaluator extends int {
|
||||
/** Gets the value of subexpressions `req` for expression `e`, if any. */
|
||||
private int getValueInternal(Expr e, Expr req) {
|
||||
(
|
||||
interestingInternal(e, req, true) and
|
||||
this.interestingInternal(e, req, true) and
|
||||
(
|
||||
result = req.(CompileTimeConstantInt).getIntValue() or
|
||||
result = getCompoundValue(e, req.(CompileTimeVariableExpr))
|
||||
result = this.getCompoundValue(e, req.(CompileTimeVariableExpr))
|
||||
) and
|
||||
(
|
||||
req.getUnderlyingType().(IntegralType).isSigned() or
|
||||
@@ -495,109 +495,126 @@ library class ExprEvaluator extends int {
|
||||
|
||||
/** Gets the value of compound subexpressions `val` for expression `e`, if any. */
|
||||
private int getCompoundValue(Expr e, CompileTimeVariableExpr val) {
|
||||
interestingInternal(e, val, true) and
|
||||
this.interestingInternal(e, val, true) and
|
||||
(
|
||||
exists(NotExpr req | req = val |
|
||||
result = 1 and getValueInternal(e, req.getOperand()) = 0
|
||||
result = 1 and this.getValueInternal(e, req.getOperand()) = 0
|
||||
or
|
||||
result = 0 and getValueInternal(e, req.getOperand()) != 0
|
||||
result = 0 and this.getValueInternal(e, req.getOperand()) != 0
|
||||
)
|
||||
or
|
||||
exists(LogicalAndExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) != 0 and
|
||||
getValueInternal(e, req.getRightOperand()) != 0
|
||||
this.getValueInternal(e, req.getLeftOperand()) != 0 and
|
||||
this.getValueInternal(e, req.getRightOperand()) != 0
|
||||
or
|
||||
result = 0 and getValueInternal(e, req.getAnOperand()) = 0
|
||||
result = 0 and this.getValueInternal(e, req.getAnOperand()) = 0
|
||||
)
|
||||
or
|
||||
exists(LogicalOrExpr req | req = val |
|
||||
result = 1 and getValueInternal(e, req.getAnOperand()) != 0
|
||||
result = 1 and this.getValueInternal(e, req.getAnOperand()) != 0
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) = 0 and
|
||||
getValueInternal(e, req.getRightOperand()) = 0
|
||||
this.getValueInternal(e, req.getLeftOperand()) = 0 and
|
||||
this.getValueInternal(e, req.getRightOperand()) = 0
|
||||
)
|
||||
or
|
||||
exists(LTExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) <
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) >=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(GTExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) >
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) <=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(LEExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) <=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) >
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(GEExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) >=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) <
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(EQExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) =
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) !=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(NEExpr req | req = val |
|
||||
result = 0 and
|
||||
getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) =
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
or
|
||||
result = 1 and
|
||||
getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) !=
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(AddExpr req | req = val |
|
||||
result =
|
||||
getValueInternal(e, req.getLeftOperand()) + getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) +
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(SubExpr req | req = val |
|
||||
result =
|
||||
getValueInternal(e, req.getLeftOperand()) - getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) -
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(MulExpr req | req = val |
|
||||
result =
|
||||
getValueInternal(e, req.getLeftOperand()) * getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) *
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(RemExpr req | req = val |
|
||||
result =
|
||||
getValueInternal(e, req.getLeftOperand()) % getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) %
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(DivExpr req | req = val |
|
||||
result =
|
||||
getValueInternal(e, req.getLeftOperand()) / getValueInternal(e, req.getRightOperand())
|
||||
this.getValueInternal(e, req.getLeftOperand()) /
|
||||
this.getValueInternal(e, req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(AssignExpr req | req = val | result = getValueInternal(e, req.getRValue()))
|
||||
exists(AssignExpr req | req = val | result = this.getValueInternal(e, req.getRValue()))
|
||||
or
|
||||
result = getVariableValue(e, val.(VariableAccess))
|
||||
result = this.getVariableValue(e, val.(VariableAccess))
|
||||
or
|
||||
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) |
|
||||
result = getFunctionValue(call.getTarget())
|
||||
result = this.getFunctionValue(call.getTarget())
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -605,7 +622,7 @@ library class ExprEvaluator extends int {
|
||||
language[monotonicAggregates]
|
||||
private int getVariableValue(Expr e, VariableAccess va) {
|
||||
exists(Variable v |
|
||||
interestingVariableAccess(e, va, v, true) and
|
||||
this.interestingVariableAccess(e, va, v, true) and
|
||||
// All assignments must have the same int value
|
||||
result =
|
||||
unique(Expr value |
|
||||
@@ -619,14 +636,16 @@ library class ExprEvaluator extends int {
|
||||
/** Holds if the function `f` is considered by the analysis and may return `ret`. */
|
||||
pragma[noinline]
|
||||
private predicate interestingReturnValue(Function f, Expr ret) {
|
||||
interestingFunction(_, f) and
|
||||
this.interestingFunction(_, f) and
|
||||
returnStmt(f, ret)
|
||||
}
|
||||
|
||||
private int getFunctionValue(Function f) {
|
||||
// All returns must have the same int value
|
||||
// And it must have at least one return
|
||||
forex(Expr ret | interestingReturnValue(f, ret) | result = getValueInternalNonSubExpr(ret))
|
||||
forex(Expr ret | this.interestingReturnValue(f, ret) |
|
||||
result = this.getValueInternalNonSubExpr(ret)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,10 +660,10 @@ library class ExprEvaluator extends int {
|
||||
* omitted).
|
||||
*/
|
||||
private int getValueInternalNonSubExpr(Expr req) {
|
||||
interestingInternal(_, req, false) and
|
||||
this.interestingInternal(_, req, false) and
|
||||
(
|
||||
result = req.(CompileTimeConstantInt).getIntValue() or
|
||||
result = getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr))
|
||||
result = this.getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr))
|
||||
) and
|
||||
(
|
||||
req.getUnderlyingType().(IntegralType).isSigned() or
|
||||
@@ -655,131 +674,131 @@ library class ExprEvaluator extends int {
|
||||
private int getCompoundValueNonSubExpr(CompileTimeVariableExpr val) {
|
||||
(
|
||||
exists(NotExpr req | req = val |
|
||||
result = 1 and getValueInternalNonSubExpr(req.getOperand()) = 0
|
||||
result = 1 and this.getValueInternalNonSubExpr(req.getOperand()) = 0
|
||||
or
|
||||
result = 0 and getValueInternalNonSubExpr(req.getOperand()) != 0
|
||||
result = 0 and this.getValueInternalNonSubExpr(req.getOperand()) != 0
|
||||
)
|
||||
or
|
||||
exists(LogicalAndExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and
|
||||
getValueInternalNonSubExpr(req.getRightOperand()) != 0
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand()) != 0
|
||||
or
|
||||
result = 0 and getValueInternalNonSubExpr(req.getAnOperand()) = 0
|
||||
result = 0 and this.getValueInternalNonSubExpr(req.getAnOperand()) = 0
|
||||
)
|
||||
or
|
||||
exists(LogicalOrExpr req | req = val |
|
||||
result = 1 and getValueInternalNonSubExpr(req.getAnOperand()) != 0
|
||||
result = 1 and this.getValueInternalNonSubExpr(req.getAnOperand()) != 0
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and
|
||||
getValueInternalNonSubExpr(req.getRightOperand()) = 0
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand()) = 0
|
||||
)
|
||||
or
|
||||
exists(LTExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) <
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) <
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) >=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(GTExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) >
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) >
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) <=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(LEExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) <=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) >
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) >
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(GEExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) >=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) <
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) <
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(EQExpr req | req = val |
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) =
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) =
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) !=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(NEExpr req | req = val |
|
||||
result = 0 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) =
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) =
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
or
|
||||
result = 1 and
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) !=
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(AddExpr req | req = val |
|
||||
result =
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) +
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) +
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(SubExpr req | req = val |
|
||||
result =
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) -
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) -
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(MulExpr req | req = val |
|
||||
result =
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) *
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) *
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(RemExpr req | req = val |
|
||||
result =
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) %
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) %
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(DivExpr req | req = val |
|
||||
result =
|
||||
getValueInternalNonSubExpr(req.getLeftOperand()) /
|
||||
getValueInternalNonSubExpr(req.getRightOperand())
|
||||
this.getValueInternalNonSubExpr(req.getLeftOperand()) /
|
||||
this.getValueInternalNonSubExpr(req.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(AssignExpr req | req = val | result = getValueInternalNonSubExpr(req.getRValue()))
|
||||
exists(AssignExpr req | req = val | result = this.getValueInternalNonSubExpr(req.getRValue()))
|
||||
or
|
||||
result = getVariableValueNonSubExpr(val.(VariableAccess))
|
||||
result = this.getVariableValueNonSubExpr(val.(VariableAccess))
|
||||
or
|
||||
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) |
|
||||
result = getFunctionValue(call.getTarget())
|
||||
result = this.getFunctionValue(call.getTarget())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private int getVariableValueNonSubExpr(VariableAccess va) {
|
||||
// All assignments must have the same int value
|
||||
result = getMinVariableValueNonSubExpr(va) and
|
||||
result = getMaxVariableValueNonSubExpr(va)
|
||||
result = this.getMinVariableValueNonSubExpr(va) and
|
||||
result = this.getMaxVariableValueNonSubExpr(va)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -790,8 +809,9 @@ library class ExprEvaluator extends int {
|
||||
pragma[noopt]
|
||||
private int getMinVariableValueNonSubExpr(VariableAccess va) {
|
||||
exists(Variable v |
|
||||
interestingVariableAccess(_, va, v, false) and
|
||||
result = min(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value))
|
||||
this.interestingVariableAccess(_, va, v, false) and
|
||||
result =
|
||||
min(Expr value | value = v.getAnAssignedValue() | this.getValueInternalNonSubExpr(value))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -803,8 +823,9 @@ library class ExprEvaluator extends int {
|
||||
pragma[noopt]
|
||||
private int getMaxVariableValueNonSubExpr(VariableAccess va) {
|
||||
exists(Variable v |
|
||||
interestingVariableAccess(_, va, v, false) and
|
||||
result = max(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value))
|
||||
this.interestingVariableAccess(_, va, v, false) and
|
||||
result =
|
||||
max(Expr value | value = v.getAnAssignedValue() | this.getValueInternalNonSubExpr(value))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -967,9 +988,9 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
abstract predicate isLoopBody(Expr e, StmtParent s);
|
||||
|
||||
private predicate isLoopBodyDescendant(Expr e, StmtParent s) {
|
||||
isLoopBody(e, s)
|
||||
this.isLoopBody(e, s)
|
||||
or
|
||||
exists(StmtParent mid | isLoopBodyDescendant(e, mid) |
|
||||
exists(StmtParent mid | this.isLoopBodyDescendant(e, mid) |
|
||||
s = mid.(Stmt).getAChild() or
|
||||
s = mid.(Expr).getAChild()
|
||||
)
|
||||
@@ -977,13 +998,13 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
|
||||
// Same as `interestingInternal(e, sub, true)` but avoids negative recursion
|
||||
private predicate interestingSubExpr(Expr e, Expr sub) {
|
||||
interesting(e) and e = sub
|
||||
this.interesting(e) and e = sub
|
||||
or
|
||||
exists(Expr mid | interestingSubExpr(e, mid) and sub = mid.getAChild())
|
||||
exists(Expr mid | this.interestingSubExpr(e, mid) and sub = mid.getAChild())
|
||||
}
|
||||
|
||||
private predicate maybeInterestingVariable(Expr e, Variable v) {
|
||||
exists(VariableAccess va | interestingSubExpr(e, va) | va.getTarget() = v)
|
||||
exists(VariableAccess va | this.interestingSubExpr(e, va) | va.getTarget() = v)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -995,9 +1016,9 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
* definition of `v`.
|
||||
*/
|
||||
private predicate reachesLoopEntryFromLoopBody(Expr e, Variable v, StmtParent valueOrDef) {
|
||||
maybeInterestingVariable(e, v) and
|
||||
this.maybeInterestingVariable(e, v) and
|
||||
(valueOrDef = v.getAnAssignedValue() or nonAnalyzableVariableDefinition(v, valueOrDef)) and
|
||||
isLoopBodyDescendant(e, valueOrDef) and
|
||||
this.isLoopBodyDescendant(e, valueOrDef) and
|
||||
/*
|
||||
* Use primitive basic blocks in reachability analysis for better performance.
|
||||
* This is similar to the pattern used in e.g. `DefinitionsAndUses` and
|
||||
@@ -1007,16 +1028,16 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
exists(PrimitiveBasicBlock bb1, int pos1 | bb1.getNode(pos1) = valueOrDef |
|
||||
// Reaches in same basic block
|
||||
exists(int pos2 |
|
||||
loopEntryAt(bb1, pos2, e) and
|
||||
this.loopEntryAt(bb1, pos2, e) and
|
||||
pos2 > pos1 and
|
||||
not exists(int k | assignmentAt(bb1, k, v) | k in [pos1 + 1 .. pos2 - 1])
|
||||
not exists(int k | this.assignmentAt(bb1, k, v) | k in [pos1 + 1 .. pos2 - 1])
|
||||
)
|
||||
or
|
||||
// Reaches in a successor block
|
||||
exists(PrimitiveBasicBlock bb2 |
|
||||
bb2 = bb1.getASuccessor() and
|
||||
not exists(int pos3 | assignmentAt(bb1, pos3, v) and pos3 > pos1) and
|
||||
bbReachesLoopEntry(bb2, e, v)
|
||||
not exists(int pos3 | this.assignmentAt(bb1, pos3, v) and pos3 > pos1) and
|
||||
this.bbReachesLoopEntry(bb2, e, v)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -1024,12 +1045,12 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
private predicate loopEntryAt(PrimitiveBasicBlock bb, int pos, Expr e) {
|
||||
exists(Node cfn |
|
||||
bb.getNode(pos) = cfn and
|
||||
isLoopEntry(e, cfn)
|
||||
this.isLoopEntry(e, cfn)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate assignmentAt(PrimitiveBasicBlock bb, int pos, Variable v) {
|
||||
maybeInterestingVariable(_, v) and
|
||||
this.maybeInterestingVariable(_, v) and
|
||||
bb.getNode(pos) = v.getAnAssignedValue()
|
||||
}
|
||||
|
||||
@@ -1038,19 +1059,19 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
* the loop belonging to `e` without crossing an assignment to `v`.
|
||||
*/
|
||||
private predicate bbReachesLoopEntry(PrimitiveBasicBlock bb, Expr e, Variable v) {
|
||||
bbReachesLoopEntryLocally(bb, e, v)
|
||||
this.bbReachesLoopEntryLocally(bb, e, v)
|
||||
or
|
||||
exists(PrimitiveBasicBlock succ | succ = bb.getASuccessor() |
|
||||
bbReachesLoopEntry(succ, e, v) and
|
||||
not assignmentAt(bb, _, v)
|
||||
this.bbReachesLoopEntry(succ, e, v) and
|
||||
not this.assignmentAt(bb, _, v)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbReachesLoopEntryLocally(PrimitiveBasicBlock bb, Expr e, Variable v) {
|
||||
exists(int pos |
|
||||
loopEntryAt(bb, pos, e) and
|
||||
maybeInterestingVariable(e, v) and
|
||||
not exists(int pos1 | assignmentAt(bb, pos1, v) | pos1 < pos)
|
||||
this.loopEntryAt(bb, pos, e) and
|
||||
this.maybeInterestingVariable(e, v) and
|
||||
not exists(int pos1 | this.assignmentAt(bb, pos1, v) | pos1 < pos)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1084,10 +1105,10 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
* ```
|
||||
*/
|
||||
override predicate ignoreNonAnalyzableVariableDefinition(Expr e, Variable v, StmtParent def) {
|
||||
maybeInterestingVariable(e, v) and
|
||||
this.maybeInterestingVariable(e, v) and
|
||||
nonAnalyzableVariableDefinition(v, def) and
|
||||
isLoopBodyDescendant(e, def) and
|
||||
not reachesLoopEntryFromLoopBody(e, v, def)
|
||||
this.isLoopBodyDescendant(e, def) and
|
||||
not this.reachesLoopEntryFromLoopBody(e, v, def)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1120,10 +1141,10 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
|
||||
* ```
|
||||
*/
|
||||
override predicate ignoreVariableAssignment(Expr e, Variable v, Expr value) {
|
||||
maybeInterestingVariable(e, v) and
|
||||
this.maybeInterestingVariable(e, v) and
|
||||
value = v.getAnAssignedValue() and
|
||||
isLoopBodyDescendant(e, value) and
|
||||
not reachesLoopEntryFromLoopBody(e, v, value)
|
||||
this.isLoopBodyDescendant(e, value) and
|
||||
not this.reachesLoopEntryFromLoopBody(e, v, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -106,13 +106,13 @@ class Node extends TNode {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an upper bound on the type of this node.
|
||||
*/
|
||||
Type getTypeBound() { result = getType() }
|
||||
Type getTypeBound() { result = this.getType() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,11 +293,11 @@ abstract class PostUpdateNode extends Node {
|
||||
*/
|
||||
abstract Node getPreUpdateNode();
|
||||
|
||||
override Function getFunction() { result = getPreUpdateNode().getFunction() }
|
||||
override Function getFunction() { result = this.getPreUpdateNode().getFunction() }
|
||||
|
||||
override Type getType() { result = getPreUpdateNode().getType() }
|
||||
override Type getType() { result = this.getPreUpdateNode().getType() }
|
||||
|
||||
override Location getLocation() { result = getPreUpdateNode().getLocation() }
|
||||
override Location getLocation() { result = this.getPreUpdateNode().getLocation() }
|
||||
}
|
||||
|
||||
abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
|
||||
@@ -309,7 +309,7 @@ abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDef
|
||||
|
||||
PartialDefinition getPartialDefinition() { result = pd }
|
||||
|
||||
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
|
||||
override string toString() { result = this.getPreUpdateNode().toString() + " [post update]" }
|
||||
}
|
||||
|
||||
private class VariablePartialDefinitionNode extends PartialDefinitionNode {
|
||||
@@ -380,13 +380,13 @@ private class ObjectInitializerNode extends PostUpdateNode, TExprNode {
|
||||
class PreObjectInitializerNode extends Node, TPreObjectInitializerNode {
|
||||
Expr getExpr() { this = TPreObjectInitializerNode(result) }
|
||||
|
||||
override Function getFunction() { result = getExpr().getEnclosingFunction() }
|
||||
override Function getFunction() { result = this.getExpr().getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = getExpr().getType() }
|
||||
override Type getType() { result = this.getExpr().getType() }
|
||||
|
||||
override Location getLocation() { result = getExpr().getLocation() }
|
||||
override Location getLocation() { result = this.getExpr().getLocation() }
|
||||
|
||||
override string toString() { result = getExpr().toString() + " [pre init]" }
|
||||
override string toString() { result = this.getExpr().toString() + " [pre init]" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,7 +401,7 @@ private class PostConstructorInitThis extends PostUpdateNode, TPostConstructorIn
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = getPreUpdateNode().getConstructorFieldInit().toString() + " [post-this]"
|
||||
result = this.getPreUpdateNode().getConstructorFieldInit().toString() + " [post-this]"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,15 +416,17 @@ private class PostConstructorInitThis extends PostUpdateNode, TPostConstructorIn
|
||||
class PreConstructorInitThis extends Node, TPreConstructorInitThis {
|
||||
ConstructorFieldInit getConstructorFieldInit() { this = TPreConstructorInitThis(result) }
|
||||
|
||||
override Constructor getFunction() { result = getConstructorFieldInit().getEnclosingFunction() }
|
||||
|
||||
override PointerType getType() {
|
||||
result.getBaseType() = getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
|
||||
override Constructor getFunction() {
|
||||
result = this.getConstructorFieldInit().getEnclosingFunction()
|
||||
}
|
||||
|
||||
override Location getLocation() { result = getConstructorFieldInit().getLocation() }
|
||||
override PointerType getType() {
|
||||
result.getBaseType() = this.getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
|
||||
}
|
||||
|
||||
override string toString() { result = getConstructorFieldInit().toString() + " [pre-this]" }
|
||||
override Location getLocation() { result = this.getConstructorFieldInit().getLocation() }
|
||||
|
||||
override string toString() { result = this.getConstructorFieldInit().toString() + " [pre-this]" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -354,7 +354,7 @@ module FlowVar_internal {
|
||||
result = def.getAUse(v)
|
||||
or
|
||||
exists(SsaDefinition descendentDef |
|
||||
getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and
|
||||
this.getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and
|
||||
result = descendentDef.getAUse(v)
|
||||
)
|
||||
)
|
||||
@@ -515,7 +515,7 @@ module FlowVar_internal {
|
||||
this.bbInLoopCondition(bbInside) and
|
||||
not this.bbInLoop(bbOutside) and
|
||||
bbOutside = bbInside.getASuccessor() and
|
||||
not reachesWithoutAssignment(bbInside, v)
|
||||
not this.reachesWithoutAssignment(bbInside, v)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,7 +546,7 @@ module FlowVar_internal {
|
||||
private predicate bbInLoop(BasicBlock bb) {
|
||||
bbDominates(this.(Loop).getStmt(), bb)
|
||||
or
|
||||
bbInLoopCondition(bb)
|
||||
this.bbInLoopCondition(bb)
|
||||
}
|
||||
|
||||
/** Holds if `sbb` is inside this loop. */
|
||||
@@ -563,7 +563,7 @@ module FlowVar_internal {
|
||||
bb = this.(Loop).getStmt() and
|
||||
v = this.getARelevantVariable()
|
||||
or
|
||||
reachesWithoutAssignment(bb.getAPredecessor(), v) and
|
||||
this.reachesWithoutAssignment(bb.getAPredecessor(), v) and
|
||||
this.bbInLoop(bb)
|
||||
) and
|
||||
not assignsToVar(bb, v)
|
||||
|
||||
@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
|
||||
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
|
||||
* position.
|
||||
*/
|
||||
deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 }
|
||||
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
|
||||
|
||||
pragma[noinline]
|
||||
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
|
||||
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
|
||||
exists(BasicBlock bb |
|
||||
exists(int outerIndex |
|
||||
result = bb.getNode(outerIndex) and
|
||||
index = outerToInnerIndex(bb, outerIndex)
|
||||
index = this.outerToInnerIndex(bb, outerIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ class PointerFieldAccess extends FieldAccess {
|
||||
|
||||
PointerFieldAccess() {
|
||||
exists(PointerType t |
|
||||
t = getQualifier().getFullyConverted().getUnspecifiedType() and
|
||||
t = this.getQualifier().getFullyConverted().getUnspecifiedType() and
|
||||
t.getBaseType() instanceof Class
|
||||
)
|
||||
}
|
||||
@@ -218,7 +218,9 @@ class PointerFieldAccess extends FieldAccess {
|
||||
class DotFieldAccess extends FieldAccess {
|
||||
override string getAPrimaryQlClass() { result = "DotFieldAccess" }
|
||||
|
||||
DotFieldAccess() { exists(Class c | c = getQualifier().getFullyConverted().getUnspecifiedType()) }
|
||||
DotFieldAccess() {
|
||||
exists(Class c | c = this.getQualifier().getFullyConverted().getUnspecifiedType())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -148,7 +148,7 @@ class PostfixIncrExpr extends IncrementOperation, PostfixCrementOperation, @post
|
||||
|
||||
override int getPrecedence() { result = 17 }
|
||||
|
||||
override string toString() { result = "... " + getOperator() }
|
||||
override string toString() { result = "... " + this.getOperator() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +166,7 @@ class PostfixDecrExpr extends DecrementOperation, PostfixCrementOperation, @post
|
||||
|
||||
override int getPrecedence() { result = 17 }
|
||||
|
||||
override string toString() { result = "... " + getOperator() }
|
||||
override string toString() { result = "... " + this.getOperator() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,12 +35,12 @@ class BuiltInVarArgsStart extends VarArgsExpr, @vastartexpr {
|
||||
/**
|
||||
* Gets the `va_list` argument.
|
||||
*/
|
||||
final Expr getVAList() { result = getChild(0) }
|
||||
final Expr getVAList() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the argument that specifies the last named parameter before the ellipsis.
|
||||
*/
|
||||
final VariableAccess getLastNamedParameter() { result = getChild(1) }
|
||||
final VariableAccess getLastNamedParameter() { result = this.getChild(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ class BuiltInVarArgsEnd extends VarArgsExpr, @vaendexpr {
|
||||
/**
|
||||
* Gets the `va_list` argument.
|
||||
*/
|
||||
final Expr getVAList() { result = getChild(0) }
|
||||
final Expr getVAList() { result = this.getChild(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +78,7 @@ class BuiltInVarArg extends VarArgsExpr, @vaargexpr {
|
||||
/**
|
||||
* Gets the `va_list` argument.
|
||||
*/
|
||||
final Expr getVAList() { result = getChild(0) }
|
||||
final Expr getVAList() { result = this.getChild(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,12 +98,12 @@ class BuiltInVarArgCopy extends VarArgsExpr, @vacopyexpr {
|
||||
/**
|
||||
* Gets the destination `va_list` argument.
|
||||
*/
|
||||
final Expr getDestinationVAList() { result = getChild(0) }
|
||||
final Expr getDestinationVAList() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the the source `va_list` argument.
|
||||
*/
|
||||
final Expr getSourceVAList() { result = getChild(1) }
|
||||
final Expr getSourceVAList() { result = this.getChild(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,10 +71,10 @@ class Call extends Expr, NameQualifiableElement, TCall {
|
||||
* at index 2, respectively.
|
||||
*/
|
||||
Expr getAnArgumentSubExpr(int index) {
|
||||
result = getArgument(index)
|
||||
result = this.getArgument(index)
|
||||
or
|
||||
exists(Expr mid |
|
||||
mid = getAnArgumentSubExpr(index) and
|
||||
mid = this.getAnArgumentSubExpr(index) and
|
||||
not mid instanceof Call and
|
||||
not mid instanceof SizeofOperator and
|
||||
result = mid.getAChild()
|
||||
@@ -167,27 +167,27 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
override string getAPrimaryQlClass() { result = "FunctionCall" }
|
||||
|
||||
/** Gets an explicit template argument for this call. */
|
||||
Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
|
||||
Locatable getAnExplicitTemplateArgument() { result = this.getExplicitTemplateArgument(_) }
|
||||
|
||||
/** Gets an explicit template argument value for this call. */
|
||||
Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) }
|
||||
Locatable getAnExplicitTemplateArgumentKind() { result = this.getExplicitTemplateArgumentKind(_) }
|
||||
|
||||
/** Gets a template argument for this call. */
|
||||
Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() }
|
||||
Locatable getATemplateArgument() { result = this.getTarget().getATemplateArgument() }
|
||||
|
||||
/** Gets a template argument value for this call. */
|
||||
Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() }
|
||||
Locatable getATemplateArgumentKind() { result = this.getTarget().getATemplateArgumentKind() }
|
||||
|
||||
/** Gets the nth explicit template argument for this call. */
|
||||
Locatable getExplicitTemplateArgument(int n) {
|
||||
n < getNumberOfExplicitTemplateArguments() and
|
||||
result = getTemplateArgument(n)
|
||||
n < this.getNumberOfExplicitTemplateArguments() and
|
||||
result = this.getTemplateArgument(n)
|
||||
}
|
||||
|
||||
/** Gets the nth explicit template argument value for this call. */
|
||||
Locatable getExplicitTemplateArgumentKind(int n) {
|
||||
n < getNumberOfExplicitTemplateArguments() and
|
||||
result = getTemplateArgumentKind(n)
|
||||
n < this.getNumberOfExplicitTemplateArguments() and
|
||||
result = this.getTemplateArgumentKind(n)
|
||||
}
|
||||
|
||||
/** Gets the number of explicit template arguments for this call. */
|
||||
@@ -198,19 +198,19 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
}
|
||||
|
||||
/** Gets the number of template arguments for this call. */
|
||||
int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) }
|
||||
int getNumberOfTemplateArguments() { result = count(int i | exists(this.getTemplateArgument(i))) }
|
||||
|
||||
/** Gets the nth template argument for this call (indexed from 0). */
|
||||
Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
|
||||
Locatable getTemplateArgument(int n) { result = this.getTarget().getTemplateArgument(n) }
|
||||
|
||||
/** Gets the nth template argument value for this call (indexed from 0). */
|
||||
Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) }
|
||||
Locatable getTemplateArgumentKind(int n) { result = this.getTarget().getTemplateArgumentKind(n) }
|
||||
|
||||
/** Holds if any template arguments for this call are implicit / deduced. */
|
||||
predicate hasImplicitTemplateArguments() {
|
||||
exists(int i |
|
||||
exists(getTemplateArgument(i)) and
|
||||
not exists(getExplicitTemplateArgument(i))
|
||||
exists(this.getTemplateArgument(i)) and
|
||||
not exists(this.getExplicitTemplateArgument(i))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -233,9 +233,9 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
* visible at the call site.
|
||||
*/
|
||||
Type getExpectedReturnType() {
|
||||
if getTargetType() instanceof RoutineType
|
||||
then result = getTargetType().(RoutineType).getReturnType()
|
||||
else result = getTarget().getType()
|
||||
if this.getTargetType() instanceof RoutineType
|
||||
then result = this.getTargetType().(RoutineType).getReturnType()
|
||||
else result = this.getTarget().getType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,9 +247,9 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
* was visible at the call site.
|
||||
*/
|
||||
Type getExpectedParameterType(int n) {
|
||||
if getTargetType() instanceof RoutineType
|
||||
then result = getTargetType().(RoutineType).getParameterType(n)
|
||||
else result = getTarget().getParameter(n).getType()
|
||||
if this.getTargetType() instanceof RoutineType
|
||||
then result = this.getTargetType().(RoutineType).getParameterType(n)
|
||||
else result = this.getTarget().getParameter(n).getType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,7 +263,7 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
/**
|
||||
* Gets the type of this expression, that is, the return type of the function being called.
|
||||
*/
|
||||
override Type getType() { result = getExpectedReturnType() }
|
||||
override Type getType() { result = this.getExpectedReturnType() }
|
||||
|
||||
/**
|
||||
* Holds if this is a call to a virtual function.
|
||||
@@ -280,7 +280,7 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
|
||||
/** Gets a textual representation of this function call. */
|
||||
override string toString() {
|
||||
if exists(getTarget())
|
||||
if exists(this.getTarget())
|
||||
then result = "call to " + this.getTarget().getName()
|
||||
else result = "call to unknown function"
|
||||
}
|
||||
@@ -288,15 +288,15 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
override predicate mayBeImpure() {
|
||||
this.getChild(_).mayBeImpure() or
|
||||
this.getTarget().mayHaveSideEffects() or
|
||||
isVirtual() or
|
||||
getTarget().getAnAttribute().getName() = "weak"
|
||||
this.isVirtual() or
|
||||
this.getTarget().getAnAttribute().getName() = "weak"
|
||||
}
|
||||
|
||||
override predicate mayBeGloballyImpure() {
|
||||
this.getChild(_).mayBeGloballyImpure() or
|
||||
this.getTarget().mayHaveSideEffects() or
|
||||
isVirtual() or
|
||||
getTarget().getAnAttribute().getName() = "weak"
|
||||
this.isVirtual() or
|
||||
this.getTarget().getAnAttribute().getName() = "weak"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ class OverloadedPointerDereferenceExpr extends FunctionCall {
|
||||
* ```
|
||||
*/
|
||||
class OverloadedArrayExpr extends FunctionCall {
|
||||
OverloadedArrayExpr() { getTarget().hasName("operator[]") }
|
||||
OverloadedArrayExpr() { this.getTarget().hasName("operator[]") }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "OverloadedArrayExpr" }
|
||||
|
||||
@@ -585,7 +585,7 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
override string toString() { result = "constructor init of field " + getTarget().getName() }
|
||||
override string toString() { result = "constructor init of field " + this.getTarget().getName() }
|
||||
|
||||
override predicate mayBeImpure() { this.getExpr().mayBeImpure() }
|
||||
|
||||
|
||||
@@ -188,8 +188,8 @@ private predicate isPointerToMemberOrNullPointer(Type type) {
|
||||
class ArithmeticConversion extends Cast {
|
||||
ArithmeticConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
isArithmeticOrEnum(getUnspecifiedType()) and
|
||||
isArithmeticOrEnum(getExpr().getUnspecifiedType())
|
||||
isArithmeticOrEnum(this.getUnspecifiedType()) and
|
||||
isArithmeticOrEnum(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getSemanticConversionString() { result = "arithmetic conversion" }
|
||||
@@ -204,8 +204,8 @@ class ArithmeticConversion extends Cast {
|
||||
*/
|
||||
class IntegralConversion extends ArithmeticConversion {
|
||||
IntegralConversion() {
|
||||
isIntegralOrEnum(getUnspecifiedType()) and
|
||||
isIntegralOrEnum(getExpr().getUnspecifiedType())
|
||||
isIntegralOrEnum(this.getUnspecifiedType()) and
|
||||
isIntegralOrEnum(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -224,8 +224,8 @@ class IntegralConversion extends ArithmeticConversion {
|
||||
*/
|
||||
class FloatingPointConversion extends ArithmeticConversion {
|
||||
FloatingPointConversion() {
|
||||
getUnspecifiedType() instanceof FloatingPointType and
|
||||
getExpr().getUnspecifiedType() instanceof FloatingPointType
|
||||
this.getUnspecifiedType() instanceof FloatingPointType and
|
||||
this.getExpr().getUnspecifiedType() instanceof FloatingPointType
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -244,8 +244,8 @@ class FloatingPointConversion extends ArithmeticConversion {
|
||||
*/
|
||||
class FloatingPointToIntegralConversion extends ArithmeticConversion {
|
||||
FloatingPointToIntegralConversion() {
|
||||
isIntegralOrEnum(getUnspecifiedType()) and
|
||||
getExpr().getUnspecifiedType() instanceof FloatingPointType
|
||||
isIntegralOrEnum(this.getUnspecifiedType()) and
|
||||
this.getExpr().getUnspecifiedType() instanceof FloatingPointType
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -264,8 +264,8 @@ class FloatingPointToIntegralConversion extends ArithmeticConversion {
|
||||
*/
|
||||
class IntegralToFloatingPointConversion extends ArithmeticConversion {
|
||||
IntegralToFloatingPointConversion() {
|
||||
getUnspecifiedType() instanceof FloatingPointType and
|
||||
isIntegralOrEnum(getExpr().getUnspecifiedType())
|
||||
this.getUnspecifiedType() instanceof FloatingPointType and
|
||||
isIntegralOrEnum(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -290,8 +290,8 @@ class IntegralToFloatingPointConversion extends ArithmeticConversion {
|
||||
class PointerConversion extends Cast {
|
||||
PointerConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
isPointerOrNullPointer(getUnspecifiedType()) and
|
||||
isPointerOrNullPointer(getExpr().getUnspecifiedType())
|
||||
isPointerOrNullPointer(this.getUnspecifiedType()) and
|
||||
isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "PointerConversion" }
|
||||
@@ -315,8 +315,8 @@ class PointerToMemberConversion extends Cast {
|
||||
PointerToMemberConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
exists(Type fromType, Type toType |
|
||||
fromType = getExpr().getUnspecifiedType() and
|
||||
toType = getUnspecifiedType() and
|
||||
fromType = this.getExpr().getUnspecifiedType() and
|
||||
toType = this.getUnspecifiedType() and
|
||||
isPointerToMemberOrNullPointer(fromType) and
|
||||
isPointerToMemberOrNullPointer(toType) and
|
||||
// A conversion from nullptr to nullptr is a `PointerConversion`, not a
|
||||
@@ -345,8 +345,8 @@ class PointerToMemberConversion extends Cast {
|
||||
class PointerToIntegralConversion extends Cast {
|
||||
PointerToIntegralConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
isIntegralOrEnum(getUnspecifiedType()) and
|
||||
isPointerOrNullPointer(getExpr().getUnspecifiedType())
|
||||
isIntegralOrEnum(this.getUnspecifiedType()) and
|
||||
isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -366,8 +366,8 @@ class PointerToIntegralConversion extends Cast {
|
||||
class IntegralToPointerConversion extends Cast {
|
||||
IntegralToPointerConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
isPointerOrNullPointer(getUnspecifiedType()) and
|
||||
isIntegralOrEnum(getExpr().getUnspecifiedType())
|
||||
isPointerOrNullPointer(this.getUnspecifiedType()) and
|
||||
isIntegralOrEnum(this.getExpr().getUnspecifiedType())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
@@ -403,7 +403,7 @@ class BoolConversion extends Cast {
|
||||
class VoidConversion extends Cast {
|
||||
VoidConversion() {
|
||||
conversionkinds(underlyingElement(this), 0) and
|
||||
getUnspecifiedType() instanceof VoidType
|
||||
this.getUnspecifiedType() instanceof VoidType
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "VoidConversion" }
|
||||
@@ -434,8 +434,8 @@ class InheritanceConversion extends Cast {
|
||||
* conversion is to an indirect virtual base class.
|
||||
*/
|
||||
final ClassDerivation getDerivation() {
|
||||
result.getBaseClass() = getBaseClass() and
|
||||
result.getDerivedClass() = getDerivedClass()
|
||||
result.getBaseClass() = this.getBaseClass() and
|
||||
result.getDerivedClass() = this.getDerivedClass()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,12 +490,12 @@ class BaseClassConversion extends InheritanceConversion {
|
||||
|
||||
override Class getBaseClass() { result = getConversionClass(this) }
|
||||
|
||||
override Class getDerivedClass() { result = getConversionClass(getExpr()) }
|
||||
override Class getDerivedClass() { result = getConversionClass(this.getExpr()) }
|
||||
|
||||
/**
|
||||
* Holds if this conversion is to a virtual base class.
|
||||
*/
|
||||
predicate isVirtual() { getDerivation().isVirtual() or not exists(getDerivation()) }
|
||||
predicate isVirtual() { this.getDerivation().isVirtual() or not exists(this.getDerivation()) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -515,7 +515,7 @@ class DerivedClassConversion extends InheritanceConversion {
|
||||
|
||||
override string getSemanticConversionString() { result = "derived class conversion" }
|
||||
|
||||
override Class getBaseClass() { result = getConversionClass(getExpr()) }
|
||||
override Class getBaseClass() { result = getConversionClass(this.getExpr()) }
|
||||
|
||||
override Class getDerivedClass() { result = getConversionClass(this) }
|
||||
}
|
||||
@@ -637,8 +637,8 @@ class DynamicCast extends Cast, @dynamic_cast {
|
||||
*/
|
||||
class UuidofOperator extends Expr, @uuidof {
|
||||
override string toString() {
|
||||
if exists(getTypeOperand())
|
||||
then result = "__uuidof(" + getTypeOperand().getName() + ")"
|
||||
if exists(this.getTypeOperand())
|
||||
then result = "__uuidof(" + this.getTypeOperand().getName() + ")"
|
||||
else result = "__uuidof(0)"
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class Expr extends StmtParent, @expr {
|
||||
Function getEnclosingFunction() { result = exprEnclosingElement(this) }
|
||||
|
||||
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */
|
||||
BlockStmt getEnclosingBlock() { result = getEnclosingStmt().getEnclosingBlock() }
|
||||
BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() }
|
||||
|
||||
override Stmt getEnclosingStmt() {
|
||||
result = this.getParent().(Expr).getEnclosingStmt()
|
||||
@@ -219,13 +219,13 @@ class Expr extends StmtParent, @expr {
|
||||
* Holds if this expression is a _glvalue_. A _glvalue_ is either an _lvalue_ or an
|
||||
* _xvalue_.
|
||||
*/
|
||||
predicate isGLValueCategory() { isLValueCategory() or isXValueCategory() }
|
||||
predicate isGLValueCategory() { this.isLValueCategory() or this.isXValueCategory() }
|
||||
|
||||
/**
|
||||
* Holds if this expression is an _rvalue_. An _rvalue_ is either a _prvalue_ or an
|
||||
* _xvalue_.
|
||||
*/
|
||||
predicate isRValueCategory() { isPRValueCategory() or isXValueCategory() }
|
||||
predicate isRValueCategory() { this.isPRValueCategory() or this.isXValueCategory() }
|
||||
|
||||
/**
|
||||
* Gets a string representation of the value category of the expression.
|
||||
@@ -240,15 +240,15 @@ class Expr extends StmtParent, @expr {
|
||||
* `hasLValueToRvalueConversion()` holds.
|
||||
*/
|
||||
string getValueCategoryString() {
|
||||
isLValueCategory() and
|
||||
this.isLValueCategory() and
|
||||
result = "lvalue"
|
||||
or
|
||||
isXValueCategory() and
|
||||
this.isXValueCategory() and
|
||||
result = "xvalue"
|
||||
or
|
||||
(
|
||||
isPRValueCategory() and
|
||||
if hasLValueToRValueConversion() then result = "prvalue(load)" else result = "prvalue"
|
||||
this.isPRValueCategory() and
|
||||
if this.hasLValueToRValueConversion() then result = "prvalue(load)" else result = "prvalue"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ class Expr extends StmtParent, @expr {
|
||||
* such as an expression inside a sizeof.
|
||||
*/
|
||||
predicate isUnevaluated() {
|
||||
exists(Element e | e = getParentWithConversions+() |
|
||||
exists(Element e | e = this.getParentWithConversions+() |
|
||||
e instanceof SizeofOperator
|
||||
or
|
||||
exists(Expr e2 |
|
||||
@@ -279,7 +279,7 @@ class Expr extends StmtParent, @expr {
|
||||
e instanceof AlignofOperator
|
||||
)
|
||||
or
|
||||
exists(Decltype d | d.getExpr() = getParentWithConversions*())
|
||||
exists(Decltype d | d.getExpr() = this.getParentWithConversions*())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,7 +725,7 @@ class PointerDereferenceExpr extends UnaryOperation, @indirect {
|
||||
*
|
||||
* Gets the expression that is being dereferenced.
|
||||
*/
|
||||
deprecated Expr getExpr() { result = getOperand() }
|
||||
deprecated Expr getExpr() { result = this.getOperand() }
|
||||
|
||||
override string getOperator() { result = "*" }
|
||||
|
||||
@@ -780,15 +780,15 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
|
||||
* Gets the alignment argument passed to the allocation function, if any.
|
||||
*/
|
||||
Expr getAlignmentArgument() {
|
||||
hasAlignedAllocation() and
|
||||
this.hasAlignedAllocation() and
|
||||
(
|
||||
// If we have an allocator call, the alignment is the second argument to
|
||||
// that call.
|
||||
result = getAllocatorCall().getArgument(1)
|
||||
result = this.getAllocatorCall().getArgument(1)
|
||||
or
|
||||
// Otherwise, the alignment winds up as child number 3 of the `new`
|
||||
// itself.
|
||||
result = getChild(3)
|
||||
result = this.getChild(3)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -916,7 +916,7 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
|
||||
* Gets the element type of the array being allocated.
|
||||
*/
|
||||
Type getAllocatedElementType() {
|
||||
result = getType().getUnderlyingType().(PointerType).getBaseType()
|
||||
result = this.getType().getUnderlyingType().(PointerType).getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -946,7 +946,12 @@ class DeleteExpr extends Expr, @delete_expr {
|
||||
*/
|
||||
Type getDeletedObjectType() {
|
||||
result =
|
||||
getExpr().getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType()
|
||||
this.getExpr()
|
||||
.getFullyConverted()
|
||||
.getType()
|
||||
.stripTopLevelSpecifiers()
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -957,7 +962,7 @@ class DeleteExpr extends Expr, @delete_expr {
|
||||
/**
|
||||
* Gets the destructor to be called to destroy the object, if any.
|
||||
*/
|
||||
Destructor getDestructor() { result = getDestructorCall().getTarget() }
|
||||
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the `operator delete` that deallocates storage. Does not hold
|
||||
@@ -1020,7 +1025,12 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
*/
|
||||
Type getDeletedElementType() {
|
||||
result =
|
||||
getExpr().getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType()
|
||||
this.getExpr()
|
||||
.getFullyConverted()
|
||||
.getType()
|
||||
.stripTopLevelSpecifiers()
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1034,7 +1044,7 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
/**
|
||||
* Gets the destructor to be called to destroy each element in the array, if any.
|
||||
*/
|
||||
Destructor getDestructor() { result = getDestructorCall().getTarget() }
|
||||
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the `operator delete[]` that deallocates storage.
|
||||
@@ -1101,7 +1111,7 @@ class StmtExpr extends Expr, @expr_stmt {
|
||||
* x = ({ dosomething(); a+b; });
|
||||
* ```
|
||||
*/
|
||||
Expr getResultExpr() { result = getStmtResultExpr(getStmt()) }
|
||||
Expr getResultExpr() { result = getStmtResultExpr(this.getStmt()) }
|
||||
}
|
||||
|
||||
/** Get the result expression of a statement. (Helper function for StmtExpr.) */
|
||||
@@ -1230,20 +1240,20 @@ class FoldExpr extends Expr, @foldexpr {
|
||||
predicate isRightFold() { fold(underlyingElement(this), _, false) }
|
||||
|
||||
/** Holds if this is a unary fold expression. */
|
||||
predicate isUnaryFold() { getNumChild() = 1 }
|
||||
predicate isUnaryFold() { this.getNumChild() = 1 }
|
||||
|
||||
/** Holds if this is a binary fold expression. */
|
||||
predicate isBinaryFold() { getNumChild() = 2 }
|
||||
predicate isBinaryFold() { this.getNumChild() = 2 }
|
||||
|
||||
/**
|
||||
* Gets the child expression containing the unexpanded parameter pack.
|
||||
*/
|
||||
Expr getPackExpr() {
|
||||
this.isUnaryFold() and
|
||||
result = getChild(0)
|
||||
result = this.getChild(0)
|
||||
or
|
||||
this.isBinaryFold() and
|
||||
if this.isRightFold() then result = getChild(0) else result = getChild(1)
|
||||
if this.isRightFold() then result = this.getChild(0) else result = this.getChild(1)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1251,7 +1261,7 @@ class FoldExpr extends Expr, @foldexpr {
|
||||
*/
|
||||
Expr getInitExpr() {
|
||||
this.isBinaryFold() and
|
||||
if this.isRightFold() then result = getChild(1) else result = getChild(0)
|
||||
if this.isRightFold() then result = this.getChild(1) else result = this.getChild(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
|
||||
/**
|
||||
* Gets an implicitly or explicitly captured value of this lambda expression.
|
||||
*/
|
||||
LambdaCapture getACapture() { result = getCapture(_) }
|
||||
LambdaCapture getACapture() { result = this.getCapture(_) }
|
||||
|
||||
/**
|
||||
* Gets the nth implicitly or explicitly captured value of this lambda expression.
|
||||
@@ -58,13 +58,13 @@ class LambdaExpression extends Expr, @lambdaexpr {
|
||||
* - The return type.
|
||||
* - The statements comprising the lambda body.
|
||||
*/
|
||||
Operator getLambdaFunction() { result = getType().(Closure).getLambdaFunction() }
|
||||
Operator getLambdaFunction() { result = this.getType().(Closure).getLambdaFunction() }
|
||||
|
||||
/**
|
||||
* Gets the initializer that initializes the captured variables in the closure, if any.
|
||||
* A lambda that does not capture any variables will not have an initializer.
|
||||
*/
|
||||
ClassAggregateLiteral getInitializer() { result = getChild(0) }
|
||||
ClassAggregateLiteral getInitializer() { result = this.getChild(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +103,7 @@ class Closure extends Class {
|
||||
* ```
|
||||
*/
|
||||
class LambdaCapture extends Locatable, @lambdacapture {
|
||||
override string toString() { result = getField().getName() }
|
||||
override string toString() { result = this.getField().getName() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LambdaCapture" }
|
||||
|
||||
|
||||
@@ -60,12 +60,12 @@ class TextLiteral extends Literal {
|
||||
|
||||
/** Gets a hex escape sequence that appears in the character or string literal (see [lex.ccon] in the C++ Standard). */
|
||||
string getAHexEscapeSequence(int occurrence, int offset) {
|
||||
result = getValueText().regexpFind("(?<!\\\\)\\\\x[0-9a-fA-F]+", occurrence, offset)
|
||||
result = this.getValueText().regexpFind("(?<!\\\\)\\\\x[0-9a-fA-F]+", occurrence, offset)
|
||||
}
|
||||
|
||||
/** Gets an octal escape sequence that appears in the character or string literal (see [lex.ccon] in the C++ Standard). */
|
||||
string getAnOctalEscapeSequence(int occurrence, int offset) {
|
||||
result = getValueText().regexpFind("(?<!\\\\)\\\\[0-7]{1,3}", occurrence, offset)
|
||||
result = this.getValueText().regexpFind("(?<!\\\\)\\\\[0-7]{1,3}", occurrence, offset)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,27 +75,27 @@ class TextLiteral extends Literal {
|
||||
string getANonStandardEscapeSequence(int occurrence, int offset) {
|
||||
// Find all single character escape sequences (ignoring the start of octal escape sequences),
|
||||
// together with anything starting like a hex escape sequence but not followed by a hex digit.
|
||||
result = getValueText().regexpFind("\\\\[^x0-7\\s]|\\\\x[^0-9a-fA-F]", occurrence, offset) and
|
||||
result = this.getValueText().regexpFind("\\\\[^x0-7\\s]|\\\\x[^0-9a-fA-F]", occurrence, offset) and
|
||||
// From these, exclude all standard escape sequences.
|
||||
not result = getAStandardEscapeSequence(_, _)
|
||||
not result = this.getAStandardEscapeSequence(_, _)
|
||||
}
|
||||
|
||||
/** Gets a simple escape sequence that appears in the char or string literal (see [lex.ccon] in the C++ Standard). */
|
||||
string getASimpleEscapeSequence(int occurrence, int offset) {
|
||||
result = getValueText().regexpFind("\\\\['\"?\\\\abfnrtv]", occurrence, offset)
|
||||
result = this.getValueText().regexpFind("\\\\['\"?\\\\abfnrtv]", occurrence, offset)
|
||||
}
|
||||
|
||||
/** Gets a standard escape sequence that appears in the char or string literal (see [lex.ccon] in the C++ Standard). */
|
||||
string getAStandardEscapeSequence(int occurrence, int offset) {
|
||||
result = getASimpleEscapeSequence(occurrence, offset) or
|
||||
result = getAnOctalEscapeSequence(occurrence, offset) or
|
||||
result = getAHexEscapeSequence(occurrence, offset)
|
||||
result = this.getASimpleEscapeSequence(occurrence, offset) or
|
||||
result = this.getAnOctalEscapeSequence(occurrence, offset) or
|
||||
result = this.getAHexEscapeSequence(occurrence, offset)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of the string literal (including null) before escape sequences added by the extractor.
|
||||
*/
|
||||
int getOriginalLength() { result = getValue().length() + 1 }
|
||||
int getOriginalLength() { result = this.getValue().length() + 1 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +216,7 @@ class ClassAggregateLiteral extends AggregateLiteral {
|
||||
(
|
||||
// If the field has an explicit initializer expression, then the field is
|
||||
// initialized.
|
||||
exists(getFieldExpr(field))
|
||||
exists(this.getFieldExpr(field))
|
||||
or
|
||||
// If the type is not a union, all fields without initializers are value
|
||||
// initialized.
|
||||
@@ -224,7 +224,7 @@ class ClassAggregateLiteral extends AggregateLiteral {
|
||||
or
|
||||
// If the type is a union, and there are no explicit initializers, then
|
||||
// the first declared field is value initialized.
|
||||
not exists(getAChild()) and
|
||||
not exists(this.getAChild()) and
|
||||
field.getInitializationOrder() = 0
|
||||
)
|
||||
}
|
||||
@@ -239,8 +239,8 @@ class ClassAggregateLiteral extends AggregateLiteral {
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate isValueInitialized(Field field) {
|
||||
isInitialized(field) and
|
||||
not exists(getFieldExpr(field))
|
||||
this.isInitialized(field) and
|
||||
not exists(this.getFieldExpr(field))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
|
||||
bindingset[elementIndex]
|
||||
predicate isInitialized(int elementIndex) {
|
||||
elementIndex >= 0 and
|
||||
elementIndex < getArraySize()
|
||||
elementIndex < this.getArraySize()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,8 +298,8 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
|
||||
*/
|
||||
bindingset[elementIndex]
|
||||
predicate isValueInitialized(int elementIndex) {
|
||||
isInitialized(elementIndex) and
|
||||
not exists(getElementExpr(elementIndex))
|
||||
this.isInitialized(elementIndex) and
|
||||
not exists(this.getElementExpr(elementIndex))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class LocalVariable extends LocalScopeVariable, @localvariable { }
|
||||
class VariableDeclarationEntry extends @var_decl {
|
||||
string toString() { result = "QualifiedName DeclarationEntry" }
|
||||
|
||||
Variable getDeclaration() { result = getVariable() }
|
||||
Variable getDeclaration() { result = this.getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the variable which is being declared or defined.
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNodeEx().toString() + ppAp() }
|
||||
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNodeEx() = sink.getNodeEx() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
|
||||
@@ -110,7 +110,7 @@ class Node extends TIRDataFlowNode {
|
||||
/**
|
||||
* Gets an upper bound on the type of this node.
|
||||
*/
|
||||
IRType getTypeBound() { result = getType() }
|
||||
IRType getTypeBound() { result = this.getType() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
Location getLocation() { none() } // overridden by subclasses
|
||||
@@ -831,7 +831,7 @@ class FieldContent extends Content, TFieldContent {
|
||||
FieldContent() { this = TFieldContent(c, startBit, endBit) }
|
||||
|
||||
// Ensure that there's just 1 result for `toString`.
|
||||
override string toString() { result = min(Field f | f = getAField() | f.toString()) }
|
||||
override string toString() { result = min(Field f | f = this.getAField() | f.toString()) }
|
||||
|
||||
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -366,7 +366,7 @@ class MetricClass extends Class {
|
||||
1 +
|
||||
count(string s |
|
||||
exists(Operation op | op = this.getAnEnclosedExpression() and s = op.getOperator())
|
||||
) + count(string s | s = getAUsedHalsteadN1Operator())
|
||||
) + count(string s | s = this.getAUsedHalsteadN1Operator())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -134,7 +134,7 @@ class MetricFile extends File {
|
||||
result =
|
||||
// avoid 0 values
|
||||
1 + count(string s | exists(Operation op | op.getFile() = this and s = op.getOperator())) +
|
||||
count(string s | s = getAUsedHalsteadN1Operator())
|
||||
count(string s | s = this.getAUsedHalsteadN1Operator())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ class MetricFunction extends Function {
|
||||
* `&&`, and `||`) plus one.
|
||||
*/
|
||||
int getCyclomaticComplexity() {
|
||||
result = 1 + cyclomaticComplexityBranches(getBlock()) and
|
||||
result = 1 + cyclomaticComplexityBranches(this.getBlock()) and
|
||||
not this.isMultiplyDefined()
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ class MetricFunction extends Function {
|
||||
int getNestingDepth() {
|
||||
result =
|
||||
max(Stmt s, int aDepth | s.getEnclosingFunction() = this and nestingDepth(s, aDepth) | aDepth) and
|
||||
not isMultiplyDefined()
|
||||
not this.isMultiplyDefined()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ private class MallocAllocationFunction extends AllocationFunction {
|
||||
|
||||
MallocAllocationFunction() {
|
||||
// --- C library allocation
|
||||
hasGlobalOrStdOrBslName("malloc") and // malloc(size)
|
||||
this.hasGlobalOrStdOrBslName("malloc") and // malloc(size)
|
||||
sizeArg = 0
|
||||
or
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress)
|
||||
"MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
|
||||
@@ -39,7 +39,7 @@ private class MallocAllocationFunction extends AllocationFunction {
|
||||
]) and
|
||||
sizeArg = 0
|
||||
or
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"ExAllocatePool", // ExAllocatePool(type, size)
|
||||
"ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag)
|
||||
@@ -56,10 +56,10 @@ private class MallocAllocationFunction extends AllocationFunction {
|
||||
]) and
|
||||
sizeArg = 1
|
||||
or
|
||||
hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
|
||||
this.hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
|
||||
sizeArg = 2
|
||||
or
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
|
||||
"MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
|
||||
@@ -79,7 +79,7 @@ private class AllocaAllocationFunction extends AllocationFunction {
|
||||
int sizeArg;
|
||||
|
||||
AllocaAllocationFunction() {
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- stack allocation
|
||||
"alloca", // // alloca(size)
|
||||
"__builtin_alloca", // __builtin_alloca(size)
|
||||
@@ -104,7 +104,7 @@ private class CallocAllocationFunction extends AllocationFunction {
|
||||
|
||||
CallocAllocationFunction() {
|
||||
// --- C library allocation
|
||||
hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
|
||||
this.hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
|
||||
sizeArg = 1 and
|
||||
multArg = 0
|
||||
}
|
||||
@@ -124,11 +124,11 @@ private class ReallocAllocationFunction extends AllocationFunction {
|
||||
|
||||
ReallocAllocationFunction() {
|
||||
// --- C library allocation
|
||||
hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
|
||||
this.hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
|
||||
sizeArg = 1 and
|
||||
reallocArg = 0
|
||||
or
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- Windows Global / Local legacy allocation
|
||||
"LocalReAlloc", // LocalReAlloc(ptr, size, flags)
|
||||
"GlobalReAlloc", // GlobalReAlloc(ptr, size, flags)
|
||||
@@ -140,7 +140,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
|
||||
sizeArg = 1 and
|
||||
reallocArg = 0
|
||||
or
|
||||
hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
|
||||
this.hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
|
||||
sizeArg = 3 and
|
||||
reallocArg = 2
|
||||
}
|
||||
@@ -156,7 +156,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
|
||||
*/
|
||||
private class SizelessAllocationFunction extends AllocationFunction {
|
||||
SizelessAllocationFunction() {
|
||||
hasGlobalName([
|
||||
this.hasGlobalName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list)
|
||||
"ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list)
|
||||
@@ -209,18 +209,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
AllocationFunction target;
|
||||
|
||||
CallAllocationExpr() {
|
||||
target = getTarget() and
|
||||
target = this.getTarget() and
|
||||
// realloc(ptr, 0) only frees the pointer
|
||||
not (
|
||||
exists(target.getReallocPtrArg()) and
|
||||
getArgument(target.getSizeArg()).getValue().toInt() = 0
|
||||
this.getArgument(target.getSizeArg()).getValue().toInt() = 0
|
||||
) and
|
||||
// these are modelled directly (and more accurately), avoid duplication
|
||||
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
|
||||
}
|
||||
|
||||
override Expr getSizeExpr() {
|
||||
exists(Expr sizeExpr | sizeExpr = getArgument(target.getSizeArg()) |
|
||||
exists(Expr sizeExpr | sizeExpr = this.getArgument(target.getSizeArg()) |
|
||||
if exists(target.getSizeMult())
|
||||
then result = sizeExpr
|
||||
else
|
||||
@@ -233,16 +233,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
|
||||
override int getSizeMult() {
|
||||
// malloc with multiplier argument that is a constant
|
||||
result = getArgument(target.getSizeMult()).getValue().toInt()
|
||||
result = this.getArgument(target.getSizeMult()).getValue().toInt()
|
||||
or
|
||||
// malloc with no multiplier argument
|
||||
not exists(target.getSizeMult()) and
|
||||
deconstructSizeExpr(getArgument(target.getSizeArg()), _, result)
|
||||
deconstructSizeExpr(this.getArgument(target.getSizeArg()), _, result)
|
||||
}
|
||||
|
||||
override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
|
||||
override int getSizeBytes() {
|
||||
result = this.getSizeExpr().getValue().toInt() * this.getSizeMult()
|
||||
}
|
||||
|
||||
override Expr getReallocPtr() { result = getArgument(target.getReallocPtrArg()) }
|
||||
override Expr getReallocPtr() { result = this.getArgument(target.getReallocPtrArg()) }
|
||||
|
||||
override Type getAllocatedElementType() {
|
||||
result =
|
||||
@@ -259,11 +261,11 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
private class NewAllocationExpr extends AllocationExpr, NewExpr {
|
||||
NewAllocationExpr() { this instanceof NewExpr }
|
||||
|
||||
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
||||
override int getSizeBytes() { result = this.getAllocatedType().getSize() }
|
||||
|
||||
override Type getAllocatedElementType() { result = getAllocatedType() }
|
||||
override Type getAllocatedElementType() { result = this.getAllocatedType() }
|
||||
|
||||
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
||||
override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,18 +276,18 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
|
||||
|
||||
override Expr getSizeExpr() {
|
||||
// new array expr with variable size
|
||||
result = getExtent()
|
||||
result = this.getExtent()
|
||||
}
|
||||
|
||||
override int getSizeMult() {
|
||||
// new array expr with variable size
|
||||
exists(getExtent()) and
|
||||
result = getAllocatedElementType().getSize()
|
||||
exists(this.getExtent()) and
|
||||
result = this.getAllocatedElementType().getSize()
|
||||
}
|
||||
|
||||
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
|
||||
|
||||
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
||||
override int getSizeBytes() { result = this.getAllocatedType().getSize() }
|
||||
|
||||
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
||||
override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FlowSource
|
||||
*/
|
||||
private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction,
|
||||
RemoteFlowSourceFunction {
|
||||
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
|
||||
GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
|
||||
i.isParameter(3) and o.isParameterDeref(0)
|
||||
|
||||
@@ -19,7 +19,7 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
|
||||
// gets(str)
|
||||
// fgets(str, num, stream)
|
||||
// fgetws(wstr, num, stream)
|
||||
hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
|
||||
this.hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
@@ -54,13 +54,13 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
|
||||
}
|
||||
|
||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||
not hasName("gets") and
|
||||
not this.hasName("gets") and
|
||||
bufParam = 0 and
|
||||
countParam = 1
|
||||
}
|
||||
|
||||
override predicate hasArrayWithUnknownSize(int bufParam) {
|
||||
hasName("gets") and
|
||||
this.hasName("gets") and
|
||||
bufParam = 0
|
||||
}
|
||||
|
||||
|
||||
@@ -44,27 +44,27 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
|
||||
*/
|
||||
int getParamSize() { if this.hasGlobalName("memccpy") then result = 3 else result = 2 }
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() }
|
||||
override predicate hasArrayInput(int bufParam) { bufParam = this.getParamSrc() }
|
||||
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = getParamDest() }
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(getParamSrc()) and
|
||||
output.isParameterDeref(getParamDest())
|
||||
input.isParameterDeref(this.getParamSrc()) and
|
||||
output.isParameterDeref(this.getParamDest())
|
||||
or
|
||||
input.isParameterDeref(getParamSrc()) and
|
||||
input.isParameterDeref(this.getParamSrc()) and
|
||||
output.isReturnValueDeref()
|
||||
or
|
||||
input.isParameter(getParamDest()) and
|
||||
input.isParameter(this.getParamDest()) and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||
(
|
||||
bufParam = getParamDest() or
|
||||
bufParam = getParamSrc()
|
||||
bufParam = this.getParamDest() or
|
||||
bufParam = this.getParamSrc()
|
||||
) and
|
||||
countParam = getParamSize()
|
||||
countParam = this.getParamSize()
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() { any() }
|
||||
@@ -72,37 +72,37 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i = getParamDest() and
|
||||
i = this.getParamDest() and
|
||||
buffer = true and
|
||||
// memccpy only writes until a given character `c` is found
|
||||
(if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true)
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
i = getParamSrc() and buffer = true
|
||||
i = this.getParamSrc() and buffer = true
|
||||
}
|
||||
|
||||
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
|
||||
result = getParamSize() and
|
||||
result = this.getParamSize() and
|
||||
(
|
||||
i = getParamDest() or
|
||||
i = getParamSrc()
|
||||
i = this.getParamDest() or
|
||||
i = this.getParamSrc()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) {
|
||||
index = getParamSrc()
|
||||
index = this.getParamSrc()
|
||||
or
|
||||
this.hasGlobalName("bcopy") and index = getParamDest()
|
||||
this.hasGlobalName("bcopy") and index = this.getParamDest()
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
not this.hasGlobalName("bcopy") and index = getParamDest()
|
||||
not this.hasGlobalName("bcopy") and index = this.getParamDest()
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int index) {
|
||||
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
|
||||
index = getParamDest()
|
||||
index = this.getParamDest()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,17 +31,17 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
|
||||
|
||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||
bufParam = 0 and
|
||||
(if hasGlobalName(bzero()) then countParam = 1 else countParam = 2)
|
||||
(if this.hasGlobalName(bzero()) then countParam = 1 else countParam = 2)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) { hasGlobalName(bzero()) and index = 0 }
|
||||
override predicate parameterNeverEscapes(int index) { this.hasGlobalName(bzero()) and index = 0 }
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
not hasGlobalName(bzero()) and index = 0
|
||||
not this.hasGlobalName(bzero()) and index = 0
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int index) {
|
||||
not hasGlobalName(bzero()) and index = 0
|
||||
not this.hasGlobalName(bzero()) and index = 0
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() { any() }
|
||||
@@ -54,7 +54,7 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
|
||||
|
||||
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
|
||||
i = 0 and
|
||||
if hasGlobalName(bzero()) then result = 1 else result = 2
|
||||
if this.hasGlobalName(bzero()) then result = 1 else result = 2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,49 +10,49 @@ import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
|
||||
SideEffectFunction {
|
||||
PureStrFunction() {
|
||||
hasGlobalOrStdOrBslName([
|
||||
this.hasGlobalOrStdOrBslName([
|
||||
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
|
||||
"strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
|
||||
])
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) {
|
||||
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasArrayWithNullTerminator(int bufParam) {
|
||||
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
exists(ParameterIndex i |
|
||||
(
|
||||
input.isParameter(i) and
|
||||
exists(getParameter(i))
|
||||
exists(this.getParameter(i))
|
||||
or
|
||||
input.isParameterDeref(i) and
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
) and
|
||||
// Functions that end with _l also take a locale argument (always as the last argument),
|
||||
// and we don't want taint from those arguments.
|
||||
(not this.getName().matches("%\\_l") or exists(getParameter(i + 1)))
|
||||
(not this.getName().matches("%\\_l") or exists(this.getParameter(i + 1)))
|
||||
) and
|
||||
(
|
||||
output.isReturnValueDeref() and
|
||||
getUnspecifiedType() instanceof PointerType
|
||||
this.getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int i) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
not parameterEscapesOnlyViaReturn(i)
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
not this.parameterEscapesOnlyViaReturn(i)
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int i) {
|
||||
i = 0 and
|
||||
getUnspecifiedType() instanceof PointerType
|
||||
this.getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int i) { none() }
|
||||
@@ -62,7 +62,7 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
buffer = true
|
||||
}
|
||||
}
|
||||
@@ -97,21 +97,21 @@ private string strcmp() {
|
||||
*/
|
||||
private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
|
||||
StrLenFunction() {
|
||||
hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
|
||||
this.hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
|
||||
or
|
||||
hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
|
||||
this.hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) {
|
||||
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasArrayWithNullTerminator(int bufParam) {
|
||||
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int i) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int i) { none() }
|
||||
@@ -123,7 +123,7 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
buffer = true
|
||||
}
|
||||
}
|
||||
@@ -133,12 +133,12 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
|
||||
* side-effect free. Excludes functions modeled by `PureStrFunction` and `PureMemFunction`.
|
||||
*/
|
||||
private class PureFunction extends TaintFunction, SideEffectFunction {
|
||||
PureFunction() { hasGlobalOrStdOrBslName(["abs", "labs"]) }
|
||||
PureFunction() { this.hasGlobalOrStdOrBslName(["abs", "labs"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
exists(ParameterIndex i |
|
||||
input.isParameter(i) and
|
||||
exists(getParameter(i))
|
||||
exists(this.getParameter(i))
|
||||
) and
|
||||
output.isReturnValue()
|
||||
}
|
||||
@@ -155,44 +155,44 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
|
||||
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
|
||||
SideEffectFunction {
|
||||
PureMemFunction() {
|
||||
hasGlobalOrStdOrBslName([
|
||||
this.hasGlobalOrStdOrBslName([
|
||||
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"
|
||||
]) or
|
||||
this.hasGlobalName("memfrob")
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) {
|
||||
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
exists(ParameterIndex i |
|
||||
(
|
||||
input.isParameter(i) and
|
||||
exists(getParameter(i))
|
||||
exists(this.getParameter(i))
|
||||
or
|
||||
input.isParameterDeref(i) and
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType
|
||||
) and
|
||||
// `memfrob` should not have taint from the size argument.
|
||||
(not this.hasGlobalName("memfrob") or i = 0)
|
||||
) and
|
||||
(
|
||||
output.isReturnValueDeref() and
|
||||
getUnspecifiedType() instanceof PointerType
|
||||
this.getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int i) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
not parameterEscapesOnlyViaReturn(i)
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
not this.parameterEscapesOnlyViaReturn(i)
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int i) {
|
||||
i = 0 and
|
||||
getUnspecifiedType() instanceof PointerType
|
||||
this.getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int i) { none() }
|
||||
@@ -202,7 +202,7 @@ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunctio
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
|
||||
buffer = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ private class MakeUniqueOrShared extends TaintFunction {
|
||||
// since these just take a size argument, which we don't want to propagate taint through.
|
||||
not this.isArray() and
|
||||
(
|
||||
input.isParameter([0 .. getNumberOfParameters() - 1])
|
||||
input.isParameter([0 .. this.getNumberOfParameters() - 1])
|
||||
or
|
||||
input.isParameterDeref([0 .. getNumberOfParameters() - 1])
|
||||
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1])
|
||||
) and
|
||||
output.isReturnValue()
|
||||
}
|
||||
@@ -116,14 +116,14 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
|
||||
or
|
||||
// When taking ownership of a smart pointer via an rvalue reference, always overwrite the input
|
||||
// smart pointer.
|
||||
getPointerInput().isParameterDeref(i) and
|
||||
this.getPointerInput().isParameterDeref(i) and
|
||||
this.getParameter(i).getUnspecifiedType() instanceof RValueReferenceType and
|
||||
buffer = false and
|
||||
mustWrite = true
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
getPointerInput().isParameterDeref(i) and
|
||||
this.getPointerInput().isParameterDeref(i) and
|
||||
buffer = false
|
||||
or
|
||||
not this instanceof Constructor and
|
||||
@@ -136,7 +136,7 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
|
||||
|
||||
override predicate hasAddressFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = getPointerInput() and
|
||||
input = this.getPointerInput() and
|
||||
output.isQualifierObject()
|
||||
or
|
||||
// Assignment operator always returns a reference to `*this`.
|
||||
|
||||
@@ -23,15 +23,15 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
|
||||
bufParam = this.(ScanfFunction).getInputParameterIndex()
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
|
||||
override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
|
||||
|
||||
private int getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() }
|
||||
|
||||
private int getLocaleParameterIndex() {
|
||||
this.getName().matches("%\\_l") and
|
||||
(
|
||||
if exists(getLengthParameterIndex())
|
||||
then result = getLengthParameterIndex() + 2
|
||||
if exists(this.getLengthParameterIndex())
|
||||
then result = this.getLengthParameterIndex() + 2
|
||||
else result = 2
|
||||
)
|
||||
}
|
||||
@@ -40,11 +40,11 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
|
||||
output.isParameterDeref(any(int i | i >= getArgsStartPosition()))
|
||||
output.isParameterDeref(any(int i | i >= this.getArgsStartPosition()))
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) {
|
||||
index = [0 .. max(getACallToThisFunction().getNumberOfArguments())]
|
||||
index = [0 .. max(this.getACallToThisFunction().getNumberOfArguments())]
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
|
||||
@@ -56,7 +56,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i >= getArgsStartPosition() and
|
||||
i >= this.getArgsStartPosition() and
|
||||
buffer = true and
|
||||
mustWrite = true
|
||||
}
|
||||
@@ -66,7 +66,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
|
||||
i =
|
||||
[
|
||||
this.(ScanfFunction).getInputParameterIndex(),
|
||||
this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex()
|
||||
this.(ScanfFunction).getFormatParameterIndex(), this.getLocaleParameterIndex()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,20 +61,20 @@ private class StdSequenceContainerConstructor extends Constructor, TaintFunction
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from any parameter of the value type to the returned object
|
||||
(
|
||||
input.isParameterDeref(getAValueTypeParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAValueTypeParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
@@ -158,21 +158,21 @@ private class StdSequenceContainerInsert extends TaintFunction {
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to container itself (qualifier) and return value
|
||||
(
|
||||
input.isQualifierObject() or
|
||||
input.isParameterDeref(getAValueTypeParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAValueTypeParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
@@ -197,20 +197,20 @@ private class StdSequenceContainerAssign extends TaintFunction {
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to container itself (qualifier)
|
||||
(
|
||||
input.isParameterDeref(getAValueTypeParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAValueTypeParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
@@ -246,7 +246,7 @@ class StdVectorEmplace extends TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from any parameter except the position iterator to qualifier and return value
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
input.isParameterDeref([1 .. getNumberOfParameters() - 1]) and
|
||||
input.isParameterDeref([1 .. this.getNumberOfParameters() - 1]) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
output.isReturnValue()
|
||||
@@ -263,7 +263,7 @@ class StdVectorEmplaceBack extends TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from any parameter to qualifier
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
input.isParameterDeref([0 .. getNumberOfParameters() - 1]) and
|
||||
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ private class StdMapConstructor extends Constructor, TaintFunction {
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType() instanceof Iterator
|
||||
this.getParameter(result).getUnspecifiedType() instanceof Iterator
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from any parameter of an iterator type to the qualifier
|
||||
input.isParameterDeref(getAnIteratorParameterIndex()) and
|
||||
input.isParameterDeref(this.getAnIteratorParameterIndex()) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
or
|
||||
@@ -47,7 +47,7 @@ private class StdMapInsert extends TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from last parameter to qualifier and return value
|
||||
// (where the return value is a pair, this should really flow just to the first part of it)
|
||||
input.isParameterDeref(getNumberOfParameters() - 1) and
|
||||
input.isParameterDeref(this.getNumberOfParameters() - 1) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
output.isReturnValue()
|
||||
@@ -66,7 +66,7 @@ private class StdMapEmplace extends TaintFunction {
|
||||
// construct a pair, or a pair to be copied / moved) to the qualifier and
|
||||
// return value.
|
||||
// (where the return value is a pair, this should really flow just to the first part of it)
|
||||
input.isParameterDeref(getNumberOfParameters() - 1) and
|
||||
input.isParameterDeref(this.getNumberOfParameters() - 1) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
output.isReturnValue()
|
||||
@@ -87,9 +87,9 @@ private class StdMapTryEmplace extends TaintFunction {
|
||||
// flow from any parameter apart from the key to qualifier and return value
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
// (where the return value is a pair, this should really flow just to the first part of it)
|
||||
exists(int arg | arg = [1 .. getNumberOfParameters() - 1] |
|
||||
exists(int arg | arg = [1 .. this.getNumberOfParameters() - 1] |
|
||||
(
|
||||
not getUnspecifiedType() instanceof Iterator or
|
||||
not this.getUnspecifiedType() instanceof Iterator or
|
||||
arg != 1
|
||||
) and
|
||||
input.isParameterDeref(arg)
|
||||
@@ -154,7 +154,7 @@ private class StdMapErase extends TaintFunction {
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to iterator return value
|
||||
getType().getUnderlyingType() instanceof Iterator and
|
||||
this.getType().getUnderlyingType() instanceof Iterator and
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
@@ -51,13 +51,13 @@ private class StdPairConstructor extends Constructor, TaintFunction {
|
||||
* either value type of the pair.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from second parameter of a value type to the qualifier
|
||||
getAValueTypeParameterIndex() = 1 and
|
||||
this.getAValueTypeParameterIndex() = 1 and
|
||||
input.isParameterDeref(1) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
|
||||
@@ -22,12 +22,12 @@ private class StdSetConstructor extends Constructor, TaintFunction {
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() {
|
||||
getParameter(result).getUnspecifiedType() instanceof Iterator
|
||||
this.getParameter(result).getUnspecifiedType() instanceof Iterator
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from any parameter of an iterator type to the qualifier
|
||||
input.isParameterDeref(getAnIteratorParameterIndex()) and
|
||||
input.isParameterDeref(this.getAnIteratorParameterIndex()) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
or
|
||||
@@ -45,7 +45,7 @@ private class StdSetInsert extends TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from last parameter to qualifier and return value
|
||||
// (where the return value is a pair, this should really flow just to the first part of it)
|
||||
input.isParameterDeref(getNumberOfParameters() - 1) and
|
||||
input.isParameterDeref(this.getNumberOfParameters() - 1) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
output.isReturnValue()
|
||||
@@ -63,7 +63,7 @@ private class StdSetEmplace extends TaintFunction {
|
||||
// flow from any parameter to qualifier and return value
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
// (where the return value is a pair, this should really flow just to the first part of it)
|
||||
input.isParameterDeref([0 .. getNumberOfParameters() - 1]) and
|
||||
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
output.isReturnValue()
|
||||
@@ -107,7 +107,7 @@ private class StdSetErase extends TaintFunction {
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to iterator return value
|
||||
getType().getUnderlyingType() instanceof Iterator and
|
||||
this.getType().getUnderlyingType() instanceof Iterator and
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
@@ -31,31 +31,31 @@ private class StdStringConstructor extends Constructor, TaintFunction {
|
||||
* character).
|
||||
*/
|
||||
int getAStringParameterIndex() {
|
||||
exists(Type paramType | paramType = getParameter(result).getUnspecifiedType() |
|
||||
exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() |
|
||||
// e.g. `std::basic_string::CharT *`
|
||||
paramType instanceof PointerType
|
||||
or
|
||||
// e.g. `std::basic_string &`, avoiding `const Allocator&`
|
||||
paramType instanceof ReferenceType and
|
||||
not paramType.(ReferenceType).getBaseType() =
|
||||
getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
|
||||
this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
|
||||
or
|
||||
// i.e. `std::basic_string::CharT`
|
||||
getParameter(result).getUnspecifiedType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
|
||||
this.getParameter(result).getUnspecifiedType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from any parameter of the value type to the returned object
|
||||
(
|
||||
input.isParameterDeref(getAStringParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAStringParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
@@ -156,23 +156,23 @@ private class StdStringAppend extends TaintFunction {
|
||||
* character).
|
||||
*/
|
||||
int getAStringParameterIndex() {
|
||||
getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
|
||||
getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
|
||||
getParameter(result).getUnspecifiedType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
|
||||
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
|
||||
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
|
||||
this.getParameter(result).getUnspecifiedType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from string and parameter to string (qualifier) and return value
|
||||
(
|
||||
input.isQualifierObject() or
|
||||
input.isParameterDeref(getAStringParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAStringParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
@@ -197,22 +197,22 @@ private class StdStringAssign extends TaintFunction {
|
||||
* character).
|
||||
*/
|
||||
int getAStringParameterIndex() {
|
||||
getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
|
||||
getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
|
||||
getParameter(result).getUnspecifiedType() =
|
||||
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
|
||||
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
|
||||
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
|
||||
this.getParameter(result).getUnspecifiedType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to string itself (qualifier) and return value
|
||||
(
|
||||
input.isParameterDeref(getAStringParameterIndex()) or
|
||||
input.isParameter(getAnIteratorParameterIndex())
|
||||
input.isParameterDeref(this.getAStringParameterIndex()) or
|
||||
input.isParameter(this.getAnIteratorParameterIndex())
|
||||
) and
|
||||
(
|
||||
output.isQualifierObject() or
|
||||
@@ -574,12 +574,12 @@ private class StdStringStreamConstructor extends Constructor, TaintFunction {
|
||||
* Gets the index of a parameter to this function that is a string.
|
||||
*/
|
||||
int getAStringParameterIndex() {
|
||||
getParameter(result).getType() instanceof ReferenceType // `const std::basic_string &`
|
||||
this.getParameter(result).getType() instanceof ReferenceType // `const std::basic_string &`
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// taint flow from any parameter of string type to the returned object
|
||||
input.isParameterDeref(getAStringParameterIndex()) and
|
||||
input.isParameterDeref(this.getAStringParameterIndex()) and
|
||||
(
|
||||
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
|
||||
or
|
||||
|
||||
@@ -32,7 +32,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
|
||||
/**
|
||||
* Gets the index of the parameter that is the size of the copy (in characters).
|
||||
*/
|
||||
int getParamSize() { exists(getParameter(2)) and result = 2 }
|
||||
int getParamSize() { exists(this.getParameter(2)) and result = 2 }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the source of the copy.
|
||||
@@ -50,11 +50,11 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
|
||||
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
|
||||
input.isParameter(2) and
|
||||
output.isParameterDeref(0)
|
||||
or
|
||||
getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
|
||||
this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
|
||||
input.isParameter(3) and
|
||||
output.isParameterDeref(0)
|
||||
or
|
||||
|
||||
@@ -45,22 +45,22 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
|
||||
) and
|
||||
// exclude the 2-parameter template versions
|
||||
// that find the size of a fixed size destination buffer.
|
||||
getNumberOfParameters() = 3
|
||||
this.getNumberOfParameters() = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is one of the `strcpy_s` variants.
|
||||
*/
|
||||
private predicate isSVariant() { getName().matches("%\\_s") }
|
||||
private predicate isSVariant() { this.getName().matches("%\\_s") }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the maximum size of the copy (in characters).
|
||||
*/
|
||||
int getParamSize() {
|
||||
if isSVariant()
|
||||
if this.isSVariant()
|
||||
then result = 1
|
||||
else (
|
||||
getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
|
||||
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
|
||||
result = 2
|
||||
)
|
||||
}
|
||||
@@ -68,49 +68,49 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
|
||||
/**
|
||||
* Gets the index of the parameter that is the source of the copy.
|
||||
*/
|
||||
int getParamSrc() { if isSVariant() then result = 2 else result = 1 }
|
||||
int getParamSrc() { if this.isSVariant() then result = 2 else result = 1 }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the destination of the copy.
|
||||
*/
|
||||
int getParamDest() { result = 0 }
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() }
|
||||
override predicate hasArrayInput(int bufParam) { bufParam = this.getParamSrc() }
|
||||
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = getParamDest() }
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() }
|
||||
|
||||
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = getParamSrc() }
|
||||
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = this.getParamSrc() }
|
||||
|
||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||
bufParam = getParamDest() and
|
||||
countParam = getParamSize()
|
||||
bufParam = this.getParamDest() and
|
||||
countParam = this.getParamSize()
|
||||
}
|
||||
|
||||
override predicate hasArrayWithUnknownSize(int bufParam) {
|
||||
not exists(getParamSize()) and
|
||||
bufParam = getParamDest()
|
||||
not exists(this.getParamSize()) and
|
||||
bufParam = this.getParamDest()
|
||||
}
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
not exists(getParamSize()) and
|
||||
input.isParameterDeref(getParamSrc()) and
|
||||
output.isParameterDeref(getParamDest())
|
||||
not exists(this.getParamSize()) and
|
||||
input.isParameterDeref(this.getParamSrc()) and
|
||||
output.isParameterDeref(this.getParamDest())
|
||||
or
|
||||
not exists(getParamSize()) and
|
||||
input.isParameterDeref(getParamSrc()) and
|
||||
not exists(this.getParamSize()) and
|
||||
input.isParameterDeref(this.getParamSrc()) and
|
||||
output.isReturnValueDeref()
|
||||
or
|
||||
input.isParameter(getParamDest()) and
|
||||
input.isParameter(this.getParamDest()) and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// these may do only a partial copy of the input buffer to the output
|
||||
// buffer
|
||||
exists(getParamSize()) and
|
||||
input.isParameter(getParamSrc()) and
|
||||
exists(this.getParamSize()) and
|
||||
input.isParameter(this.getParamSrc()) and
|
||||
(
|
||||
output.isParameterDeref(getParamDest()) or
|
||||
output.isParameterDeref(this.getParamDest()) or
|
||||
output.isReturnValueDeref()
|
||||
)
|
||||
}
|
||||
@@ -120,18 +120,18 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i = getParamDest() and
|
||||
i = this.getParamDest() and
|
||||
buffer = true and
|
||||
mustWrite = false
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
i = getParamSrc() and
|
||||
i = this.getParamSrc() and
|
||||
buffer = true
|
||||
}
|
||||
|
||||
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
|
||||
i = getParamDest() and
|
||||
result = getParamSize()
|
||||
i = this.getParamDest() and
|
||||
result = this.getParamSize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
|
||||
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
|
||||
override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
exists(int index | hasArrayInput(index) |
|
||||
exists(int index | this.hasArrayInput(index) |
|
||||
input.isParameter(index) and output.isReturnValue()
|
||||
or
|
||||
input.isParameterDeref(index) and output.isReturnValueDeref()
|
||||
@@ -44,6 +44,6 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
hasArrayInput(i) and buffer = true
|
||||
this.hasArrayInput(i) and buffer = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
|
||||
this.hasName("swap") and
|
||||
this.getNumberOfParameters() = 1 and
|
||||
this.getParameter(0).getType().(ReferenceType).getBaseType().getUnspecifiedType() =
|
||||
getDeclaringType()
|
||||
this.getDeclaringType()
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
|
||||
@@ -44,7 +44,7 @@ class FunctionInput extends TFunctionInput {
|
||||
* Holds if this is the input value of the parameter with index `index`.
|
||||
* DEPRECATED: Use `isParameter(index)` instead.
|
||||
*/
|
||||
deprecated final predicate isInParameter(ParameterIndex index) { isParameter(index) }
|
||||
deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
|
||||
|
||||
/**
|
||||
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
|
||||
@@ -70,7 +70,9 @@ class FunctionInput extends TFunctionInput {
|
||||
* `index`.
|
||||
* DEPRECATED: Use `isParameterDeref(index)` instead.
|
||||
*/
|
||||
deprecated final predicate isInParameterPointer(ParameterIndex index) { isParameterDeref(index) }
|
||||
deprecated final predicate isInParameterPointer(ParameterIndex index) {
|
||||
this.isParameterDeref(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the input value pointed to by the `this` pointer of an instance member
|
||||
@@ -92,7 +94,7 @@ class FunctionInput extends TFunctionInput {
|
||||
* function.
|
||||
* DEPRECATED: Use `isQualifierObject()` instead.
|
||||
*/
|
||||
deprecated final predicate isInQualifier() { isQualifierObject() }
|
||||
deprecated final predicate isInQualifier() { this.isQualifierObject() }
|
||||
|
||||
/**
|
||||
* Holds if this is the input value of the `this` pointer of an instance member function.
|
||||
@@ -314,7 +316,9 @@ class FunctionOutput extends TFunctionOutput {
|
||||
* index `index`.
|
||||
* DEPRECATED: Use `isParameterDeref(index)` instead.
|
||||
*/
|
||||
deprecated final predicate isOutParameterPointer(ParameterIndex index) { isParameterDeref(index) }
|
||||
deprecated final predicate isOutParameterPointer(ParameterIndex index) {
|
||||
this.isParameterDeref(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the output value pointed to by the `this` pointer of an instance member
|
||||
@@ -336,7 +340,7 @@ class FunctionOutput extends TFunctionOutput {
|
||||
* function.
|
||||
* DEPRECATED: Use `isQualifierObject()` instead.
|
||||
*/
|
||||
deprecated final predicate isOutQualifier() { isQualifierObject() }
|
||||
deprecated final predicate isOutQualifier() { this.isQualifierObject() }
|
||||
|
||||
/**
|
||||
* Holds if this is the value returned by a function.
|
||||
@@ -361,7 +365,7 @@ class FunctionOutput extends TFunctionOutput {
|
||||
* Holds if this is the value returned by a function.
|
||||
* DEPRECATED: Use `isReturnValue()` instead.
|
||||
*/
|
||||
deprecated final predicate isOutReturnValue() { isReturnValue() }
|
||||
deprecated final predicate isOutReturnValue() { this.isReturnValue() }
|
||||
|
||||
/**
|
||||
* Holds if this is the output value pointed to by the return value of a function, if the function
|
||||
@@ -389,7 +393,7 @@ class FunctionOutput extends TFunctionOutput {
|
||||
* function returns a reference.
|
||||
* DEPRECATED: Use `isReturnValueDeref()` instead.
|
||||
*/
|
||||
deprecated final predicate isOutReturnPointer() { isReturnValueDeref() }
|
||||
deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
|
||||
|
||||
/**
|
||||
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or
|
||||
|
||||
@@ -72,7 +72,7 @@ abstract class Architecture extends string {
|
||||
or
|
||||
t instanceof CharType and result = 8
|
||||
or
|
||||
t instanceof WideCharType and result = wideCharSize()
|
||||
t instanceof WideCharType and result = this.wideCharSize()
|
||||
or
|
||||
t instanceof Char8Type and result = 8
|
||||
or
|
||||
@@ -84,22 +84,22 @@ abstract class Architecture extends string {
|
||||
or
|
||||
t instanceof IntType and result = 32
|
||||
or
|
||||
t instanceof LongType and result = longSize()
|
||||
t instanceof LongType and result = this.longSize()
|
||||
or
|
||||
t instanceof LongLongType and result = longLongSize()
|
||||
t instanceof LongLongType and result = this.longLongSize()
|
||||
or
|
||||
result = enumBitSize(t.(Enum))
|
||||
result = this.enumBitSize(t.(Enum))
|
||||
or
|
||||
result = integralBitSize(t.(SpecifiedType).getBaseType())
|
||||
result = this.integralBitSize(t.(SpecifiedType).getBaseType())
|
||||
or
|
||||
result = integralBitSize(t.(TypedefType).getBaseType())
|
||||
result = this.integralBitSize(t.(TypedefType).getBaseType())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bit size of enum type `e`.
|
||||
*/
|
||||
int enumBitSize(Enum e) {
|
||||
result = integralBitSize(e.getExplicitUnderlyingType())
|
||||
result = this.integralBitSize(e.getExplicitUnderlyingType())
|
||||
or
|
||||
not exists(e.getExplicitUnderlyingType()) and result = 32
|
||||
}
|
||||
@@ -108,7 +108,7 @@ abstract class Architecture extends string {
|
||||
* Gets the alignment of enum type `e`.
|
||||
*/
|
||||
int enumAlignment(Enum e) {
|
||||
result = alignment(e.getExplicitUnderlyingType())
|
||||
result = this.alignment(e.getExplicitUnderlyingType())
|
||||
or
|
||||
not exists(e.getExplicitUnderlyingType()) and result = 32
|
||||
}
|
||||
@@ -120,26 +120,26 @@ abstract class Architecture extends string {
|
||||
*/
|
||||
cached
|
||||
int bitSize(Type t) {
|
||||
result = integralBitSize(t)
|
||||
result = this.integralBitSize(t)
|
||||
or
|
||||
t instanceof FloatType and result = 32
|
||||
or
|
||||
t instanceof DoubleType and result = 64
|
||||
or
|
||||
t instanceof LongDoubleType and result = longDoubleSize()
|
||||
t instanceof LongDoubleType and result = this.longDoubleSize()
|
||||
or
|
||||
t instanceof PointerType and result = pointerSize()
|
||||
t instanceof PointerType and result = this.pointerSize()
|
||||
or
|
||||
t instanceof ReferenceType and result = pointerSize()
|
||||
t instanceof ReferenceType and result = this.pointerSize()
|
||||
or
|
||||
t instanceof FunctionPointerType and result = pointerSize()
|
||||
t instanceof FunctionPointerType and result = this.pointerSize()
|
||||
or
|
||||
result = bitSize(t.(SpecifiedType).getBaseType())
|
||||
result = this.bitSize(t.(SpecifiedType).getBaseType())
|
||||
or
|
||||
result = bitSize(t.(TypedefType).getBaseType())
|
||||
result = this.bitSize(t.(TypedefType).getBaseType())
|
||||
or
|
||||
exists(ArrayType array | array = t |
|
||||
result = array.getArraySize() * paddedSize(array.getBaseType())
|
||||
result = array.getArraySize() * this.paddedSize(array.getBaseType())
|
||||
)
|
||||
or
|
||||
result = t.(PaddedType).typeBitSize(this)
|
||||
@@ -155,7 +155,7 @@ abstract class Architecture extends string {
|
||||
or
|
||||
t instanceof CharType and result = 8
|
||||
or
|
||||
t instanceof WideCharType and result = wideCharSize()
|
||||
t instanceof WideCharType and result = this.wideCharSize()
|
||||
or
|
||||
t instanceof Char8Type and result = 8
|
||||
or
|
||||
@@ -169,27 +169,27 @@ abstract class Architecture extends string {
|
||||
or
|
||||
t instanceof FloatType and result = 32
|
||||
or
|
||||
t instanceof DoubleType and result = doubleAlign()
|
||||
t instanceof DoubleType and result = this.doubleAlign()
|
||||
or
|
||||
t instanceof LongType and result = longSize()
|
||||
t instanceof LongType and result = this.longSize()
|
||||
or
|
||||
t instanceof LongDoubleType and result = longDoubleAlign()
|
||||
t instanceof LongDoubleType and result = this.longDoubleAlign()
|
||||
or
|
||||
t instanceof LongLongType and result = longLongAlign()
|
||||
t instanceof LongLongType and result = this.longLongAlign()
|
||||
or
|
||||
t instanceof PointerType and result = pointerSize()
|
||||
t instanceof PointerType and result = this.pointerSize()
|
||||
or
|
||||
t instanceof FunctionPointerType and result = pointerSize()
|
||||
t instanceof FunctionPointerType and result = this.pointerSize()
|
||||
or
|
||||
t instanceof ReferenceType and result = pointerSize()
|
||||
t instanceof ReferenceType and result = this.pointerSize()
|
||||
or
|
||||
result = enumAlignment(t.(Enum))
|
||||
result = this.enumAlignment(t.(Enum))
|
||||
or
|
||||
result = alignment(t.(SpecifiedType).getBaseType())
|
||||
result = this.alignment(t.(SpecifiedType).getBaseType())
|
||||
or
|
||||
result = alignment(t.(TypedefType).getBaseType())
|
||||
result = this.alignment(t.(TypedefType).getBaseType())
|
||||
or
|
||||
result = alignment(t.(ArrayType).getBaseType())
|
||||
result = this.alignment(t.(ArrayType).getBaseType())
|
||||
or
|
||||
result = t.(PaddedType).typeAlignment(this)
|
||||
}
|
||||
@@ -203,7 +203,7 @@ abstract class Architecture extends string {
|
||||
exists(Type realType | realType = stripSpecifiers(t) |
|
||||
if realType instanceof PaddedType
|
||||
then result = realType.(PaddedType).paddedSize(this)
|
||||
else result = bitSize(realType)
|
||||
else result = this.bitSize(realType)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -429,7 +429,7 @@ class PaddedType extends Class {
|
||||
* Gets the number of bits wasted by padding at the end of this
|
||||
* struct.
|
||||
*/
|
||||
int trailingPadding(Architecture arch) { result = paddedSize(arch) - arch.bitSize(this) }
|
||||
int trailingPadding(Architecture arch) { result = this.paddedSize(arch) - arch.bitSize(this) }
|
||||
|
||||
/**
|
||||
* Gets the number of bits wasted in this struct definition; that is.
|
||||
@@ -440,7 +440,7 @@ class PaddedType extends Class {
|
||||
* laid out one after another, and hence there is no padding between
|
||||
* them.
|
||||
*/
|
||||
int wastedSpace(Architecture arch) { result = arch.paddedSize(this) - dataSize(arch) }
|
||||
int wastedSpace(Architecture arch) { result = arch.paddedSize(this) - this.dataSize(arch) }
|
||||
|
||||
/**
|
||||
* Gets the total size of all fields declared in this class, not including any
|
||||
@@ -448,8 +448,8 @@ class PaddedType extends Class {
|
||||
*/
|
||||
private int fieldDataSize(Architecture arch) {
|
||||
if this instanceof Union
|
||||
then result = max(Field f | f = this.getAMember() | fieldSize(f, arch))
|
||||
else result = sum(Field f | f = this.getAMember() | fieldSize(f, arch))
|
||||
then result = max(Field f | f = this.getAMember() | this.fieldSize(f, arch))
|
||||
else result = sum(Field f | f = this.getAMember() | this.fieldSize(f, arch))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,7 +472,7 @@ class PaddedType extends Class {
|
||||
* reorganizing member structs' field layouts.
|
||||
*/
|
||||
int optimalSize(Architecture arch) {
|
||||
result = alignUp(dataSize(arch), arch.alignment(this)).maximum(8)
|
||||
result = alignUp(this.dataSize(arch), arch.alignment(this)).maximum(8)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,11 +490,11 @@ class PaddedType extends Class {
|
||||
// but that uses a recursive aggregate, which isn't supported in
|
||||
// QL. We therefore use this slightly more complex implementation
|
||||
// instead.
|
||||
result = biggestFieldSizeUpTo(lastFieldIndex(), arch)
|
||||
result = this.biggestFieldSizeUpTo(this.lastFieldIndex(), arch)
|
||||
else
|
||||
// If we're not a union type, the size is the padded
|
||||
// sum of field sizes, padded.
|
||||
result = fieldEnd(lastFieldIndex(), arch)
|
||||
result = this.fieldEnd(this.lastFieldIndex(), arch)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,8 +522,8 @@ class PaddedType extends Class {
|
||||
if index = 0
|
||||
then result = 0
|
||||
else
|
||||
exists(Field f, int fSize | index = fieldIndex(f) and fSize = fieldSize(f, arch) |
|
||||
result = fSize.maximum(biggestFieldSizeUpTo(index - 1, arch))
|
||||
exists(Field f, int fSize | index = this.fieldIndex(f) and fSize = this.fieldSize(f, arch) |
|
||||
result = fSize.maximum(this.biggestFieldSizeUpTo(index - 1, arch))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -536,8 +536,10 @@ class PaddedType extends Class {
|
||||
if index = 0
|
||||
then result = 1 // Minimum possible alignment
|
||||
else
|
||||
exists(Field f, int fAlign | index = fieldIndex(f) and fAlign = arch.alignment(f.getType()) |
|
||||
result = fAlign.maximum(biggestAlignmentUpTo(index - 1, arch))
|
||||
exists(Field f, int fAlign |
|
||||
index = this.fieldIndex(f) and fAlign = arch.alignment(f.getType())
|
||||
|
|
||||
result = fAlign.maximum(this.biggestAlignmentUpTo(index - 1, arch))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -545,17 +547,18 @@ class PaddedType extends Class {
|
||||
* Gets the 1-based index for each field.
|
||||
*/
|
||||
int fieldIndex(Field f) {
|
||||
memberIndex(f) = rank[result](Field field, int index | memberIndex(field) = index | index)
|
||||
this.memberIndex(f) =
|
||||
rank[result](Field field, int index | this.memberIndex(field) = index | index)
|
||||
}
|
||||
|
||||
private int memberIndex(Field f) { result = min(int i | getCanonicalMember(i) = f) }
|
||||
private int memberIndex(Field f) { result = min(int i | this.getCanonicalMember(i) = f) }
|
||||
|
||||
/**
|
||||
* Gets the 1-based index for the last field.
|
||||
*/
|
||||
int lastFieldIndex() {
|
||||
if exists(lastField())
|
||||
then result = fieldIndex(lastField())
|
||||
if exists(this.lastField())
|
||||
then result = this.fieldIndex(this.lastField())
|
||||
else
|
||||
// Field indices are 1-based, so return 0 to represent the lack of fields.
|
||||
result = 0
|
||||
@@ -566,25 +569,27 @@ class PaddedType extends Class {
|
||||
* `arch`.
|
||||
*/
|
||||
int fieldSize(Field f, Architecture arch) {
|
||||
exists(fieldIndex(f)) and
|
||||
exists(this.fieldIndex(f)) and
|
||||
if f instanceof BitField
|
||||
then result = f.(BitField).getNumBits()
|
||||
else result = arch.paddedSize(f.getType())
|
||||
}
|
||||
|
||||
/** Gets the last field of this type. */
|
||||
Field lastField() { fieldIndex(result) = max(Field other | | fieldIndex(other)) }
|
||||
Field lastField() { this.fieldIndex(result) = max(Field other | | this.fieldIndex(other)) }
|
||||
|
||||
/**
|
||||
* Gets the offset, in bits, of the end of the class' last base class
|
||||
* subobject, or zero if the class has no base classes.
|
||||
*/
|
||||
int baseClassEnd(Architecture arch) {
|
||||
if exists(getABaseClass()) then result = arch.baseClassSize(getADerivation()) else result = 0
|
||||
if exists(this.getABaseClass())
|
||||
then result = arch.baseClassSize(this.getADerivation())
|
||||
else result = 0
|
||||
}
|
||||
|
||||
/** Gets the bitfield at field index `index`, if that field is a bitfield. */
|
||||
private BitField bitFieldAt(int index) { fieldIndex(result) = index }
|
||||
private BitField bitFieldAt(int index) { this.fieldIndex(result) = index }
|
||||
|
||||
/**
|
||||
* Gets the 0-based offset, in bits, of the first free bit after
|
||||
@@ -596,13 +601,13 @@ class PaddedType extends Class {
|
||||
then
|
||||
// Base case: No fields seen yet, so return the offset of the end of the
|
||||
// base class subojects.
|
||||
result = baseClassEnd(arch)
|
||||
result = this.baseClassEnd(arch)
|
||||
else
|
||||
exists(Field f | index = fieldIndex(f) |
|
||||
exists(int fSize | fSize = fieldSize(f, arch) |
|
||||
exists(Field f | index = this.fieldIndex(f) |
|
||||
exists(int fSize | fSize = this.fieldSize(f, arch) |
|
||||
// Recursive case: Take previous field's end point, pad and add
|
||||
// this field's size
|
||||
exists(int firstFree | firstFree = fieldEnd(index - 1, arch) |
|
||||
exists(int firstFree | firstFree = this.fieldEnd(index - 1, arch) |
|
||||
if f instanceof BitField
|
||||
then
|
||||
// Bitfield packing:
|
||||
@@ -629,9 +634,11 @@ class PaddedType extends Class {
|
||||
// No additional restrictions, so just pack it in with no padding.
|
||||
result = firstFree + fSize
|
||||
) else (
|
||||
if exists(bitFieldAt(index - 1))
|
||||
if exists(this.bitFieldAt(index - 1))
|
||||
then
|
||||
exists(BitField previousBitField | previousBitField = bitFieldAt(index - 1) |
|
||||
exists(BitField previousBitField |
|
||||
previousBitField = this.bitFieldAt(index - 1)
|
||||
|
|
||||
// Previous field was a bitfield.
|
||||
if
|
||||
nextSizeofBoundary >= (firstFree + fSize) and
|
||||
|
||||
@@ -88,7 +88,7 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
|
||||
ControlFlowNode getDefinition() { result = this }
|
||||
|
||||
/** Gets the basic block containing this definition. */
|
||||
BasicBlock getBasicBlock() { result.contains(getDefinition()) }
|
||||
BasicBlock getBasicBlock() { result.contains(this.getDefinition()) }
|
||||
|
||||
/** Whether this definition is a phi node for variable `v`. */
|
||||
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }
|
||||
|
||||
@@ -127,17 +127,22 @@ private string getValue(Expr e) {
|
||||
private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
|
||||
UnsignedBitwiseAndExpr() {
|
||||
(
|
||||
getLeftOperand().getFullyConverted().getType().getUnderlyingType().(IntegralType).isUnsigned() or
|
||||
getValue(getLeftOperand().getFullyConverted()).toInt() >= 0
|
||||
) and
|
||||
(
|
||||
getRightOperand()
|
||||
this.getLeftOperand()
|
||||
.getFullyConverted()
|
||||
.getType()
|
||||
.getUnderlyingType()
|
||||
.(IntegralType)
|
||||
.isUnsigned() or
|
||||
getValue(getRightOperand().getFullyConverted()).toInt() >= 0
|
||||
getValue(this.getLeftOperand().getFullyConverted()).toInt() >= 0
|
||||
) and
|
||||
(
|
||||
this.getRightOperand()
|
||||
.getFullyConverted()
|
||||
.getType()
|
||||
.getUnderlyingType()
|
||||
.(IntegralType)
|
||||
.isUnsigned() or
|
||||
getValue(this.getRightOperand().getFullyConverted()).toInt() >= 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,21 +77,21 @@ abstract class BufferWrite extends Expr {
|
||||
* much smaller (8 bytes) than their true maximum length. This can be
|
||||
* helpful in determining the cause of a buffer overflow issue.
|
||||
*/
|
||||
int getMaxDataLimited() { result = getMaxData() }
|
||||
int getMaxDataLimited() { result = this.getMaxData() }
|
||||
|
||||
/**
|
||||
* Gets the size of a single character of the type this
|
||||
* operation works with, in bytes.
|
||||
*/
|
||||
int getCharSize() {
|
||||
result = getBufferType().(PointerType).getBaseType().getSize() or
|
||||
result = getBufferType().(ArrayType).getBaseType().getSize()
|
||||
result = this.getBufferType().(PointerType).getBaseType().getSize() or
|
||||
result = this.getBufferType().(ArrayType).getBaseType().getSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of this buffer write.
|
||||
*/
|
||||
string getBWDesc() { result = toString() }
|
||||
string getBWDesc() { result = this.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ abstract class BufferWriteCall extends BufferWrite, FunctionCall { }
|
||||
class StrCopyBW extends BufferWriteCall {
|
||||
StrcpyFunction f;
|
||||
|
||||
StrCopyBW() { getTarget() = f.(TopLevelFunction) }
|
||||
StrCopyBW() { this.getTarget() = f.(TopLevelFunction) }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the maximum size of the copy (in characters).
|
||||
@@ -122,21 +122,22 @@ class StrCopyBW extends BufferWriteCall {
|
||||
int getParamSrc() { result = f.getParamSrc() }
|
||||
|
||||
override Type getBufferType() {
|
||||
result = this.getTarget().getParameter(getParamSrc()).getUnspecifiedType()
|
||||
result = this.getTarget().getParameter(this.getParamSrc()).getUnspecifiedType()
|
||||
}
|
||||
|
||||
override Expr getASource() { result = getArgument(getParamSrc()) }
|
||||
override Expr getASource() { result = this.getArgument(this.getParamSrc()) }
|
||||
|
||||
override Expr getDest() { result = getArgument(f.getParamDest()) }
|
||||
override Expr getDest() { result = this.getArgument(f.getParamDest()) }
|
||||
|
||||
override predicate hasExplicitLimit() { exists(getParamSize()) }
|
||||
override predicate hasExplicitLimit() { exists(this.getParamSize()) }
|
||||
|
||||
override int getExplicitLimit() {
|
||||
result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
result = getArgument(getParamSrc()).(AnalysedString).getMaxLength() * getCharSize()
|
||||
result =
|
||||
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ class StrCopyBW extends BufferWriteCall {
|
||||
class StrCatBW extends BufferWriteCall {
|
||||
StrcatFunction f;
|
||||
|
||||
StrCatBW() { getTarget() = f.(TopLevelFunction) }
|
||||
StrCatBW() { this.getTarget() = f.(TopLevelFunction) }
|
||||
|
||||
/**
|
||||
* Gets the index of the parameter that is the maximum size of the copy (in characters).
|
||||
@@ -159,21 +160,22 @@ class StrCatBW extends BufferWriteCall {
|
||||
int getParamSrc() { result = f.getParamSrc() }
|
||||
|
||||
override Type getBufferType() {
|
||||
result = this.getTarget().getParameter(getParamSrc()).getUnspecifiedType()
|
||||
result = this.getTarget().getParameter(this.getParamSrc()).getUnspecifiedType()
|
||||
}
|
||||
|
||||
override Expr getASource() { result = getArgument(getParamSrc()) }
|
||||
override Expr getASource() { result = this.getArgument(this.getParamSrc()) }
|
||||
|
||||
override Expr getDest() { result = getArgument(f.getParamDest()) }
|
||||
override Expr getDest() { result = this.getArgument(f.getParamDest()) }
|
||||
|
||||
override predicate hasExplicitLimit() { exists(getParamSize()) }
|
||||
override predicate hasExplicitLimit() { exists(this.getParamSize()) }
|
||||
|
||||
override int getExplicitLimit() {
|
||||
result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
result = getArgument(getParamSrc()).(AnalysedString).getMaxLength() * getCharSize()
|
||||
result =
|
||||
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +186,7 @@ class SprintfBW extends BufferWriteCall {
|
||||
FormattingFunction f;
|
||||
|
||||
SprintfBW() {
|
||||
exists(string name | f = getTarget().(TopLevelFunction) and name = f.getName() |
|
||||
exists(string name | f = this.getTarget().(TopLevelFunction) and name = f.getName() |
|
||||
/*
|
||||
* C sprintf variants:
|
||||
*/
|
||||
@@ -229,19 +231,19 @@ class SprintfBW extends BufferWriteCall {
|
||||
result = this.(FormattingFunctionCall).getFormatArgument(_)
|
||||
}
|
||||
|
||||
override Expr getDest() { result = getArgument(f.getOutputParameterIndex(false)) }
|
||||
override Expr getDest() { result = this.getArgument(f.getOutputParameterIndex(false)) }
|
||||
|
||||
override int getMaxData() {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLength() * getCharSize()
|
||||
result = fl.getMaxConvertedLength() * this.getCharSize()
|
||||
)
|
||||
}
|
||||
|
||||
override int getMaxDataLimited() {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLengthLimited() * getCharSize()
|
||||
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -251,7 +253,7 @@ class SprintfBW extends BufferWriteCall {
|
||||
*/
|
||||
class SnprintfBW extends BufferWriteCall {
|
||||
SnprintfBW() {
|
||||
exists(TopLevelFunction fn, string name | fn = getTarget() and name = fn.getName() |
|
||||
exists(TopLevelFunction fn, string name | fn = this.getTarget() and name = fn.getName() |
|
||||
/*
|
||||
* C snprintf variants:
|
||||
*/
|
||||
@@ -326,25 +328,25 @@ class SnprintfBW extends BufferWriteCall {
|
||||
result = this.(FormattingFunctionCall).getFormatArgument(_)
|
||||
}
|
||||
|
||||
override Expr getDest() { result = getArgument(0) }
|
||||
override Expr getDest() { result = this.getArgument(0) }
|
||||
|
||||
override predicate hasExplicitLimit() { exists(getParamSize()) }
|
||||
override predicate hasExplicitLimit() { exists(this.getParamSize()) }
|
||||
|
||||
override int getExplicitLimit() {
|
||||
result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLength() * getCharSize()
|
||||
result = fl.getMaxConvertedLength() * this.getCharSize()
|
||||
)
|
||||
}
|
||||
|
||||
override int getMaxDataLimited() {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLengthLimited() * getCharSize()
|
||||
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -354,7 +356,7 @@ class SnprintfBW extends BufferWriteCall {
|
||||
*/
|
||||
class GetsBW extends BufferWriteCall {
|
||||
GetsBW() {
|
||||
getTarget().(TopLevelFunction).getName() =
|
||||
this.getTarget().(TopLevelFunction).getName() =
|
||||
[
|
||||
"gets", // gets(dst)
|
||||
"fgets", // fgets(dst, max_amount, src_stream)
|
||||
@@ -365,24 +367,24 @@ class GetsBW extends BufferWriteCall {
|
||||
/**
|
||||
* Gets the index of the parameter that is the maximum number of characters to be read.
|
||||
*/
|
||||
int getParamSize() { exists(getArgument(1)) and result = 1 }
|
||||
int getParamSize() { exists(this.getArgument(1)) and result = 1 }
|
||||
|
||||
override Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }
|
||||
|
||||
override Expr getASource() {
|
||||
if exists(getArgument(2))
|
||||
then result = getArgument(2)
|
||||
if exists(this.getArgument(2))
|
||||
then result = this.getArgument(2)
|
||||
else
|
||||
// the source is input inside the 'gets' call itself
|
||||
result = this
|
||||
}
|
||||
|
||||
override Expr getDest() { result = getArgument(0) }
|
||||
override Expr getDest() { result = this.getArgument(0) }
|
||||
|
||||
override predicate hasExplicitLimit() { exists(getParamSize()) }
|
||||
override predicate hasExplicitLimit() { exists(this.getParamSize()) }
|
||||
|
||||
override int getExplicitLimit() {
|
||||
result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +440,7 @@ class ScanfBW extends BufferWrite {
|
||||
exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
|
||||
this = fc.getArgument(arg) and
|
||||
fl = fc.getFormat() and
|
||||
result = (fl.getMaxConvertedLength(arg - getParamArgs()) + 1) * getCharSize() // +1 is for the terminating null
|
||||
result = (fl.getMaxConvertedLength(arg - this.getParamArgs()) + 1) * this.getCharSize() // +1 is for the terminating null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -463,14 +465,14 @@ private int path_max() {
|
||||
class RealpathBW extends BufferWriteCall {
|
||||
RealpathBW() {
|
||||
exists(path_max()) and // Ignore realpath() calls if PATH_MAX cannot be determined
|
||||
getTarget().hasGlobalName("realpath") // realpath(path, resolved_path);
|
||||
this.getTarget().hasGlobalName("realpath") // realpath(path, resolved_path);
|
||||
}
|
||||
|
||||
override Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }
|
||||
|
||||
override Expr getDest() { result = getArgument(1) }
|
||||
override Expr getDest() { result = this.getArgument(1) }
|
||||
|
||||
override Expr getASource() { result = getArgument(0) }
|
||||
override Expr getASource() { result = this.getArgument(0) }
|
||||
|
||||
override int getMaxData() {
|
||||
result = path_max() and
|
||||
|
||||
@@ -52,9 +52,9 @@ class BasicOStreamClass extends Type {
|
||||
*/
|
||||
class BasicOStreamCall extends FunctionCall {
|
||||
BasicOStreamCall() {
|
||||
if getTarget() instanceof MemberFunction
|
||||
then getQualifier().getType() instanceof BasicOStreamClass
|
||||
else getArgument(0).getType() instanceof BasicOStreamClass
|
||||
if this.getTarget() instanceof MemberFunction
|
||||
then this.getQualifier().getType() instanceof BasicOStreamClass
|
||||
else this.getArgument(0).getType() instanceof BasicOStreamClass
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,10 +77,10 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
|
||||
*/
|
||||
Expr getEndDest() {
|
||||
// recurse into the destination
|
||||
result = getDest().(ChainedOutputCall).getEndDest()
|
||||
result = this.getDest().(ChainedOutputCall).getEndDest()
|
||||
or
|
||||
// or return something other than a ChainedOutputCall
|
||||
result = getDest() and
|
||||
result = this.getDest() and
|
||||
not result instanceof ChainedOutputCall
|
||||
}
|
||||
}
|
||||
@@ -89,18 +89,18 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
|
||||
* A call to `operator<<` on an output stream.
|
||||
*/
|
||||
class OperatorLShiftCall extends ChainedOutputCall {
|
||||
OperatorLShiftCall() { getTarget().(Operator).hasName("operator<<") }
|
||||
OperatorLShiftCall() { this.getTarget().(Operator).hasName("operator<<") }
|
||||
|
||||
override Expr getSource() {
|
||||
if getTarget() instanceof MemberFunction
|
||||
then result = getArgument(0)
|
||||
else result = getArgument(1)
|
||||
if this.getTarget() instanceof MemberFunction
|
||||
then result = this.getArgument(0)
|
||||
else result = this.getArgument(1)
|
||||
}
|
||||
|
||||
override Expr getDest() {
|
||||
if getTarget() instanceof MemberFunction
|
||||
then result = getQualifier()
|
||||
else result = getArgument(0)
|
||||
if this.getTarget() instanceof MemberFunction
|
||||
then result = this.getQualifier()
|
||||
else result = this.getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,22 +108,22 @@ class OperatorLShiftCall extends ChainedOutputCall {
|
||||
* A call to 'put'.
|
||||
*/
|
||||
class PutFunctionCall extends ChainedOutputCall {
|
||||
PutFunctionCall() { getTarget().(MemberFunction).hasName("put") }
|
||||
PutFunctionCall() { this.getTarget().(MemberFunction).hasName("put") }
|
||||
|
||||
override Expr getSource() { result = getArgument(0) }
|
||||
override Expr getSource() { result = this.getArgument(0) }
|
||||
|
||||
override Expr getDest() { result = getQualifier() }
|
||||
override Expr getDest() { result = this.getQualifier() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to 'write'.
|
||||
*/
|
||||
class WriteFunctionCall extends ChainedOutputCall {
|
||||
WriteFunctionCall() { getTarget().(MemberFunction).hasName("write") }
|
||||
WriteFunctionCall() { this.getTarget().(MemberFunction).hasName("write") }
|
||||
|
||||
override Expr getSource() { result = getArgument(0) }
|
||||
override Expr getSource() { result = this.getArgument(0) }
|
||||
|
||||
override Expr getDest() { result = getQualifier() }
|
||||
override Expr getDest() { result = this.getQualifier() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ private class RemoteReturnSource extends RemoteFlowSource {
|
||||
|
||||
RemoteReturnSource() {
|
||||
exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
this.asInstruction() = instr and
|
||||
instr.getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
(
|
||||
@@ -43,7 +43,7 @@ private class RemoteParameterSource extends RemoteFlowSource {
|
||||
|
||||
RemoteParameterSource() {
|
||||
exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
this.asInstruction() = instr and
|
||||
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
output.isParameterDerefOrQualifierObject(instr.getIndex())
|
||||
@@ -58,7 +58,7 @@ private class LocalReturnSource extends LocalFlowSource {
|
||||
|
||||
LocalReturnSource() {
|
||||
exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
this.asInstruction() = instr and
|
||||
instr.getStaticCallTarget() = func and
|
||||
func.hasLocalFlowSource(output, sourceType) and
|
||||
(
|
||||
@@ -77,7 +77,7 @@ private class LocalParameterSource extends LocalFlowSource {
|
||||
|
||||
LocalParameterSource() {
|
||||
exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
|
||||
asInstruction() = instr and
|
||||
this.asInstruction() = instr and
|
||||
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
|
||||
func.hasLocalFlowSource(output, sourceType) and
|
||||
output.isParameterDerefOrQualifierObject(instr.getIndex())
|
||||
|
||||
@@ -77,7 +77,7 @@ abstract class FunctionWithWrappers extends Function {
|
||||
) {
|
||||
// base case
|
||||
func = this and
|
||||
interestingArg(paramIndex) and
|
||||
this.interestingArg(paramIndex) and
|
||||
callChain = toCause(func, paramIndex) and
|
||||
depth = 0
|
||||
or
|
||||
@@ -101,7 +101,7 @@ abstract class FunctionWithWrappers extends Function {
|
||||
private predicate wrapperFunctionAnyDepth(Function func, int paramIndex, string cause) {
|
||||
// base case
|
||||
func = this and
|
||||
interestingArg(paramIndex) and
|
||||
this.interestingArg(paramIndex) and
|
||||
cause = toCause(func, paramIndex)
|
||||
or
|
||||
// recursive step
|
||||
@@ -147,7 +147,7 @@ abstract class FunctionWithWrappers extends Function {
|
||||
)
|
||||
or
|
||||
not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and
|
||||
cause = wrapperFunctionAnyDepthUnique(func, paramIndex)
|
||||
cause = this.wrapperFunctionAnyDepthUnique(func, paramIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,7 +78,7 @@ class SecurityOptions extends string {
|
||||
functionCall.getTarget().getName() = fname and
|
||||
(
|
||||
fname = ["fgets", "gets"] or
|
||||
userInputReturn(fname)
|
||||
this.userInputReturn(fname)
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -29,7 +29,7 @@ private predicate suspicious(string s) {
|
||||
*/
|
||||
class SensitiveVariable extends Variable {
|
||||
SensitiveVariable() {
|
||||
suspicious(getName().toLowerCase()) and
|
||||
suspicious(this.getName().toLowerCase()) and
|
||||
not this.getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class SensitiveVariable extends Variable {
|
||||
*/
|
||||
class SensitiveFunction extends Function {
|
||||
SensitiveFunction() {
|
||||
suspicious(getName().toLowerCase()) and
|
||||
suspicious(this.getName().toLowerCase()) and
|
||||
not this.getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ module BoostorgAsio {
|
||||
result.getName() = "tls_server"
|
||||
)
|
||||
or
|
||||
result = getASslv23ProtocolConstant()
|
||||
result = this.getASslv23ProtocolConstant()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,9 +76,9 @@ class BlockStmt extends Stmt, @stmt_block {
|
||||
* the result is the expression statement `a = b`.
|
||||
*/
|
||||
Stmt getLastStmtIn() {
|
||||
if getLastStmt() instanceof BlockStmt
|
||||
then result = getLastStmt().(BlockStmt).getLastStmtIn()
|
||||
else result = getLastStmt()
|
||||
if this.getLastStmt() instanceof BlockStmt
|
||||
then result = this.getLastStmt().(BlockStmt).getLastStmtIn()
|
||||
else result = this.getLastStmt()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,10 +27,10 @@ class Stmt extends StmtParent, @stmt {
|
||||
*/
|
||||
BlockStmt getEnclosingBlock() {
|
||||
if
|
||||
getParentStmt() instanceof BlockStmt and
|
||||
not getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation
|
||||
then result = getParentStmt()
|
||||
else result = getParentStmt().getEnclosingBlock()
|
||||
this.getParentStmt() instanceof BlockStmt and
|
||||
not this.getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation
|
||||
then result = this.getParentStmt()
|
||||
else result = this.getParentStmt().getEnclosingBlock()
|
||||
}
|
||||
|
||||
/** Gets a child of this statement. */
|
||||
@@ -438,7 +438,7 @@ class WhileStmt extends Loop, @stmt_while {
|
||||
* while(1) { ...; if(b) break; ...; }
|
||||
* ```
|
||||
*/
|
||||
predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) }
|
||||
predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
|
||||
|
||||
/**
|
||||
* Holds if the loop condition is provably `false`.
|
||||
@@ -448,7 +448,7 @@ class WhileStmt extends Loop, @stmt_while {
|
||||
* while(0) { ...; }
|
||||
* ```
|
||||
*/
|
||||
predicate conditionAlwaysFalse() { conditionAlwaysFalse(getCondition()) }
|
||||
predicate conditionAlwaysFalse() { conditionAlwaysFalse(this.getCondition()) }
|
||||
|
||||
/**
|
||||
* Holds if the loop condition is provably `true` upon entry,
|
||||
@@ -857,7 +857,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
||||
* ```
|
||||
* the result is `int x`.
|
||||
*/
|
||||
LocalVariable getVariable() { result = getChild(4).(DeclStmt).getADeclaration() }
|
||||
LocalVariable getVariable() { result = this.getChild(4).(DeclStmt).getADeclaration() }
|
||||
|
||||
/**
|
||||
* Gets the expression giving the range to iterate over.
|
||||
@@ -868,10 +868,10 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
||||
* ```
|
||||
* the result is `xs`.
|
||||
*/
|
||||
Expr getRange() { result = getRangeVariable().getInitializer().getExpr() }
|
||||
Expr getRange() { result = this.getRangeVariable().getInitializer().getExpr() }
|
||||
|
||||
/** Gets the compiler-generated `__range` variable after desugaring. */
|
||||
LocalVariable getRangeVariable() { result = getChild(0).(DeclStmt).getADeclaration() }
|
||||
LocalVariable getRangeVariable() { result = this.getChild(0).(DeclStmt).getADeclaration() }
|
||||
|
||||
/**
|
||||
* Gets the compiler-generated `__begin != __end` which is the
|
||||
@@ -891,10 +891,10 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
||||
DeclStmt getBeginEndDeclaration() { result = this.getChild(1) }
|
||||
|
||||
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
||||
LocalVariable getBeginVariable() { result = getBeginEndDeclaration().getDeclaration(0) }
|
||||
LocalVariable getBeginVariable() { result = this.getBeginEndDeclaration().getDeclaration(0) }
|
||||
|
||||
/** Gets the compiler-generated `__end` variable after desugaring. */
|
||||
LocalVariable getEndVariable() { result = getBeginEndDeclaration().getDeclaration(1) }
|
||||
LocalVariable getEndVariable() { result = this.getBeginEndDeclaration().getDeclaration(1) }
|
||||
|
||||
/**
|
||||
* Gets the compiler-generated `++__begin` which is the update
|
||||
@@ -905,7 +905,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
||||
Expr getUpdate() { result = this.getChild(3) }
|
||||
|
||||
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
||||
LocalVariable getAnIterationVariable() { result = getBeginVariable() }
|
||||
LocalVariable getAnIterationVariable() { result = this.getBeginVariable() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1067,7 +1067,7 @@ class ForStmt extends Loop, @stmt_for {
|
||||
* for(x = 0; 1; ++x) { sum += x; }
|
||||
* ```
|
||||
*/
|
||||
predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) }
|
||||
predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
|
||||
|
||||
/**
|
||||
* Holds if the loop condition is provably `false`.
|
||||
@@ -1077,7 +1077,7 @@ class ForStmt extends Loop, @stmt_for {
|
||||
* for(x = 0; 0; ++x) { sum += x; }
|
||||
* ```
|
||||
*/
|
||||
predicate conditionAlwaysFalse() { conditionAlwaysFalse(getCondition()) }
|
||||
predicate conditionAlwaysFalse() { conditionAlwaysFalse(this.getCondition()) }
|
||||
|
||||
/**
|
||||
* Holds if the loop condition is provably `true` upon entry,
|
||||
@@ -1723,10 +1723,10 @@ class Handler extends Stmt, @stmt_handler {
|
||||
/**
|
||||
* Gets the block containing the implementation of this handler.
|
||||
*/
|
||||
CatchBlock getBlock() { result = getChild(0) }
|
||||
CatchBlock getBlock() { result = this.getChild(0) }
|
||||
|
||||
/** Gets the 'try' statement corresponding to this 'catch block'. */
|
||||
TryStmt getTryStmt() { result = getParent() }
|
||||
TryStmt getTryStmt() { result = this.getParent() }
|
||||
|
||||
/**
|
||||
* Gets the parameter introduced by this 'catch block', if any.
|
||||
@@ -1734,7 +1734,7 @@ class Handler extends Stmt, @stmt_handler {
|
||||
* For example, `catch(std::exception& e)` introduces a
|
||||
* parameter `e`, whereas `catch(...)` does not introduce a parameter.
|
||||
*/
|
||||
Parameter getParameter() { result = getBlock().getParameter() }
|
||||
Parameter getParameter() { result = this.getBlock().getParameter() }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
@@ -1921,15 +1921,15 @@ class MicrosoftTryStmt extends Stmt, @stmt_microsoft_try {
|
||||
* This is a Microsoft C/C++ extension.
|
||||
*/
|
||||
class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
|
||||
MicrosoftTryExceptStmt() { getChild(1) instanceof Expr }
|
||||
MicrosoftTryExceptStmt() { this.getChild(1) instanceof Expr }
|
||||
|
||||
override string toString() { result = "__try { ... } __except( ... ) { ... }" }
|
||||
|
||||
/** Gets the expression guarding the `__except` statement. */
|
||||
Expr getCondition() { result = getChild(1) }
|
||||
Expr getCondition() { result = this.getChild(1) }
|
||||
|
||||
/** Gets the `__except` statement (usually a `BlockStmt`). */
|
||||
Stmt getExcept() { result = getChild(2) }
|
||||
Stmt getExcept() { result = this.getChild(2) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" }
|
||||
}
|
||||
@@ -1948,12 +1948,12 @@ class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
|
||||
* This is a Microsoft C/C++ extension.
|
||||
*/
|
||||
class MicrosoftTryFinallyStmt extends MicrosoftTryStmt {
|
||||
MicrosoftTryFinallyStmt() { not getChild(1) instanceof Expr }
|
||||
MicrosoftTryFinallyStmt() { not this.getChild(1) instanceof Expr }
|
||||
|
||||
override string toString() { result = "__try { ... } __finally { ... }" }
|
||||
|
||||
/** Gets the `__finally` statement (usually a `BlockStmt`). */
|
||||
Stmt getFinally() { result = getChild(1) }
|
||||
Stmt getFinally() { result = this.getChild(1) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" }
|
||||
}
|
||||
|
||||
@@ -68,12 +68,12 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
|
||||
/**
|
||||
* Gets the start column of the first `VariableDeclarationEntry` on this line.
|
||||
*/
|
||||
int getStartColumn() { result = min(getAVDE().getLocation().getStartColumn()) }
|
||||
int getStartColumn() { result = min(this.getAVDE().getLocation().getStartColumn()) }
|
||||
|
||||
/**
|
||||
* Gets the end column of the last `VariableDeclarationEntry` on this line.
|
||||
*/
|
||||
int getEndColumn() { result = max(getAVDE().getLocation().getEndColumn()) }
|
||||
int getEndColumn() { result = max(this.getAVDE().getLocation().getEndColumn()) }
|
||||
|
||||
/**
|
||||
* Gets the rank of this `VariableDeclarationLine` in its file and class
|
||||
@@ -89,14 +89,14 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
|
||||
*/
|
||||
VariableDeclarationLine getNext() {
|
||||
result = TVariableDeclarationLine(c, f, _) and
|
||||
result.getRank() = getRank() + 1
|
||||
result.getRank() = this.getRank() + 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `VariableDeclarationLine` following this one, if it is nearby.
|
||||
*/
|
||||
VariableDeclarationLine getProximateNext() {
|
||||
result = getNext() and
|
||||
result = this.getNext() and
|
||||
result.getLine() <= this.getLine() + 3
|
||||
}
|
||||
|
||||
@@ -114,14 +114,14 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
|
||||
// there is no `VariableDeclarationLine` within three lines previously
|
||||
not any(VariableDeclarationLine prev).getProximateNext() = this and
|
||||
// `end` is the last transitively proximate line
|
||||
end = getProximateNext*() and
|
||||
end = this.getProximateNext*() and
|
||||
not exists(end.getProximateNext())
|
||||
}
|
||||
|
||||
predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) {
|
||||
path = f.getAbsolutePath() and
|
||||
startline = getLine() and
|
||||
startcol = getStartColumn() and
|
||||
startline = this.getLine() and
|
||||
startcol = this.getStartColumn() and
|
||||
endline = end.getLine() and
|
||||
endcol = end.getEndColumn()
|
||||
}
|
||||
@@ -132,18 +132,18 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
|
||||
int getCount() {
|
||||
result =
|
||||
count(VariableDeclarationLine l |
|
||||
l = getProximateNext*()
|
||||
l = this.getProximateNext*()
|
||||
|
|
||||
l.getAVDE().getVariable().getName()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
getCount() = 1 and
|
||||
result = "declaration of " + getAVDE().getVariable().getName()
|
||||
this.getCount() = 1 and
|
||||
result = "declaration of " + this.getAVDE().getVariable().getName()
|
||||
or
|
||||
getCount() > 1 and
|
||||
result = "group of " + getCount() + " fields here"
|
||||
this.getCount() > 1 and
|
||||
result = "group of " + this.getCount() + " fields here"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class SemaphoreTake extends LockOperation {
|
||||
result.(SemaphoreGive).getLocked() = this.getLocked()
|
||||
}
|
||||
|
||||
override string say() { result = "semaphore take of " + getLocked().getName() }
|
||||
override string say() { result = "semaphore take of " + this.getLocked().getName() }
|
||||
}
|
||||
|
||||
class SemaphoreGive extends UnlockOperation {
|
||||
@@ -76,13 +76,13 @@ class LockingPrimitive extends FunctionCall, LockOperation {
|
||||
this.getTarget().getName().replaceAll("Lock", "Unlock")
|
||||
}
|
||||
|
||||
override string say() { result = "call to " + getLocked().getName() }
|
||||
override string say() { result = "call to " + this.getLocked().getName() }
|
||||
}
|
||||
|
||||
class UnlockingPrimitive extends FunctionCall, UnlockOperation {
|
||||
UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] }
|
||||
|
||||
Function getLocked() { result = getMatchingLock().getLocked() }
|
||||
Function getLocked() { result = this.getMatchingLock().getLocked() }
|
||||
|
||||
override LockOperation getMatchingLock() { this = result.getMatchingUnlock() }
|
||||
}
|
||||
|
||||
20
cpp/ql/src/external/CodeDuplication.qll
vendored
20
cpp/ql/src/external/CodeDuplication.qll
vendored
@@ -38,10 +38,10 @@ class Copy extends @duplication_or_similarity {
|
||||
int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
|
||||
|
||||
/** Gets the line on which the last token in this block ends. */
|
||||
int sourceEndLine() { tokens(this, lastToken(), _, _, result, _) }
|
||||
int sourceEndLine() { tokens(this, this.lastToken(), _, _, result, _) }
|
||||
|
||||
/** Gets the column on which the last token in this block ends. */
|
||||
int sourceEndColumn() { tokens(this, lastToken(), _, _, _, result) }
|
||||
int sourceEndColumn() { tokens(this, this.lastToken(), _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines containing at least (part of) one token in this block. */
|
||||
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
|
||||
@@ -66,11 +66,11 @@ class Copy extends @duplication_or_similarity {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
sourceFile().getAbsolutePath() = filepath and
|
||||
startline = sourceStartLine() and
|
||||
startcolumn = sourceStartColumn() and
|
||||
endline = sourceEndLine() and
|
||||
endcolumn = sourceEndColumn()
|
||||
this.sourceFile().getAbsolutePath() = filepath and
|
||||
startline = this.sourceStartLine() and
|
||||
startcolumn = this.sourceStartColumn() and
|
||||
endline = this.sourceEndLine() and
|
||||
endcolumn = this.sourceEndColumn()
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
@@ -79,13 +79,15 @@ class Copy extends @duplication_or_similarity {
|
||||
|
||||
/** A block of duplicated code. */
|
||||
class DuplicateBlock extends Copy, @duplication {
|
||||
override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." }
|
||||
override string toString() {
|
||||
result = "Duplicate code: " + this.sourceLines() + " duplicated lines."
|
||||
}
|
||||
}
|
||||
|
||||
/** A block of similar code. */
|
||||
class SimilarBlock extends Copy, @similarity {
|
||||
override string toString() {
|
||||
result = "Similar code: " + sourceLines() + " almost duplicated lines."
|
||||
result = "Similar code: " + this.sourceLines() + " almost duplicated lines."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
cpp/ql/src/external/MetricFilter.qll
vendored
4
cpp/ql/src/external/MetricFilter.qll
vendored
@@ -67,7 +67,7 @@ class MetricResult extends int {
|
||||
/** Gets the URL corresponding to the location of this query result. */
|
||||
string getURL() {
|
||||
result =
|
||||
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
|
||||
getEndLine() + ":" + getEndColumn()
|
||||
"file://" + this.getFile().getAbsolutePath() + ":" + this.getStartLine() + ":" +
|
||||
this.getStartColumn() + ":" + this.getEndLine() + ":" + this.getEndColumn()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user