C++: fix implicit this

This commit is contained in:
Erik Krogh Kristensen
2021-10-14 09:49:53 +02:00
committed by Mathias Vorreiter Pedersen
parent b2e4276bc8
commit fe891746bf
97 changed files with 1739 additions and 1571 deletions

View File

@@ -15,7 +15,7 @@ class ExternalData extends @externalDataElement {
* Gets the path of the file this data was loaded from, with its * Gets the path of the file this data was loaded from, with its
* extension replaced by `.ql`. * 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. */ /** Gets the number of fields in this data item. */
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) } 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) } string getField(int i) { externalData(this, _, i, result) }
/** Gets the integer value of the `i`th field of this data item. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** Gets a textual representation of this data item, starting with the `n`th field. */
private string buildTupleString(int n) { private string buildTupleString(int n) {
n = getNumFields() - 1 and result = getField(n) n = this.getNumFields() - 1 and result = this.getField(n)
or 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. */ /** 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. */ /** Gets the message associated with this data item. */
string getMessage() { result = getField(1) } string getMessage() { result = this.getField(1) }
} }

View File

@@ -269,13 +269,13 @@ class Class extends UserType {
* DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that * DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that
* `= default` members are no longer included. * `= default` members are no longer included.
*/ */
deprecated predicate hasGeneratedCopyConstructor() { hasImplicitCopyConstructor() } deprecated predicate hasGeneratedCopyConstructor() { this.hasImplicitCopyConstructor() }
/** /**
* DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to * DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to
* reflect that `= default` members are no longer included. * 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 * Holds if this class, struct or union has an implicitly-declared copy
@@ -487,7 +487,7 @@ class Class extends UserType {
exists(ClassDerivation cd | exists(ClassDerivation cd |
// Add the offset of the direct base class and the offset of `baseClass` // Add the offset of the direct base class and the offset of `baseClass`
// within that direct base class. // within that direct base class.
cd = getADerivation() and cd = this.getADerivation() and
result = cd.getBaseClass().getANonVirtualBaseClassByteOffset(baseClass) + cd.getByteOffset() result = cd.getBaseClass().getANonVirtualBaseClassByteOffset(baseClass) + cd.getByteOffset()
) )
} }
@@ -502,12 +502,12 @@ class Class extends UserType {
*/ */
int getABaseClassByteOffset(Class baseClass) { int getABaseClassByteOffset(Class baseClass) {
// Handle the non-virtual case. // Handle the non-virtual case.
result = getANonVirtualBaseClassByteOffset(baseClass) result = this.getANonVirtualBaseClassByteOffset(baseClass)
or or
exists(Class virtualBaseClass, int virtualBaseOffset, int offsetFromVirtualBase | exists(Class virtualBaseClass, int virtualBaseOffset, int offsetFromVirtualBase |
// Look for the base class as a non-virtual base of a direct or indirect // Look for the base class as a non-virtual base of a direct or indirect
// virtual base, adding the two offsets. // virtual base, adding the two offsets.
getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and this.getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and
offsetFromVirtualBase = virtualBaseClass.getANonVirtualBaseClassByteOffset(baseClass) and offsetFromVirtualBase = virtualBaseClass.getANonVirtualBaseClassByteOffset(baseClass) and
result = virtualBaseOffset + offsetFromVirtualBase result = virtualBaseOffset + offsetFromVirtualBase
) )
@@ -623,11 +623,11 @@ class Class extends UserType {
* inherits one). * inherits one).
*/ */
predicate isPolymorphic() { predicate isPolymorphic() {
exists(MemberFunction f | f.getDeclaringType() = getABaseClass*() and f.isVirtual()) exists(MemberFunction f | f.getDeclaringType() = this.getABaseClass*() and f.isVirtual())
} }
override predicate involvesTemplateParameter() { override predicate involvesTemplateParameter() {
getATemplateArgument().(Type).involvesTemplateParameter() this.getATemplateArgument().(Type).involvesTemplateParameter()
} }
/** Holds if this class, struct or union was declared 'final'. */ /** 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" } override string getAPrimaryQlClass() { result = "ClassDerivation" }
@@ -818,7 +818,7 @@ class ClassDerivation extends Locatable, @derivation {
predicate hasSpecifier(string s) { this.getASpecifier().hasName(s) } predicate hasSpecifier(string s) { this.getASpecifier().hasName(s) }
/** Holds if the derivation is for a virtual base class. */ /** 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. */ /** Gets the location of the derivation. */
override Location getLocation() { derivations(underlyingElement(this), _, _, _, result) } override Location getLocation() { derivations(underlyingElement(this), _, _, _, result) }
@@ -846,7 +846,7 @@ class ClassDerivation extends Locatable, @derivation {
* ``` * ```
*/ */
class LocalClass extends Class { class LocalClass extends Class {
LocalClass() { isLocal() } LocalClass() { this.isLocal() }
override string getAPrimaryQlClass() { not this instanceof LocalStruct and result = "LocalClass" } override string getAPrimaryQlClass() { not this instanceof LocalStruct and result = "LocalClass" }
@@ -989,9 +989,9 @@ class ClassTemplateSpecialization extends Class {
TemplateClass getPrimaryTemplate() { TemplateClass getPrimaryTemplate() {
// Ignoring template arguments, the primary template has the same name // Ignoring template arguments, the primary template has the same name
// as each of its specializations. // as each of its specializations.
result.getSimpleName() = getSimpleName() and result.getSimpleName() = this.getSimpleName() and
// It is in the same namespace as its specializations. // 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 // It is distinguished by the fact that each of its template arguments
// is a distinct template parameter. // is a distinct template parameter.
count(TemplateParameter tp | tp = result.getATemplateArgument()) = count(TemplateParameter tp | tp = result.getATemplateArgument()) =
@@ -1108,7 +1108,7 @@ deprecated class Interface extends Class {
* ``` * ```
*/ */
class VirtualClassDerivation extends ClassDerivation { class VirtualClassDerivation extends ClassDerivation {
VirtualClassDerivation() { hasSpecifier("virtual") } VirtualClassDerivation() { this.hasSpecifier("virtual") }
override string getAPrimaryQlClass() { result = "VirtualClassDerivation" } override string getAPrimaryQlClass() { result = "VirtualClassDerivation" }
} }
@@ -1136,7 +1136,7 @@ class VirtualBaseClass extends Class {
VirtualClassDerivation getAVirtualDerivation() { result.getBaseClass() = this } VirtualClassDerivation getAVirtualDerivation() { result.getBaseClass() = this }
/** A class/struct that is derived from this one using virtual inheritance. */ /** 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" } override string getAPrimaryQlClass() { result = "ProxyClass" }
/** Gets the location of the proxy class. */ /** 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. */ /** Gets the template parameter for which this is the proxy class. */
TemplateParameter getTemplateParameter() { TemplateParameter getTemplateParameter() {

View File

@@ -184,7 +184,7 @@ class Declaration extends Locatable, @declaration {
predicate hasDefinition() { exists(this.getDefinition()) } predicate hasDefinition() { exists(this.getDefinition()) }
/** DEPRECATED: Use `hasDefinition` instead. */ /** DEPRECATED: Use `hasDefinition` instead. */
predicate isDefined() { hasDefinition() } predicate isDefined() { this.hasDefinition() }
/** Gets the preferred location of this declaration, if any. */ /** Gets the preferred location of this declaration, if any. */
override Location getLocation() { none() } override Location getLocation() { none() }
@@ -209,7 +209,7 @@ class Declaration extends Locatable, @declaration {
predicate isStatic() { this.hasSpecifier("static") } predicate isStatic() { this.hasSpecifier("static") }
/** Holds if this declaration is a member of a class/struct/union. */ /** 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. */ /** Holds if this declaration is a member of a class/struct/union. */
predicate hasDeclaringType() { exists(this.getDeclaringType()) } 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 * When called on a template, this will return a template parameter type for
* both typed and non-typed parameters. * 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. * Gets a template argument used to instantiate this declaration from a template.
* When called on a template, this will return a non-typed template * When called on a template, this will return a non-typed template
* parameter value. * 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 * 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`. * `getTemplateArgument(1)` return `1`.
*/ */
final Locatable getTemplateArgument(int index) { final Locatable getTemplateArgument(int index) {
if exists(getTemplateArgumentValue(index)) if exists(this.getTemplateArgumentValue(index))
then result = getTemplateArgumentValue(index) then result = this.getTemplateArgumentValue(index)
else result = getTemplateArgumentType(index) else result = this.getTemplateArgumentType(index)
} }
/** /**
@@ -275,13 +275,13 @@ class Declaration extends Locatable, @declaration {
* `getTemplateArgumentKind(0)`. * `getTemplateArgumentKind(0)`.
*/ */
final Locatable getTemplateArgumentKind(int index) { final Locatable getTemplateArgumentKind(int index) {
exists(getTemplateArgumentValue(index)) and exists(this.getTemplateArgumentValue(index)) and
result = getTemplateArgumentType(index) result = this.getTemplateArgumentType(index)
} }
/** Gets the number of template arguments for this declaration. */ /** Gets the number of template arguments for this declaration. */
final int getNumberOfTemplateArguments() { final int getNumberOfTemplateArguments() {
result = count(int i | exists(getTemplateArgument(i))) result = count(int i | exists(this.getTemplateArgument(i)))
} }
private Type getTemplateArgumentType(int index) { private Type getTemplateArgumentType(int index) {
@@ -327,9 +327,9 @@ class DeclarationEntry extends Locatable, TDeclarationEntry {
* available), or the name declared by this entry otherwise. * available), or the name declared by this entry otherwise.
*/ */
string getCanonicalName() { string getCanonicalName() {
if getDeclaration().hasDefinition() if this.getDeclaration().hasDefinition()
then result = getDeclaration().getDefinition().getName() then result = this.getDeclaration().getDefinition().getName()
else result = 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. * 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. */ /** Holds if this declaration entry is a definition. */
predicate isDefinition() { none() } // overridden in subclasses predicate isDefinition() { none() } // overridden in subclasses
override string toString() { override string toString() {
if isDefinition() if this.isDefinition()
then result = "definition of " + getName() then result = "definition of " + this.getName()
else else
if getName() = getCanonicalName() if this.getName() = this.getCanonicalName()
then result = "declaration of " + getName() then result = "declaration of " + this.getName()
else result = "declaration of " + getCanonicalName() + " as " + 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. // transitive closure with a restricted base case.
this.thisCanAccessClassStep(base, derived) this.thisCanAccessClassStep(base, derived)
or or
exists(Class between | thisCanAccessClassTrans(base, between) | exists(Class between | this.thisCanAccessClassTrans(base, between) |
isDirectPublicBaseOf(between, derived) or isDirectPublicBaseOf(between, derived) or
this.thisCanAccessClassStep(between, derived) this.thisCanAccessClassStep(between, derived)
) )

View File

@@ -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. * 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. * 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. */ /** Gets the closest `Element` enclosing this one. */
cached cached
Element getEnclosingElement() { Element getEnclosingElement() {
result = getEnclosingElementPref() result = this.getEnclosingElementPref()
or or
not exists(getEnclosingElementPref()) and not exists(this.getEnclosingElementPref()) and
( (
this = result.(Class).getAMember() this = result.(Class).getAMember()
or or
@@ -281,7 +281,7 @@ private predicate isFromUninstantiatedTemplateRec(Element e, Element template) {
* ``` * ```
*/ */
class StaticAssert extends Locatable, @static_assert { 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. * Gets the expression which this static assertion ensures is true.

View File

@@ -85,7 +85,7 @@ class Enum extends UserType, IntegralOrEnumType {
* ``` * ```
*/ */
class LocalEnum extends Enum { class LocalEnum extends Enum {
LocalEnum() { isLocal() } LocalEnum() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalEnum" } override string getAPrimaryQlClass() { result = "LocalEnum" }
} }

View File

@@ -52,7 +52,7 @@ class Container extends Locatable, @container {
*/ */
string getRelativePath() { string getRelativePath() {
exists(string absPath, string pref | exists(string absPath, string pref |
absPath = getAbsolutePath() and sourceLocationPrefix(pref) absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
| |
absPath = pref and result = "" absPath = pref and result = ""
or or
@@ -79,7 +79,7 @@ class Container extends Locatable, @container {
* </table> * </table>
*/ */
string getBaseName() { 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> * <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table> * </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 * 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> * <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table> * </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. */ /** Gets the parent container of this file or folder, if any. */
Container getParentContainer() { Container getParentContainer() {
@@ -135,20 +139,20 @@ class Container extends Locatable, @container {
Container getAChildContainer() { this = result.getParentContainer() } Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */ /** 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. */ /** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) { File getFile(string baseName) {
result = getAFile() and result = this.getAFile() and
result.getBaseName() = baseName result.getBaseName() = baseName
} }
/** Gets a sub-folder in this container. */ /** 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. */ /** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) { Folder getFolder(string baseName) {
result = getAFolder() and result = this.getAFolder() and
result.getBaseName() = baseName result.getBaseName() = baseName
} }
@@ -157,7 +161,7 @@ class Container extends Locatable, @container {
* *
* This is the absolute path of the container. * This is the absolute path of the container.
*/ */
override string toString() { result = getAbsolutePath() } override string toString() { result = this.getAbsolutePath() }
} }
/** /**

View File

@@ -43,26 +43,26 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/ */
string getFullSignature() { string getFullSignature() {
exists(string name, string templateArgs, string args | exists(string name, string templateArgs, string args |
result = name + templateArgs + args + " -> " + getType().toString() and result = name + templateArgs + args + " -> " + this.getType().toString() and
name = getQualifiedName() and name = this.getQualifiedName() and
( (
if exists(getATemplateArgument()) if exists(this.getATemplateArgument())
then then
templateArgs = templateArgs =
"<" + "<" +
concat(int i | 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 = "" else templateArgs = ""
) and ) and
args = args =
"(" + "(" +
concat(int i | 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. */ /** Gets a specifier of this function. */
override Specifier getASpecifier() { override Specifier getASpecifier() {
funspecifiers(underlyingElement(this), unresolveElement(result)) or funspecifiers(underlyingElement(this), unresolveElement(result)) or
result.hasName(getADeclarationEntry().getASpecifier()) result.hasName(this.getADeclarationEntry().getASpecifier())
} }
/** Gets an attribute of this function. */ /** 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 * Holds if this function is declared with `__attribute__((naked))` or
* `__declspec(naked)`. * `__declspec(naked)`.
*/ */
predicate isNaked() { getAnAttribute().hasName("naked") } predicate isNaked() { this.getAnAttribute().hasName("naked") }
/** /**
* Holds if this function has a trailing return type. * 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 * Gets the return type of this function after specifiers have been deeply
* stripped and typedefs have been resolved. * 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 * 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() { int getEffectiveNumberOfParameters() {
// This method is overridden in `MemberFunction`, where the result is // This method is overridden in `MemberFunction`, where the result is
// adjusted to account for the implicit `this` parameter. // 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`. * return `int p1, int p2`.
*/ */
string getParameterString() { 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. */ /** Gets a call to this function. */
@@ -229,7 +229,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/ */
override FunctionDeclarationEntry getADeclarationEntry() { override FunctionDeclarationEntry getADeclarationEntry() {
if fun_decls(_, underlyingElement(this), _, _, _) if fun_decls(_, underlyingElement(this), _, _, _)
then declEntry(result) then this.declEntry(result)
else else
exists(Function f | exists(Function f |
this.isConstructedFrom(f) and this.isConstructedFrom(f) and
@@ -250,7 +250,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Gets the location of a `FunctionDeclarationEntry` corresponding to this * Gets the location of a `FunctionDeclarationEntry` corresponding to this
* declaration. * declaration.
*/ */
override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() } override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
/** Holds if this Function is a Template specialization. */ /** Holds if this Function is a Template specialization. */
predicate isSpecialization() { predicate isSpecialization() {
@@ -265,14 +265,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* definition, if any. * definition, if any.
*/ */
override FunctionDeclarationEntry getDefinition() { override FunctionDeclarationEntry getDefinition() {
result = getADeclarationEntry() and result = this.getADeclarationEntry() and
result.isDefinition() result.isDefinition()
} }
/** Gets the location of the definition, if any. */ /** Gets the location of the definition, if any. */
override Location getDefinitionLocation() { override Location getDefinitionLocation() {
if exists(getDefinition()) if exists(this.getDefinition())
then result = getDefinition().getLocation() then result = this.getDefinition().getLocation()
else exists(Function f | this.isConstructedFrom(f) and result = f.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.) * definition, if possible.)
*/ */
override Location getLocation() { override Location getLocation() {
if exists(getDefinition()) if exists(this.getDefinition())
then result = this.getDefinitionLocation() then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation() else result = this.getADeclarationLocation()
} }
@@ -299,7 +299,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
BlockStmt getBlock() { result.getParentScope() = this } BlockStmt getBlock() { result.getParentScope() = this }
/** Holds if this function has an entry point. */ /** 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. * 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 * Holds if this function has C linkage, as specified by one of its
* declaration entries. For example: `extern "C" void foo();`. * 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 * 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 * several functions that are not linked together have been compiled. An
* example would be a project with many 'main' functions. * 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. */ /** 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. */ /** 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. * 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. */ /** 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. */ /** 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. */ /** 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. * 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 { class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** Gets the function which is being declared or defined. */ /** 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" } override string getAPrimaryQlClass() { result = "FunctionDeclarationEntry" }
@@ -586,7 +586,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* case, catch) plus the number of branching expressions (`?`, `&&`, * case, catch) plus the number of branching expressions (`?`, `&&`,
* `||`) plus one. * `||`) 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 * If this is a function definition, get the block containing the
@@ -594,7 +594,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
*/ */
BlockStmt getBlock() { BlockStmt getBlock() {
this.isDefinition() and this.isDefinition() and
result = getFunction().getBlock() and result = this.getFunction().getBlock() and
result.getFile() = this.getFile() result.getFile() = this.getFile()
} }
@@ -604,7 +604,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
*/ */
pragma[noopt] pragma[noopt]
int getNumberOfLines() { 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 l = b.getLocation() and
start = l.getStartLine() and start = l.getStartLine() and
end = l.getEndLine() and end = l.getEndLine() and
@@ -618,7 +618,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* declaration. * declaration.
*/ */
ParameterDeclarationEntry getAParameterDeclarationEntry() { ParameterDeclarationEntry getAParameterDeclarationEntry() {
result = getParameterDeclarationEntry(_) result = this.getParameterDeclarationEntry(_)
} }
/** /**
@@ -639,7 +639,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* return 'int p1, int p2'. * return 'int p1, int p2'.
*/ */
string getParameterString() { 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();` * `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. */ /** 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. */ /** Holds if this declaration is also a definition of its function. */
override predicate isDefinition() { fun_def(underlyingElement(this)) } override predicate isDefinition() { fun_def(underlyingElement(this)) }
@@ -665,7 +666,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
predicate isImplicit() { fun_implicit(underlyingElement(this)) } predicate isImplicit() { fun_implicit(underlyingElement(this)) }
/** Gets a type that is specified to be thrown by the declared function. */ /** 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 * 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() { predicate hasExceptionSpecification() {
fun_decl_throws(underlyingElement(this), _, _) or fun_decl_throws(underlyingElement(this), _, _) or
fun_decl_noexcept(underlyingElement(this), _) or fun_decl_noexcept(underlyingElement(this), _) or
isNoThrow() or this.isNoThrow() or
isNoExcept() this.isNoExcept()
} }
/** /**
@@ -763,7 +764,7 @@ class Operator extends Function {
*/ */
class TemplateFunction extends Function { class TemplateFunction extends Function {
TemplateFunction() { TemplateFunction() {
is_function_template(underlyingElement(this)) and exists(getATemplateArgument()) is_function_template(underlyingElement(this)) and exists(this.getATemplateArgument())
} }
override string getAPrimaryQlClass() { result = "TemplateFunction" } override string getAPrimaryQlClass() { result = "TemplateFunction" }

View File

@@ -23,7 +23,7 @@ class Include extends PreprocessorDirective, @ppd_include {
* Gets the token which occurs after `#include`, for example `"filename"` * Gets the token which occurs after `#include`, for example `"filename"`
* or `<filename>`. * or `<filename>`.
*/ */
string getIncludeText() { result = getHead() } string getIncludeText() { result = this.getHead() }
/** Gets the file directly included by this `#include`. */ /** Gets the file directly included by this `#include`. */
File getIncludedFile() { includes(underlyingElement(this), unresolveElement(result)) } File getIncludedFile() { includes(underlyingElement(this), unresolveElement(result)) }
@@ -53,7 +53,7 @@ class Include extends PreprocessorDirective, @ppd_include {
* ``` * ```
*/ */
class IncludeNext extends Include, @ppd_include_next { 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 { class Import extends Include, @ppd_objc_import {
override string toString() { result = "#import " + getIncludeText() } override string toString() { result = "#import " + this.getIncludeText() }
} }

View File

@@ -34,8 +34,8 @@ class Initializer extends ControlFlowNode, @initialiser {
override predicate fromSource() { not this.getLocation() instanceof UnknownLocation } override predicate fromSource() { not this.getLocation() instanceof UnknownLocation }
override string toString() { override string toString() {
if exists(getDeclaration()) if exists(this.getDeclaration())
then result = "initializer for " + max(getDeclaration().getName()) then result = "initializer for " + max(this.getDeclaration().getName())
else result = "initializer" else result = "initializer"
} }

View File

@@ -79,8 +79,8 @@ class Location extends @location {
/** Holds if location `l` is completely contained within this one. */ /** Holds if location `l` is completely contained within this one. */
predicate subsumes(Location l) { predicate subsumes(Location l) {
exists(File f | f = getFile() | exists(File f | f = this.getFile() |
exists(int thisStart, int thisEnd | charLoc(f, thisStart, thisEnd) | exists(int thisStart, int thisEnd | this.charLoc(f, thisStart, thisEnd) |
exists(int lStart, int lEnd | l.charLoc(f, lStart, lEnd) | exists(int lStart, int lEnd | l.charLoc(f, lStart, lEnd) |
thisStart <= lStart and lEnd <= thisEnd thisStart <= lStart and lEnd <= thisEnd
) )
@@ -97,10 +97,10 @@ class Location extends @location {
* see `subsumes`. * see `subsumes`.
*/ */
predicate charLoc(File f, int start, int end) { predicate charLoc(File f, int start, int end) {
f = getFile() and f = this.getFile() and
exists(int maxCols | maxCols = maxCols(f) | exists(int maxCols | maxCols = maxCols(f) |
start = getStartLine() * maxCols + getStartColumn() and start = this.getStartLine() * maxCols + this.getStartColumn() and
end = getEndLine() * maxCols + getEndColumn() end = this.getEndLine() * maxCols + this.getEndColumn()
) )
} }
} }
@@ -144,7 +144,7 @@ class Locatable extends Element { }
* expressions, one for statements and one for other program elements. * expressions, one for statements and one for other program elements.
*/ */
class UnknownLocation extends Location { class UnknownLocation extends Location {
UnknownLocation() { getFile().getAbsolutePath() = "" } UnknownLocation() { this.getFile().getAbsolutePath() = "" }
} }
/** /**

View File

@@ -44,10 +44,10 @@ class Macro extends PreprocessorDirective, @ppd_define {
* Gets the name of the macro. For example, `MAX` in * Gets the name of the macro. For example, `MAX` in
* `#define MAX(x,y) (((x)>(y))?(x):(y))`. * `#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`. */ /** 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() } override string toString() { result = this.getMacro().getHead() }
/** Gets the name of the accessed macro. */ /** 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. * expression. In other cases, it may have multiple results or no results.
*/ */
Expr getExpr() { Expr getExpr() {
result = getAnExpandedElement() and result = this.getAnExpandedElement() and
not result.getParent() = getAnExpandedElement() and not result.getParent() = this.getAnExpandedElement() and
not result instanceof Conversion not result instanceof Conversion
} }
@@ -208,8 +208,8 @@ class MacroInvocation extends MacroAccess {
* element is not a statement (for example if it is an expression). * element is not a statement (for example if it is an expression).
*/ */
Stmt getStmt() { Stmt getStmt() {
result = getAnExpandedElement() and result = this.getAnExpandedElement() and
not result.getParent() = getAnExpandedElement() not result.getParent() = this.getAnExpandedElement()
} }
/** /**
@@ -278,7 +278,7 @@ deprecated class MacroInvocationExpr extends Expr {
MacroInvocation getInvocation() { result.getExpr() = this } MacroInvocation getInvocation() { result.getExpr() = this }
/** Gets the name of the invoked macro. */ /** 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 } MacroInvocation getInvocation() { result.getStmt() = this }
/** Gets the name of the invoked macro. */ /** 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. */ /** Holds if `l` is the location of a macro. */

View File

@@ -36,7 +36,9 @@ class MemberFunction extends Function {
* `this` parameter. * `this` parameter.
*/ */
override int getEffectiveNumberOfParameters() { 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. */ /** Holds if this member is private. */
@@ -49,13 +51,13 @@ class MemberFunction extends Function {
predicate isPublic() { this.hasSpecifier("public") } predicate isPublic() { this.hasSpecifier("public") }
/** Holds if this declaration has the lvalue ref-qualifier */ /** 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 */ /** Holds if this declaration has the rvalue ref-qualifier */
predicate isRValueRefQualified() { hasSpecifier("&&") } predicate isRValueRefQualified() { this.hasSpecifier("&&") }
/** Holds if this declaration has a ref-qualifier */ /** 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. */ /** Holds if this function overrides that function. */
predicate overrides(MemberFunction that) { predicate overrides(MemberFunction that) {
@@ -73,10 +75,10 @@ class MemberFunction extends Function {
* class body. * class body.
*/ */
FunctionDeclarationEntry getClassBodyDeclarationEntry() { FunctionDeclarationEntry getClassBodyDeclarationEntry() {
if strictcount(getADeclarationEntry()) = 1 if strictcount(this.getADeclarationEntry()) = 1
then result = getDefinition() then result = this.getDefinition()
else ( 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 * compiler-generated action which initializes a base class or member
* variable. * variable.
*/ */
ConstructorInit getAnInitializer() { result = getInitializer(_) } ConstructorInit getAnInitializer() { result = this.getInitializer(_) }
/** /**
* Gets an entry in the constructor's initializer list, or a * Gets an entry in the constructor's initializer list, or a
@@ -220,8 +222,8 @@ class ImplicitConversionFunction extends MemberFunction {
functions(underlyingElement(this), _, 4) functions(underlyingElement(this), _, 4)
or or
// ConversionConstructor (deprecated) // ConversionConstructor (deprecated)
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
not hasSpecifier("explicit") not this.hasSpecifier("explicit")
} }
/** Gets the type this `ImplicitConversionFunction` takes as input. */ /** Gets the type this `ImplicitConversionFunction` takes as input. */
@@ -248,8 +250,8 @@ class ImplicitConversionFunction extends MemberFunction {
*/ */
deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction { deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction {
ConversionConstructor() { ConversionConstructor() {
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
not hasSpecifier("explicit") not this.hasSpecifier("explicit")
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -301,15 +303,15 @@ class CopyConstructor extends Constructor {
hasCopySignature(this) and hasCopySignature(this) and
( (
// The rest of the parameters all have default values // 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
// or this is a template class, in which case the default values have // 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 // 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 // there are default values present since that is the most common case
// in real-world code. // in real-world code.
getDeclaringType() instanceof TemplateClass this.getDeclaringType() instanceof TemplateClass
) and ) and
not exists(getATemplateArgument()) not exists(this.getATemplateArgument())
} }
override string getAPrimaryQlClass() { result = "CopyConstructor" } override string getAPrimaryQlClass() { result = "CopyConstructor" }
@@ -325,8 +327,8 @@ class CopyConstructor extends Constructor {
// type-checked for each template instantiation; if an argument in an // type-checked for each template instantiation; if an argument in an
// instantiation fails to type-check then the corresponding parameter has // instantiation fails to type-check then the corresponding parameter has
// no default argument in the instantiation. // no default argument in the instantiation.
getDeclaringType() instanceof TemplateClass and this.getDeclaringType() instanceof TemplateClass and
getNumberOfParameters() > 1 this.getNumberOfParameters() > 1
} }
} }
@@ -358,15 +360,15 @@ class MoveConstructor extends Constructor {
hasMoveSignature(this) and hasMoveSignature(this) and
( (
// The rest of the parameters all have default values // 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
// or this is a template class, in which case the default values have // 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 // 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 // there are default values present since that is the most common case
// in real-world code. // in real-world code.
getDeclaringType() instanceof TemplateClass this.getDeclaringType() instanceof TemplateClass
) and ) and
not exists(getATemplateArgument()) not exists(this.getATemplateArgument())
} }
override string getAPrimaryQlClass() { result = "MoveConstructor" } override string getAPrimaryQlClass() { result = "MoveConstructor" }
@@ -382,8 +384,8 @@ class MoveConstructor extends Constructor {
// type-checked for each template instantiation; if an argument in an // type-checked for each template instantiation; if an argument in an
// instantiation fails to type-check then the corresponding parameter has // instantiation fails to type-check then the corresponding parameter has
// no default argument in the instantiation. // no default argument in the instantiation.
getDeclaringType() instanceof TemplateClass and this.getDeclaringType() instanceof TemplateClass and
getNumberOfParameters() > 1 this.getNumberOfParameters() > 1
} }
} }
@@ -426,7 +428,7 @@ class Destructor extends MemberFunction {
* Gets a compiler-generated action which destructs a base class or member * Gets a compiler-generated action which destructs a base class or member
* variable. * variable.
*/ */
DestructorDestruction getADestruction() { result = getDestruction(_) } DestructorDestruction getADestruction() { result = this.getDestruction(_) }
/** /**
* Gets a compiler-generated action which destructs a base class or member * 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 { class CopyAssignmentOperator extends Operator {
CopyAssignmentOperator() { CopyAssignmentOperator() {
hasName("operator=") and this.hasName("operator=") and
( (
hasCopySignature(this) hasCopySignature(this)
or or
// Unlike CopyConstructor, this member allows a non-reference // Unlike CopyConstructor, this member allows a non-reference
// parameter. // parameter.
getParameter(0).getUnspecifiedType() = getDeclaringType() this.getParameter(0).getUnspecifiedType() = this.getDeclaringType()
) and ) and
not exists(this.getParameter(1)) and not exists(this.getParameter(1)) and
not exists(getATemplateArgument()) not exists(this.getATemplateArgument())
} }
override string getAPrimaryQlClass() { result = "CopyAssignmentOperator" } override string getAPrimaryQlClass() { result = "CopyAssignmentOperator" }
@@ -507,10 +509,10 @@ class CopyAssignmentOperator extends Operator {
*/ */
class MoveAssignmentOperator extends Operator { class MoveAssignmentOperator extends Operator {
MoveAssignmentOperator() { MoveAssignmentOperator() {
hasName("operator=") and this.hasName("operator=") and
hasMoveSignature(this) and hasMoveSignature(this) and
not exists(this.getParameter(1)) and not exists(this.getParameter(1)) and
not exists(getATemplateArgument()) not exists(this.getATemplateArgument())
} }
override string getAPrimaryQlClass() { result = "MoveAssignmentOperator" } override string getAPrimaryQlClass() { result = "MoveAssignmentOperator" }

View File

@@ -38,8 +38,8 @@ class Namespace extends NameQualifyingElement, @namespace {
* unless the namespace has exactly one declaration entry. * unless the namespace has exactly one declaration entry.
*/ */
override Location getLocation() { override Location getLocation() {
if strictcount(getADeclarationEntry()) = 1 if strictcount(this.getADeclarationEntry()) = 1
then result = getADeclarationEntry().getLocation() then result = this.getADeclarationEntry().getLocation()
else result instanceof UnknownDefaultLocation else result instanceof UnknownDefaultLocation
} }
@@ -50,7 +50,7 @@ class Namespace extends NameQualifyingElement, @namespace {
predicate hasName(string name) { name = this.getName() } predicate hasName(string name) { name = this.getName() }
/** Holds if this namespace is anonymous. */ /** 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. */ /** Gets the name of the parent namespace, if it exists. */
private string getParentName() { private string getParentName() {
@@ -60,9 +60,9 @@ class Namespace extends NameQualifyingElement, @namespace {
/** Gets the qualified name of this namespace. For example: `a::b`. */ /** Gets the qualified name of this namespace. For example: `a::b`. */
string getQualifiedName() { string getQualifiedName() {
if exists(getParentName()) if exists(this.getParentName())
then result = getParentNamespace().getQualifiedName() + "::" + getName() then result = this.getParentNamespace().getQualifiedName() + "::" + this.getName()
else result = getName() else result = this.getName()
} }
/** Gets the parent namespace, if any. */ /** 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. */ /** Gets a version of the `QualifiedName` that is more suitable for display purposes. */
string getFriendlyName() { result = this.getQualifiedName() } 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. */ /** Gets a declaration of (part of) this namespace. */
NamespaceDeclarationEntry getADeclarationEntry() { result.getNamespace() = this } NamespaceDeclarationEntry getADeclarationEntry() { result.getNamespace() = this }

View File

@@ -40,12 +40,12 @@ class Parameter extends LocalScopeVariable, @parameter {
*/ */
override string getName() { override string getName() {
exists(VariableDeclarationEntry vde | 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 or
not exists(getANamedDeclarationEntry()) and not exists(this.getANamedDeclarationEntry()) and
result = "(unnamed parameter " + this.getIndex().toString() + ")" result = "(unnamed parameter " + this.getIndex().toString() + ")"
} }
@@ -58,8 +58,12 @@ class Parameter extends LocalScopeVariable, @parameter {
*/ */
string getTypedName() { string getTypedName() {
exists(string typeString, string nameString | 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 != "" if typeString != "" and nameString != ""
then result = typeString + " " + nameString then result = typeString + " " + nameString
@@ -69,7 +73,7 @@ class Parameter extends LocalScopeVariable, @parameter {
} }
private VariableDeclarationEntry getANamedDeclarationEntry() { private VariableDeclarationEntry getANamedDeclarationEntry() {
result = getAnEffectiveDeclarationEntry() and result.getName() != "" result = this.getAnEffectiveDeclarationEntry() and result.getName() != ""
} }
/** /**
@@ -82,13 +86,13 @@ class Parameter extends LocalScopeVariable, @parameter {
* own). * own).
*/ */
private VariableDeclarationEntry getAnEffectiveDeclarationEntry() { private VariableDeclarationEntry getAnEffectiveDeclarationEntry() {
if getFunction().isConstructedFrom(_) if this.getFunction().isConstructedFrom(_)
then then
exists(Function prototypeInstantiation | exists(Function prototypeInstantiation |
prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and prototypeInstantiation.getParameter(this.getIndex()) = result.getVariable() and
getFunction().isConstructedFrom(prototypeInstantiation) 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 * `getName()` is not "(unnamed parameter i)" (where `i` is the index
* of the parameter). * 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 * 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() { override Location getLocation() {
exists(VariableDeclarationEntry vde | 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()
) )
} }
} }

View File

@@ -29,8 +29,8 @@ class PreprocessorDirective extends Locatable, @preprocdirect {
PreprocessorBranch getAGuard() { PreprocessorBranch getAGuard() {
exists(PreprocessorEndif e, int line | exists(PreprocessorEndif e, int line |
result.getEndIf() = e and result.getEndIf() = e and
e.getFile() = getFile() and e.getFile() = this.getFile() and
result.getFile() = getFile() and result.getFile() = this.getFile() and
line = this.getLocation().getStartLine() and line = this.getLocation().getStartLine() and
result.getLocation().getStartLine() < line and result.getLocation().getStartLine() < line and
line < e.getLocation().getEndLine() line < e.getLocation().getEndLine()
@@ -69,7 +69,9 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
* directives in different translation units, then there can be more than * directives in different translation units, then there can be more than
* one result. * 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 * 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 * which evaluated it, or was not taken by any translation unit which
* evaluated it. * 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. * Gets the name of the macro that is undefined.
*/ */
string getName() { result = getHead() } string getName() { result = this.getHead() }
} }
/** /**

View File

@@ -105,8 +105,8 @@ private class DumpType extends Type {
// for a `SpecifiedType`, insert the qualifiers after // for a `SpecifiedType`, insert the qualifiers after
// `getDeclaratorSuffixBeforeQualifiers()`. // `getDeclaratorSuffixBeforeQualifiers()`.
result = result =
getTypeSpecifier() + getDeclaratorPrefix() + getDeclaratorSuffixBeforeQualifiers() + this.getTypeSpecifier() + this.getDeclaratorPrefix() +
getDeclaratorSuffix() this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
} }
/** /**
@@ -147,29 +147,35 @@ private class DumpType extends Type {
} }
private class BuiltInDumpType extends DumpType, BuiltInType { private class BuiltInDumpType extends DumpType, BuiltInType {
override string getTypeSpecifier() { result = toString() } override string getTypeSpecifier() { result = this.toString() }
} }
private class IntegralDumpType extends BuiltInDumpType, IntegralType { 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 { private class DerivedDumpType extends DumpType, DerivedType {
override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() } override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
override string getDeclaratorSuffixBeforeQualifiers() { 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 { 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 { private class PointerIshDumpType extends DerivedDumpType {
@@ -180,10 +186,10 @@ private class PointerIshDumpType extends DerivedDumpType {
override string getDeclaratorPrefix() { override string getDeclaratorPrefix() {
exists(string declarator | exists(string declarator |
result = getBaseType().(DumpType).getDeclaratorPrefix() + declarator and result = this.getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
if getBaseType().getUnspecifiedType() instanceof ArrayType if this.getBaseType().getUnspecifiedType() instanceof ArrayType
then declarator = "(" + getDeclaratorToken() + ")" then declarator = "(" + this.getDeclaratorToken() + ")"
else declarator = getDeclaratorToken() else declarator = this.getDeclaratorToken()
) )
} }
@@ -206,13 +212,13 @@ private class RValueReferenceDumpType extends PointerIshDumpType, RValueReferenc
} }
private class PointerToMemberDumpType extends DumpType, PointerToMemberType { private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() } override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
override string getDeclaratorPrefix() { override string getDeclaratorPrefix() {
exists(string declarator, string parenDeclarator, Type baseType | exists(string declarator, string parenDeclarator, Type baseType |
declarator = getClass().(DumpType).getTypeIdentityString() + "::*" and declarator = this.getClass().(DumpType).getTypeIdentityString() + "::*" and
result = getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and result = this.getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
baseType = getBaseType().getUnspecifiedType() and baseType = this.getBaseType().getUnspecifiedType() and
if baseType instanceof ArrayType or baseType instanceof RoutineType if baseType instanceof ArrayType or baseType instanceof RoutineType
then parenDeclarator = "(" + declarator then parenDeclarator = "(" + declarator
else parenDeclarator = declarator else parenDeclarator = declarator
@@ -221,38 +227,44 @@ private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
override string getDeclaratorSuffixBeforeQualifiers() { override string getDeclaratorSuffixBeforeQualifiers() {
exists(Type baseType | exists(Type baseType |
baseType = getBaseType().getUnspecifiedType() and baseType = this.getBaseType().getUnspecifiedType() and
if baseType instanceof ArrayType or baseType instanceof RoutineType if baseType instanceof ArrayType or baseType instanceof RoutineType
then result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() then result = ")" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
else result = 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 { private class ArrayDumpType extends DerivedDumpType, ArrayType {
override string getDeclaratorPrefix() { result = getBaseType().(DumpType).getDeclaratorPrefix() } override string getDeclaratorPrefix() {
result = this.getBaseType().(DumpType).getDeclaratorPrefix()
}
override string getDeclaratorSuffixBeforeQualifiers() { override string getDeclaratorSuffixBeforeQualifiers() {
if exists(getArraySize()) if exists(this.getArraySize())
then then
result = result =
"[" + getArraySize().toString() + "]" + "[" + this.getArraySize().toString() + "]" +
getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
else result = "[]" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() else result = "[]" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
} }
} }
private class FunctionPointerIshDumpType extends DerivedDumpType, FunctionPointerIshType { private class FunctionPointerIshDumpType extends DerivedDumpType, FunctionPointerIshType {
override string getDeclaratorSuffixBeforeQualifiers() { 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() { 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 { private class RoutineDumpType extends DumpType, RoutineType {
override string getTypeSpecifier() { result = getReturnType().(DumpType).getTypeSpecifier() } override string getTypeSpecifier() { result = this.getReturnType().(DumpType).getTypeSpecifier() }
override string getDeclaratorPrefix() { override string getDeclaratorPrefix() {
result = getReturnType().(DumpType).getDeclaratorPrefix() result = this.getReturnType().(DumpType).getDeclaratorPrefix()
} }
language[monotonicAggregates] language[monotonicAggregates]
@@ -285,39 +297,41 @@ private class RoutineDumpType extends DumpType, RoutineType {
result = result =
"(" + "(" +
concat(int i | 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() { override string getDeclaratorSuffix() {
result = result =
getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() + this.getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
getReturnType().(DumpType).getDeclaratorSuffix() this.getReturnType().(DumpType).getDeclaratorSuffix()
} }
} }
private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType { private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
override string getDeclaratorPrefix() { override string getDeclaratorPrefix() {
exists(string basePrefix | exists(string basePrefix |
basePrefix = getBaseType().(DumpType).getDeclaratorPrefix() and basePrefix = this.getBaseType().(DumpType).getDeclaratorPrefix() and
if getBaseType().getUnspecifiedType() instanceof RoutineType if this.getBaseType().getUnspecifiedType() instanceof RoutineType
then result = basePrefix then result = basePrefix
else result = basePrefix + " " + getSpecifierString() else result = basePrefix + " " + this.getSpecifierString()
) )
} }
override string getDeclaratorSuffixBeforeQualifiers() { override string getDeclaratorSuffixBeforeQualifiers() {
exists(string baseSuffix | exists(string baseSuffix |
baseSuffix = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and baseSuffix = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
if getBaseType().getUnspecifiedType() instanceof RoutineType if this.getBaseType().getUnspecifiedType() instanceof RoutineType
then result = baseSuffix + " " + getSpecifierString() then result = baseSuffix + " " + this.getSpecifierString()
else result = baseSuffix 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 { 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" // "lambda [] type at line 12, col. 40"
// Use `min(getSimpleName())` to work around an extractor bug where a lambda can have different names // Use `min(getSimpleName())` to work around an extractor bug where a lambda can have different names
// from different compilation units. // from different compilation units.
simpleName = "(" + min(getSimpleName()) + ")" simpleName = "(" + min(this.getSimpleName()) + ")"
else simpleName = getSimpleName() else simpleName = this.getSimpleName()
) and ) 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 { private class DumpProxyClass extends UserDumpType, ProxyClass {
override string getIdentityString() { result = getName() } override string getIdentityString() { result = this.getName() }
} }
private class DumpVariable extends DumpDeclaration, Variable { private class DumpVariable extends DumpDeclaration, Variable {
@@ -360,9 +374,9 @@ private class DumpVariable extends DumpDeclaration, Variable {
private class DumpFunction extends DumpDeclaration, Function { private class DumpFunction extends DumpDeclaration, Function {
override string getIdentityString() { override string getIdentityString() {
result = result =
getType().(DumpType).getTypeSpecifier() + getType().(DumpType).getDeclaratorPrefix() + " " + this.getType().(DumpType).getTypeSpecifier() + this.getType().(DumpType).getDeclaratorPrefix()
getScopePrefix(this) + getName() + getTemplateArgumentsString() + + " " + getScopePrefix(this) + this.getName() + this.getTemplateArgumentsString() +
getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix() this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
} }
language[monotonicAggregates] language[monotonicAggregates]
@@ -370,28 +384,29 @@ private class DumpFunction extends DumpDeclaration, Function {
result = result =
"(" + "(" +
concat(int i | concat(int i |
exists(getParameter(i).getType()) exists(this.getParameter(i).getType())
| |
getParameterTypeString(getParameter(i).getType()), ", " order by i getParameterTypeString(this.getParameter(i).getType()), ", " order by i
) + ")" + getQualifierString() ) + ")" + this.getQualifierString()
} }
private string getQualifierString() { private string getQualifierString() {
if exists(getACVQualifier()) if exists(this.getACVQualifier())
then then
result = " " + strictconcat(string qualifier | qualifier = getACVQualifier() | qualifier, " ") result =
" " + strictconcat(string qualifier | qualifier = this.getACVQualifier() | qualifier, " ")
else result = "" else result = ""
} }
private string getACVQualifier() { private string getACVQualifier() {
result = getASpecifier().getName() and result = this.getASpecifier().getName() and
result = ["const", "volatile"] result = ["const", "volatile"]
} }
private string getDeclaratorSuffix() { private string getDeclaratorSuffix() {
result = result =
getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() + this.getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
getType().(DumpType).getDeclaratorSuffix() this.getType().(DumpType).getDeclaratorSuffix()
} }
} }

View File

@@ -140,7 +140,7 @@ class Attribute extends Element, @attribute {
AttributeArgument getArgument(int i) { result.getAttribute() = this and result.getIndex() = i } AttributeArgument getArgument(int i) { result.getAttribute() = this and result.getIndex() = i }
/** Gets an argument of the attribute. */ /** 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. * Holds if this attribute has the given namespace and name.
*/ */
predicate hasQualifiedName(string namespace, string 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 { class MicrosoftAttribute extends Attribute, @msattribute {
AttributeArgument getNamedArgument(string name) { 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 { class FormatAttribute extends GnuAttribute {
FormatAttribute() { getName() = "format" } FormatAttribute() { this.getName() = "format" }
/** /**
* Gets the archetype of this format attribute, for example * Gets the archetype of this format attribute, for example
* `"printf"`. * `"printf"`.
*/ */
string getArchetype() { result = getArgument(0).getValueText() } string getArchetype() { result = this.getArgument(0).getValueText() }
/** /**
* Gets the index in (1-based) format attribute notation associated * 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, * Gets the (0-based) index of the format string,
* according to this attribute. * 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), * Gets the (0-based) index of the first format argument (if any),
@@ -244,8 +244,8 @@ class FormatAttribute extends GnuAttribute {
*/ */
int getFirstFormatArgIndex() { int getFirstFormatArgIndex() {
exists(int val | exists(int val |
val = getArgument(2).getValueInt() and val = this.getArgument(2).getValueInt() and
result = val - firstArgumentNumber() and result = val - this.firstArgumentNumber() and
not val = 0 // indicates a `vprintf` style format function with arguments not directly available. 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. * 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. * 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" then result = "empty argument"
else else
exists(string prefix, string tail | 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)) if exists(@attribute_arg_type self | self = underlyingElement(this))
then tail = getValueType().getName() then tail = this.getValueType().getName()
else tail = getValueText() else tail = this.getValueText()
) and ) and
result = prefix + tail result = prefix + tail
) )

View File

@@ -41,7 +41,7 @@ class Struct extends Class {
* ``` * ```
*/ */
class LocalStruct extends Struct { class LocalStruct extends Struct {
LocalStruct() { isLocal() } LocalStruct() { this.isLocal() }
override string getAPrimaryQlClass() { not this instanceof LocalUnion and result = "LocalStruct" } override string getAPrimaryQlClass() { not this instanceof LocalUnion and result = "LocalStruct" }
} }

View File

@@ -10,8 +10,8 @@ import semmle.code.cpp.File
*/ */
private class GoogleTestHeader extends File { private class GoogleTestHeader extends File {
GoogleTestHeader() { GoogleTestHeader() {
getBaseName() = "gtest.h" and this.getBaseName() = "gtest.h" and
getParentContainer().getBaseName() = "gtest" this.getParentContainer().getBaseName() = "gtest"
} }
} }
@@ -30,8 +30,8 @@ private class GoogleTest extends MacroInvocation {
*/ */
private class BoostTestFolder extends Folder { private class BoostTestFolder extends Folder {
BoostTestFolder() { BoostTestFolder() {
getBaseName() = "test" and this.getBaseName() = "test" and
getParentContainer().getBaseName() = "boost" this.getParentContainer().getBaseName() = "boost"
} }
} }
@@ -49,7 +49,7 @@ private class BoostTest extends MacroInvocation {
* The `cppunit` directory. * The `cppunit` directory.
*/ */
private class CppUnitFolder extends Folder { 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 { private class CppUnitClass extends Class {
CppUnitClass() { CppUnitClass() {
getFile().getParentContainer+() instanceof CppUnitFolder and this.getFile().getParentContainer+() instanceof CppUnitFolder and
getNamespace().getParentNamespace*().getName() = "CppUnit" this.getNamespace().getParentNamespace*().getName() = "CppUnit"
} }
} }

View File

@@ -81,7 +81,7 @@ class Type extends Locatable, @type {
* Holds if this type refers to type `t` (by default, * Holds if this type refers to type `t` (by default,
* a type always refers to itself). * 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. * 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 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 * 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) } 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 toString() { result = "decltype(...)" }
override string getName() { none() } 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() { override string explain() {
result = "decltype resulting in {" + this.getBaseType().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() } override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() }
@@ -1223,7 +1225,7 @@ class PointerType extends DerivedType {
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() } override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
override Type resolveTypedefs() { 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 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() + "}" } override string explain() { result = "reference to {" + this.getBaseType().explain() + "}" }
@@ -1251,7 +1255,7 @@ class ReferenceType extends DerivedType {
override predicate involvesReference() { any() } override predicate involvesReference() { any() }
override Type resolveTypedefs() { 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() { override Type resolveTypedefs() {
result.(SpecifiedType).getBaseType() = getBaseType().resolveTypedefs() and result.(SpecifiedType).getBaseType() = this.getBaseType().resolveTypedefs() and
result.getASpecifier() = getASpecifier() 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 int getAlignment() { arraysizes(underlyingElement(this), _, _, result) }
override string explain() { 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() } override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
@@ -1468,7 +1473,9 @@ class FunctionReferenceType extends FunctionPointerIshType {
override string getAPrimaryQlClass() { result = "FunctionReferenceType" } override string getAPrimaryQlClass() { result = "FunctionReferenceType" }
override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() } override int getPointerIndirectionLevel() {
result = this.getBaseType().getPointerIndirectionLevel()
}
override string explain() { override string explain() {
result = "reference to {" + this.getBaseType().(RoutineType).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))) } int getNumberOfParameters() { result = count(int i | exists(this.getParameterType(i))) }
override predicate involvesTemplateParameter() { override predicate involvesTemplateParameter() {
getReturnType().involvesTemplateParameter() or this.getReturnType().involvesTemplateParameter() or
getAParameterType().involvesTemplateParameter() this.getAParameterType().involvesTemplateParameter()
} }
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() } override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
@@ -1581,7 +1588,7 @@ class PointerToMemberType extends Type, @ptrtomember {
this.getBaseType().explain() + "}" this.getBaseType().explain() + "}"
} }
override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() } override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() } 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 isDeeplyConstBelow() { none() } // Current limitation: no such thing as a const routine type
override predicate involvesTemplateParameter() { override predicate involvesTemplateParameter() {
getReturnType().involvesTemplateParameter() or this.getReturnType().involvesTemplateParameter() or
getAParameterType().involvesTemplateParameter() this.getAParameterType().involvesTemplateParameter()
} }
} }

View File

@@ -25,7 +25,7 @@ class TypedefType extends UserType {
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() } 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() } override int getSize() { result = this.getBaseType().getSize() }
@@ -43,11 +43,11 @@ class TypedefType extends UserType {
result = this.getBaseType().getASpecifier() 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 { class LocalTypedefType extends TypedefType {
LocalTypedefType() { isLocal() } LocalTypedefType() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalTypedefType" } override string getAPrimaryQlClass() { result = "LocalTypedefType" }
} }

View File

@@ -37,7 +37,7 @@ class Union extends Struct {
* ``` * ```
*/ */
class LocalUnion extends Union { class LocalUnion extends Union {
LocalUnion() { isLocal() } LocalUnion() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalUnion" } override string getAPrimaryQlClass() { result = "LocalUnion" }
} }

View File

@@ -30,19 +30,19 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
* Gets the simple name of this type, without any template parameters. For example * 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"`. * 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, _) } override predicate hasName(string name) { usertypes(underlyingElement(this), name, _) }
/** Holds if this type is anonymous. */ /** 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 predicate hasSpecifier(string s) { Type.super.hasSpecifier(s) }
override Specifier getASpecifier() { result = Type.super.getASpecifier() } override Specifier getASpecifier() { result = Type.super.getASpecifier() }
override Location getLocation() { override Location getLocation() {
if hasDefinition() if this.hasDefinition()
then result = this.getDefinitionLocation() then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation() 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()) 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() { override TypeDeclarationEntry getDefinition() {
result = getADeclarationEntry() and result = this.getADeclarationEntry() and
result.isDefinition() result.isDefinition()
} }
override Location getDefinitionLocation() { override Location getDefinitionLocation() {
if exists(getDefinition()) if exists(this.getDefinition())
then result = getDefinition().getLocation() then result = this.getDefinition().getLocation()
else else
exists(Class t | exists(Class t |
this.(Class).isConstructedFrom(t) and result = t.getDefinition().getLocation() 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 * Holds if this is a local type (that is, a type that has a directly-enclosing
* function). * function).
*/ */
predicate isLocal() { exists(getEnclosingFunction()) } predicate isLocal() { exists(this.getEnclosingFunction()) }
/* /*
* Dummy implementations of inherited methods. This class must not be * 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 { 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" } override string getAPrimaryQlClass() { result = "TypeDeclarationEntry" }

View File

@@ -104,17 +104,17 @@ class Variable extends Declaration, @variable {
override VariableDeclarationEntry getADeclarationEntry() { result.getDeclaration() = this } override VariableDeclarationEntry getADeclarationEntry() { result.getDeclaration() = this }
override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() } override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
override VariableDeclarationEntry getDefinition() { override VariableDeclarationEntry getDefinition() {
result = getADeclarationEntry() and result = this.getADeclarationEntry() and
result.isDefinition() result.isDefinition()
} }
override Location getDefinitionLocation() { result = getDefinition().getLocation() } override Location getDefinitionLocation() { result = this.getDefinition().getLocation() }
override Location getLocation() { override Location getLocation() {
if exists(getDefinition()) if exists(this.getDefinition())
then result = this.getDefinitionLocation() then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation() else result = this.getADeclarationLocation()
} }
@@ -199,7 +199,7 @@ class Variable extends Declaration, @variable {
* ``` * ```
*/ */
class VariableDeclarationEntry extends DeclarationEntry, @var_decl { class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
override Variable getDeclaration() { result = getVariable() } override Variable getDeclaration() { result = this.getVariable() }
override string getAPrimaryQlClass() { result = "VariableDeclarationEntry" } override string getAPrimaryQlClass() { result = "VariableDeclarationEntry" }
@@ -276,32 +276,33 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
int getIndex() { param_decl_bind(underlyingElement(this), result, _) } int getIndex() { param_decl_bind(underlyingElement(this), result, _) }
private string getAnonymousParameterDescription() { private string getAnonymousParameterDescription() {
not exists(getName()) and not exists(this.getName()) and
exists(string idx | exists(string idx |
idx = idx =
((getIndex() + 1).toString() + "th") ((this.getIndex() + 1).toString() + "th")
.replaceAll("1th", "1st") .replaceAll("1th", "1st")
.replaceAll("2th", "2nd") .replaceAll("2th", "2nd")
.replaceAll("3th", "3rd") .replaceAll("3th", "3rd")
.replaceAll("11st", "11th") .replaceAll("11st", "11th")
.replaceAll("12nd", "12th") .replaceAll("12nd", "12th")
.replaceAll("13rd", "13th") and .replaceAll("13rd", "13th") and
if exists(getCanonicalName()) if exists(this.getCanonicalName())
then result = "declaration of " + getCanonicalName() + " as anonymous " + idx + " parameter" then
result = "declaration of " + this.getCanonicalName() + " as anonymous " + idx + " parameter"
else result = "declaration of " + idx + " parameter" else result = "declaration of " + idx + " parameter"
) )
} }
override string toString() { override string toString() {
isDefinition() and this.isDefinition() and
result = "definition of " + getName() result = "definition of " + this.getName()
or or
not isDefinition() and not this.isDefinition() and
if getName() = getCanonicalName() if this.getName() = this.getCanonicalName()
then result = "declaration of " + getName() then result = "declaration of " + this.getName()
else result = "declaration of " + getCanonicalName() + " as " + getName() else result = "declaration of " + this.getCanonicalName() + " as " + this.getName()
or or
result = getAnonymousParameterDescription() result = this.getAnonymousParameterDescription()
} }
/** /**
@@ -311,8 +312,12 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
*/ */
string getTypedName() { string getTypedName() {
exists(string typeString, string nameString | 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 != "" if typeString != "" and nameString != ""
then result = typeString + " " + nameString then result = typeString + " " + nameString
else result = typeString + nameString else result = typeString + nameString
@@ -540,7 +545,7 @@ class MemberVariable extends Variable, @membervariable {
} }
/** Holds if this member is mutable. */ /** 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), _) } private Type getAType() { membervariables(underlyingElement(this), unresolveElement(result), _) }
} }

View File

@@ -375,8 +375,8 @@ class Wchar_t extends Type {
class MicrosoftInt8Type extends IntegralType { class MicrosoftInt8Type extends IntegralType {
MicrosoftInt8Type() { MicrosoftInt8Type() {
this instanceof CharType and this instanceof CharType and
not isExplicitlyUnsigned() and not this.isExplicitlyUnsigned() and
not isExplicitlySigned() not this.isExplicitlySigned()
} }
} }
@@ -391,8 +391,8 @@ class MicrosoftInt8Type extends IntegralType {
class MicrosoftInt16Type extends IntegralType { class MicrosoftInt16Type extends IntegralType {
MicrosoftInt16Type() { MicrosoftInt16Type() {
this instanceof ShortType and this instanceof ShortType and
not isExplicitlyUnsigned() and not this.isExplicitlyUnsigned() and
not isExplicitlySigned() not this.isExplicitlySigned()
} }
} }
@@ -407,8 +407,8 @@ class MicrosoftInt16Type extends IntegralType {
class MicrosoftInt32Type extends IntegralType { class MicrosoftInt32Type extends IntegralType {
MicrosoftInt32Type() { MicrosoftInt32Type() {
this instanceof IntType and this instanceof IntType and
not isExplicitlyUnsigned() and not this.isExplicitlyUnsigned() and
not isExplicitlySigned() not this.isExplicitlySigned()
} }
} }
@@ -423,8 +423,8 @@ class MicrosoftInt32Type extends IntegralType {
class MicrosoftInt64Type extends IntegralType { class MicrosoftInt64Type extends IntegralType {
MicrosoftInt64Type() { MicrosoftInt64Type() {
this instanceof LongLongType and this instanceof LongLongType and
not isExplicitlyUnsigned() and not this.isExplicitlyUnsigned() and
not isExplicitlySigned() not this.isExplicitlySigned()
} }
} }

View File

@@ -33,7 +33,7 @@ DependencyOptions getDependencyOptions() { any() }
class DependsSource extends Element { class DependsSource extends Element {
DependsSource() { DependsSource() {
// not inside a template instantiation // 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 // allow DeclarationEntrys of template specializations
this.(DeclarationEntry).getDeclaration().(Function).isConstructedFrom(_) or this.(DeclarationEntry).getDeclaration().(Function).isConstructedFrom(_) or
this.(DeclarationEntry).getDeclaration().(Class).isConstructedFrom(_) this.(DeclarationEntry).getDeclaration().(Class).isConstructedFrom(_)

View File

@@ -8,7 +8,7 @@ import semmle.code.cpp.commons.StringAnalysis
import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.FormattingFunction
class PrintfFormatAttribute extends FormatAttribute { class PrintfFormatAttribute extends FormatAttribute {
PrintfFormatAttribute() { getArchetype() = ["printf", "__printf__"] } PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
} }
/** /**
@@ -20,13 +20,13 @@ class AttributeFormattingFunction extends FormattingFunction {
AttributeFormattingFunction() { AttributeFormattingFunction() {
exists(PrintfFormatAttribute printf_attrib | exists(PrintfFormatAttribute printf_attrib |
printf_attrib = getAnAttribute() and printf_attrib = this.getAnAttribute() and
exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions
) )
} }
override int getFormatParameterIndex() { override int getFormatParameterIndex() {
forex(PrintfFormatAttribute printf_attrib | printf_attrib = getAnAttribute() | forex(PrintfFormatAttribute printf_attrib | printf_attrib = this.getAnAttribute() |
result = printf_attrib.getFormatIndex() result = printf_attrib.getFormatIndex()
) )
} }
@@ -132,7 +132,7 @@ deprecated predicate variadicFormatter(Function f, int formatParamIndex) {
class UserDefinedFormattingFunction extends FormattingFunction { class UserDefinedFormattingFunction extends FormattingFunction {
override string getAPrimaryQlClass() { result = "UserDefinedFormattingFunction" } override string getAPrimaryQlClass() { result = "UserDefinedFormattingFunction" }
UserDefinedFormattingFunction() { isVarargs() and callsVariadicFormatter(this, _, _, _) } UserDefinedFormattingFunction() { this.isVarargs() and callsVariadicFormatter(this, _, _, _) }
override int getFormatParameterIndex() { callsVariadicFormatter(this, _, result, _) } override int getFormatParameterIndex() { callsVariadicFormatter(this, _, result, _) }
@@ -191,7 +191,7 @@ class FormattingFunctionCall extends Expr {
exists(int i | exists(int i |
result = this.getArgument(i) and result = this.getArgument(i) and
n >= 0 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() { int getNumFormatArgument() {
result = count(this.getFormatArgument(_)) and result = count(this.getFormatArgument(_)) and
// format arguments must be known // 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: Use getDefaultCharType() instead.
*/ */
deprecated predicate isWideCharDefault() { deprecated predicate isWideCharDefault() {
getUse().getTarget().(FormattingFunction).isWideCharDefault() this.getUse().getTarget().(FormattingFunction).isWideCharDefault()
} }
/** /**
@@ -298,7 +298,7 @@ class FormatLiteral extends Literal {
* `char` or `wchar_t`. * `char` or `wchar_t`.
*/ */
Type getDefaultCharType() { 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. * which is correct for a particular function.
*/ */
Type getNonDefaultCharType() { 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 * snapshots there may be multiple results where we can't tell which is correct for a
* particular function. * 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 * Holds if this `FormatLiteral` is in a context that supports
@@ -353,7 +355,7 @@ class FormatLiteral extends Literal {
} }
private string getFlagRegexp() { 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]+\\$)?" } 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 getPrecRegexp() { result = "(?:\\.(?:[0-9]*|\\*|\\*[0-9]+\\$))?" }
private string getLengthRegexp() { private string getLengthRegexp() {
if isMicrosoft() if this.isMicrosoft()
then result = "(?:hh?|ll?|L|q|j|z|t|w|I32|I64|I)?" then result = "(?:hh?|ll?|L|q|j|z|t|w|I32|I64|I)?"
else result = "(?:hh?|ll?|L|q|j|z|Z|t)?" else result = "(?:hh?|ll?|L|q|j|z|Z|t)?"
} }
private string getConvCharRegexp() { private string getConvCharRegexp() {
if isMicrosoft() if this.isMicrosoft()
then result = "[aAcCdeEfFgGimnopsSuxXZ@]" then result = "[aAcCdeEfFgGimnopsSuxXZ@]"
else result = "[aAcCdeEfFgGimnopsSuxX@]" else result = "[aAcCdeEfFgGimnopsSuxX@]"
} }
@@ -747,16 +749,16 @@ class FormatLiteral extends Literal {
* Gets the argument type required by the nth conversion specifier. * Gets the argument type required by the nth conversion specifier.
*/ */
Type getConversionType(int n) { Type getConversionType(int n) {
result = getConversionType1(n) or result = this.getConversionType1(n) or
result = getConversionType1b(n) or result = this.getConversionType1b(n) or
result = getConversionType2(n) or result = this.getConversionType2(n) or
result = getConversionType3(n) or result = this.getConversionType3(n) or
result = getConversionType4(n) or result = this.getConversionType4(n) or
result = getConversionType6(n) or result = this.getConversionType6(n) or
result = getConversionType7(n) or result = this.getConversionType7(n) or
result = getConversionType8(n) or result = this.getConversionType8(n) or
result = getConversionType9(n) or result = this.getConversionType9(n) or
result = getConversionType10(n) result = this.getConversionType10(n)
} }
private Type getConversionType1(int n) { private Type getConversionType1(int n) {
@@ -786,15 +788,15 @@ class FormatLiteral extends Literal {
or or
conv = ["c", "C"] and conv = ["c", "C"] and
len = ["l", "w"] and len = ["l", "w"] and
result = getWideCharType() result = this.getWideCharType()
or or
conv = "c" and conv = "c" and
(len != "l" and len != "w" and len != "h") and (len != "l" and len != "w" and len != "h") and
result = getDefaultCharType() result = this.getDefaultCharType()
or or
conv = "C" and conv = "C" and
(len != "l" and len != "w" and len != "h") and (len != "l" and len != "w" and len != "h") and
result = getNonDefaultCharType() result = this.getNonDefaultCharType()
) )
) )
} }
@@ -831,15 +833,15 @@ class FormatLiteral extends Literal {
or or
conv = ["s", "S"] and conv = ["s", "S"] and
len = ["l", "w"] and len = ["l", "w"] and
result.(PointerType).getBaseType() = getWideCharType() result.(PointerType).getBaseType() = this.getWideCharType()
or or
conv = "s" and conv = "s" and
(len != "l" and len != "w" and len != "h") and (len != "l" and len != "w" and len != "h") and
result.(PointerType).getBaseType() = getDefaultCharType() result.(PointerType).getBaseType() = this.getDefaultCharType()
or or
conv = "S" and conv = "S" and
(len != "l" and len != "w" and len != "h") 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 | exists(string len, string conv |
this.parseConvSpec(n, _, _, _, _, _, len, conv) and this.parseConvSpec(n, _, _, _, _, _, len, conv) and
(len != "l" and len != "w" and len != "h") 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 conv = "c" and
result = getNonDefaultCharType() result = this.getNonDefaultCharType()
or or
conv = "C" and conv = "C" and
result = getDefaultCharType() result = this.getDefaultCharType()
or or
conv = "s" and conv = "s" and
result.(PointerType).getBaseType() = getNonDefaultCharType() result.(PointerType).getBaseType() = this.getNonDefaultCharType()
or or
conv = "S" and 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 (`$`). * not account for positional arguments (`$`).
*/ */
int getFormatArgumentIndexFor(int n, int mode) { int getFormatArgumentIndexFor(int n, int mode) {
hasFormatArgumentIndexFor(n, mode) and this.hasFormatArgumentIndexFor(n, mode) and
(3 * n) + mode = (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) { int getNumArgNeeded(int n) {
exists(this.getConvSpecOffset(n)) and exists(this.getConvSpecOffset(n)) and
exists(this.getConversionChar(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, // At least one conversion specifier has a parameter field, in which case,
// they all should have. // they all should have.
result = max(string s | this.getParameterField(_) = s + "$" | s.toInt()) 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 | exists(int sizeBits |
sizeBits = sizeBits =
min(int bits | min(int bits |
bits = getIntegralDisplayType(n).getSize() * 8 bits = this.getIntegralDisplayType(n).getSize() * 8
or or
exists(IntegralType t | exists(IntegralType t |
t = getUse().getConversionArgument(n).getType().getUnderlyingType() t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
| |
t.isSigned() and bits = t.getSize() * 8 t.isSigned() and bits = t.getSize() * 8
) )
@@ -1071,10 +1077,10 @@ class FormatLiteral extends Literal {
exists(int sizeBits | exists(int sizeBits |
sizeBits = sizeBits =
min(int bits | min(int bits |
bits = getIntegralDisplayType(n).getSize() * 8 bits = this.getIntegralDisplayType(n).getSize() * 8
or or
exists(IntegralType t | exists(IntegralType t |
t = getUse().getConversionArgument(n).getType().getUnderlyingType() t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
| |
t.isUnsigned() and bits = t.getSize() * 8 t.isUnsigned() and bits = t.getSize() * 8
) )
@@ -1089,26 +1095,26 @@ class FormatLiteral extends Literal {
exists(int sizeBytes, int baseLen | exists(int sizeBytes, int baseLen |
sizeBytes = sizeBytes =
min(int bytes | min(int bytes |
bytes = getIntegralDisplayType(n).getSize() bytes = this.getIntegralDisplayType(n).getSize()
or or
exists(IntegralType t | exists(IntegralType t |
t = getUse().getConversionArgument(n).getType().getUnderlyingType() t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
| |
t.isUnsigned() and bytes = t.getSize() t.isUnsigned() and bytes = t.getSize()
) )
) and ) and
baseLen = sizeBytes * 2 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 or
this.getConversionChar(n).toLowerCase() = "p" and this.getConversionChar(n).toLowerCase() = "p" and
exists(PointerType ptrType, int baseLen | 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 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 or
@@ -1117,17 +1123,17 @@ class FormatLiteral extends Literal {
exists(int sizeBits, int baseLen | exists(int sizeBits, int baseLen |
sizeBits = sizeBits =
min(int bits | min(int bits |
bits = getIntegralDisplayType(n).getSize() * 8 bits = this.getIntegralDisplayType(n).getSize() * 8
or or
exists(IntegralType t | exists(IntegralType t |
t = getUse().getConversionArgument(n).getType().getUnderlyingType() t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
| |
t.isUnsigned() and bits = t.getSize() * 8 t.isUnsigned() and bits = t.getSize() * 8
) )
) and ) and
baseLen = (sizeBits / 3.0).ceil() 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 or
@@ -1150,8 +1156,8 @@ class FormatLiteral extends Literal {
*/ */
int getMaxConvertedLengthLimited(int n) { int getMaxConvertedLengthLimited(int n) {
if this.getConversionChar(n).toLowerCase() = "f" if this.getConversionChar(n).toLowerCase() = "f"
then result = getMaxConvertedLength(n).minimum(8) then result = this.getMaxConvertedLength(n).minimum(8)
else result = getMaxConvertedLength(n) else result = this.getMaxConvertedLength(n)
} }
/** /**

View File

@@ -24,7 +24,7 @@ abstract class ScanfFunction extends Function {
* Holds if the default meaning of `%s` is a `wchar_t*` string * Holds if the default meaning of `%s` is a `wchar_t*` string
* (rather than a `char*`). * (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() { Scanf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...) this.hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...) this.hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...) this.hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...) this.hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
) )
} }
@@ -53,10 +53,10 @@ class Fscanf extends ScanfFunction {
Fscanf() { Fscanf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...) this.hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...) this.hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...) this.hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
hasGlobalName("_fwscanf_l") // _fwscanf_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() { Sscanf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...) this.hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...) this.hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...) this.hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...) this.hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
) )
} }
@@ -91,10 +91,10 @@ class Snscanf extends ScanfFunction {
Snscanf() { Snscanf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...) this.hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...) this.hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...) this.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("_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 // 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. // limit used with non null-terminated strings.
) )
@@ -120,18 +120,18 @@ class ScanfFunctionCall extends FunctionCall {
/** /**
* Gets the `scanf`-like function that is called. * 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, * Gets the position at which the input string or stream parameter occurs,
* if this function call does not read from standard input. * 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. * 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. * 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 * Holds if the default meaning of `%s` is a `wchar_t*` string
* (rather than a `char*`). * (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 } ScanfFunctionCall getUse() { result.getFormat() = this }
/** Holds if the default meaning of `%s` is a `wchar_t*` (rather than a `char*`). */ /** 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: * Gets the format string itself, transformed as follows:

View File

@@ -40,8 +40,8 @@ abstract class MutexType extends Type {
* Gets a call that locks or tries to lock any mutex of this type. * Gets a call that locks or tries to lock any mutex of this type.
*/ */
FunctionCall getLockAccess() { FunctionCall getLockAccess() {
result = getMustlockAccess() or result = this.getMustlockAccess() or
result = getTrylockAccess() result = this.getTrylockAccess()
} }
/** /**
@@ -63,22 +63,22 @@ abstract class MutexType extends Type {
/** /**
* DEPRECATED: use mustlockAccess(fc, arg) instead. * 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: 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: 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: 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) { override predicate mustlockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = mustlockCandidate() and fc.getTarget() = mustlockCandidate() and
lockArgType(fc, arg) this.lockArgType(fc, arg)
} }
override predicate trylockAccess(FunctionCall fc, Expr arg) { override predicate trylockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = trylockCandidate() and fc.getTarget() = trylockCandidate() and
lockArgType(fc, arg) this.lockArgType(fc, arg)
} }
override predicate unlockAccess(FunctionCall fc, Expr arg) { override predicate unlockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = unlockCandidate() and fc.getTarget() = unlockCandidate() and
lockArgType(fc, arg) this.lockArgType(fc, arg)
} }
} }

View File

@@ -201,7 +201,7 @@ class BasicBlock extends ControlFlowNodeBase {
predicate hasLocationInfo( predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn 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] pragma[noinline]
@@ -276,7 +276,7 @@ class EntryBasicBlock extends BasicBlock {
*/ */
class ExitBasicBlock extends BasicBlock { class ExitBasicBlock extends BasicBlock {
ExitBasicBlock() { ExitBasicBlock() {
getEnd() instanceof Function or this.getEnd() instanceof Function or
aborting(getEnd()) aborting(this.getEnd())
} }
} }

View File

@@ -66,7 +66,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
*/ */
ControlFlowNode getATrueSuccessor() { ControlFlowNode getATrueSuccessor() {
qlCFGTrueSuccessor(this, result) and qlCFGTrueSuccessor(this, result) and
result = getASuccessor() result = this.getASuccessor()
} }
/** /**
@@ -75,7 +75,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
*/ */
ControlFlowNode getAFalseSuccessor() { ControlFlowNode getAFalseSuccessor() {
qlCFGFalseSuccessor(this, result) and qlCFGFalseSuccessor(this, result) and
result = getASuccessor() result = this.getASuccessor()
} }
/** Gets the `BasicBlock` containing this control-flow node. */ /** Gets the `BasicBlock` containing this control-flow node. */

View File

@@ -121,7 +121,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
exists(boolean testIsTrue | 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) { override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
exists(boolean testIsTrue | 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 { private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr {
GuardConditionFromShortCircuitNot() { GuardConditionFromShortCircuitNot() {
not exists(Instruction inst | this.getFullyConverted() = inst.getAST()) and 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) { 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) { 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) { 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) { 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) { 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 cached
predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) { predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
pred.getASuccessor() = succ and pred.getASuccessor() = succ and
controls(pred, testIsTrue) this.controls(pred, testIsTrue)
or or
succ = getBranchSuccessor(testIsTrue) and succ = this.getBranchSuccessor(testIsTrue) and
branch.getCondition() = this and branch.getCondition() = this and
branch.getBlock() = pred branch.getBlock() = pred
} }

View File

@@ -73,19 +73,19 @@ abstract deprecated class LocalScopeVariableReachability extends string {
*/ */
exists(BasicBlock bb, int i | exists(BasicBlock bb, int i |
isSource(source, v) and this.isSource(source, v) and
bb.getNode(i) = source and bb.getNode(i) = source and
not bb.isUnreachable() not bb.isUnreachable()
| |
exists(int j | exists(int j |
j > i and j > i and
sink = bb.getNode(j) and sink = bb.getNode(j) and
isSink(sink, v) and this.isSink(sink, v) and
not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1]) not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
) )
or or
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
bbSuccessorEntryReaches(bb, v, sink, _) this.bbSuccessorEntryReaches(bb, v, sink, _)
) )
} }
@@ -97,11 +97,11 @@ abstract deprecated class LocalScopeVariableReachability extends string {
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) succSkipsFirstLoopAlwaysTrueUponEntry)
| |
bbEntryReachesLocally(succ, v, node) and this.bbEntryReachesLocally(succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false succSkipsFirstLoopAlwaysTrueUponEntry = false
or or
not isBarrier(succ.getNode(_), v) and not this.isBarrier(succ.getNode(_), v) and
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
) )
} }
@@ -110,7 +110,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
) { ) {
exists(int n | exists(int n |
node = bb.getNode(n) and node = bb.getNode(n) and
isSink(node, v) this.isSink(node, v)
| |
not exists(this.firstBarrierIndexIn(bb, v)) not exists(this.firstBarrierIndexIn(bb, v))
or or
@@ -119,7 +119,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
} }
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) { 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. * accounts for loops where the condition is provably true upon entry.
*/ */
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { 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 ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
) { ) {
exists(ControlFlowNode def | exists(ControlFlowNode def |
actualSourceReaches(source, v, def, v0) and this.actualSourceReaches(source, v, def, v0) and
LocalScopeVariableReachability.super.reaches(def, v0, sink) and LocalScopeVariableReachability.super.reaches(def, v0, sink) and
isSinkActual(sink, v0) this.isSinkActual(sink, v0)
) )
} }
private predicate actualSourceReaches( private predicate actualSourceReaches(
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0 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 or
exists(ControlFlowNode source1, SemanticStackVariable v1 | 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) { final override predicate isSource(ControlFlowNode node, LocalScopeVariable v) {
isSourceActual(node, v) this.isSourceActual(node, v)
or or
// Reassignment generates a new (non-actual) source // Reassignment generates a new (non-actual) source
reassignment(_, _, node, v) this.reassignment(_, _, node, v)
} }
final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) { final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) {
isSinkActual(node, v) this.isSinkActual(node, v)
or or
// Reassignment generates a new (non-actual) sink // Reassignment generates a new (non-actual) sink
exprDefinition(_, node, v.getAnAccess()) exprDefinition(_, node, v.getAnAccess())
@@ -347,21 +347,21 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
/** See `LocalScopeVariableReachability.reaches`. */ /** See `LocalScopeVariableReachability.reaches`. */
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
exists(BasicBlock bb, int i | exists(BasicBlock bb, int i |
isSource(source, v) and this.isSource(source, v) and
bb.getNode(i) = source and bb.getNode(i) = source and
not bb.isUnreachable() not bb.isUnreachable()
| |
exists(int j | exists(int j |
j > i and j > i and
sink = bb.getNode(j) and sink = bb.getNode(j) and
isSink(sink, v) and this.isSink(sink, v) and
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
k in [i .. j - 1] k in [i .. j - 1]
) )
) )
or or
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
bbSuccessorEntryReaches(source, bb, v, sink, _) this.bbSuccessorEntryReaches(source, bb, v, sink, _)
) )
} }
@@ -372,22 +372,22 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry | exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) and 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 succSkipsFirstLoopAlwaysTrueUponEntry = false
or or
not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
) )
} }
private predicate bbEntryReachesLocally( private predicate bbEntryReachesLocally(
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
) { ) {
isSource(source, v) and this.isSource(source, v) and
exists(int n | node = bb.getNode(n) and isSink(node, v) | exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v)) not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
) )
} }
} }

View File

@@ -59,7 +59,7 @@ class SsaDefinition extends ControlFlowNodeBase {
ControlFlowNode getDefinition() { result = this } ControlFlowNode getDefinition() { result = this }
/** Gets the `BasicBlock` containing this definition. */ /** 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`. */ /** Holds if this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) } predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) }

View File

@@ -72,19 +72,19 @@ abstract class StackVariableReachability extends string {
*/ */
exists(BasicBlock bb, int i | exists(BasicBlock bb, int i |
isSource(source, v) and this.isSource(source, v) and
bb.getNode(i) = source and bb.getNode(i) = source and
not bb.isUnreachable() not bb.isUnreachable()
| |
exists(int j | exists(int j |
j > i and j > i and
sink = bb.getNode(j) and sink = bb.getNode(j) and
isSink(sink, v) and this.isSink(sink, v) and
not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1]) not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
) )
or or
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
bbSuccessorEntryReaches(bb, v, sink, _) this.bbSuccessorEntryReaches(bb, v, sink, _)
) )
} }
@@ -96,11 +96,11 @@ abstract class StackVariableReachability extends string {
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) succSkipsFirstLoopAlwaysTrueUponEntry)
| |
bbEntryReachesLocally(succ, v, node) and this.bbEntryReachesLocally(succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false succSkipsFirstLoopAlwaysTrueUponEntry = false
or or
not isBarrier(succ.getNode(_), v) and not this.isBarrier(succ.getNode(_), v) and
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
) )
} }
@@ -109,7 +109,7 @@ abstract class StackVariableReachability extends string {
) { ) {
exists(int n | exists(int n |
node = bb.getNode(n) and node = bb.getNode(n) and
isSink(node, v) this.isSink(node, v)
| |
not exists(this.firstBarrierIndexIn(bb, v)) not exists(this.firstBarrierIndexIn(bb, v))
or or
@@ -118,7 +118,7 @@ abstract class StackVariableReachability extends string {
} }
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) { 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. * accounts for loops where the condition is provably true upon entry.
*/ */
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { 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 ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
) { ) {
exists(ControlFlowNode def | exists(ControlFlowNode def |
actualSourceReaches(source, v, def, v0) and this.actualSourceReaches(source, v, def, v0) and
StackVariableReachability.super.reaches(def, v0, sink) and StackVariableReachability.super.reaches(def, v0, sink) and
isSinkActual(sink, v0) this.isSinkActual(sink, v0)
) )
} }
private predicate actualSourceReaches( private predicate actualSourceReaches(
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0 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 or
exists(ControlFlowNode source1, SemanticStackVariable v1 | 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) { final override predicate isSource(ControlFlowNode node, StackVariable v) {
isSourceActual(node, v) this.isSourceActual(node, v)
or or
// Reassignment generates a new (non-actual) source // Reassignment generates a new (non-actual) source
reassignment(_, _, node, v) this.reassignment(_, _, node, v)
} }
final override predicate isSink(ControlFlowNode node, StackVariable v) { final override predicate isSink(ControlFlowNode node, StackVariable v) {
isSinkActual(node, v) this.isSinkActual(node, v)
or or
// Reassignment generates a new (non-actual) sink // Reassignment generates a new (non-actual) sink
exprDefinition(_, node, v.getAnAccess()) exprDefinition(_, node, v.getAnAccess())
@@ -342,21 +342,21 @@ abstract class StackVariableReachabilityExt extends string {
/** See `StackVariableReachability.reaches`. */ /** See `StackVariableReachability.reaches`. */
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) { predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
exists(BasicBlock bb, int i | exists(BasicBlock bb, int i |
isSource(source, v) and this.isSource(source, v) and
bb.getNode(i) = source and bb.getNode(i) = source and
not bb.isUnreachable() not bb.isUnreachable()
| |
exists(int j | exists(int j |
j > i and j > i and
sink = bb.getNode(j) and sink = bb.getNode(j) and
isSink(sink, v) and this.isSink(sink, v) and
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
k in [i .. j - 1] k in [i .. j - 1]
) )
) )
or or
not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
bbSuccessorEntryReaches(source, bb, v, sink, _) this.bbSuccessorEntryReaches(source, bb, v, sink, _)
) )
} }
@@ -367,22 +367,22 @@ abstract class StackVariableReachabilityExt extends string {
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry | exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry, bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) and 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 succSkipsFirstLoopAlwaysTrueUponEntry = false
or or
not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry) this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
) )
} }
private predicate bbEntryReachesLocally( private predicate bbEntryReachesLocally(
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
) { ) {
isSource(source, v) and this.isSource(source, v) and
exists(int n | node = bb.getNode(n) and isSink(node, v) | exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v)) not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
) )
} }
} }

View File

@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based * returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position. * position.
*/ */
deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 } deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline] pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) } private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
exists(BasicBlock bb | exists(BasicBlock bb |
exists(int outerIndex | exists(int outerIndex |
result = bb.getNode(outerIndex) and result = bb.getNode(outerIndex) and
index = outerToInnerIndex(bb, outerIndex) index = this.outerToInnerIndex(bb, outerIndex)
) )
) )
} }

View File

@@ -385,7 +385,7 @@ library class ExprEvaluator extends int {
abstract predicate interesting(Expr e); abstract predicate interesting(Expr e);
/** Gets the value of (interesting) expression `e`, if any. */ /** 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 * When evaluating a syntactic subexpression of `e`, we may
@@ -425,9 +425,9 @@ library class ExprEvaluator extends int {
* calculates the values bottom-up. * calculates the values bottom-up.
*/ */
predicate interestingInternal(Expr e, Expr req, boolean sub) { 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 or
exists(Expr mid | interestingInternal(e, mid, sub) | exists(Expr mid | this.interestingInternal(e, mid, sub) |
req = mid.(NotExpr).getOperand() or req = mid.(NotExpr).getOperand() or
req = mid.(BinaryLogicalOperation).getAnOperand() or req = mid.(BinaryLogicalOperation).getAnOperand() or
req = mid.(RelationalOperation).getAnOperand() or req = mid.(RelationalOperation).getAnOperand() or
@@ -442,36 +442,36 @@ library class ExprEvaluator extends int {
) )
or or
exists(VariableAccess va, Variable v, boolean sub1 | exists(VariableAccess va, Variable v, boolean sub1 |
interestingVariableAccess(e, va, v, sub1) and this.interestingVariableAccess(e, va, v, sub1) and
req = v.getAnAssignedValue() 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 sub = false
) )
or or
exists(Function f | exists(Function f |
interestingFunction(e, f) and this.interestingFunction(e, f) and
returnStmt(f, req) and returnStmt(f, req) and
sub = false sub = false
) )
} }
private predicate interestingVariableAccess(Expr e, VariableAccess va, Variable v, boolean sub) { 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 = getVariableTarget(va) and
( (
v.hasInitializer() v.hasInitializer()
or or
sub = true and allowVariableWithoutInitializer(e, v) sub = true and this.allowVariableWithoutInitializer(e, v)
) and ) and
tractableVariable(v) and tractableVariable(v) and
forall(StmtParent def | nonAnalyzableVariableDefinition(v, def) | forall(StmtParent def | nonAnalyzableVariableDefinition(v, def) |
sub = true and sub = true and
ignoreNonAnalyzableVariableDefinition(e, v, def) this.ignoreNonAnalyzableVariableDefinition(e, v, def)
) )
} }
private predicate interestingFunction(Expr e, Function f) { private predicate interestingFunction(Expr e, Function f) {
exists(FunctionCall fc | interestingInternal(e, fc, _) | exists(FunctionCall fc | this.interestingInternal(e, fc, _) |
f = fc.getTarget() and f = fc.getTarget() and
not obviouslyNonConstant(f) and not obviouslyNonConstant(f) and
not f.getUnspecifiedType() instanceof VoidType 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. */ /** Gets the value of subexpressions `req` for expression `e`, if any. */
private int getValueInternal(Expr e, Expr req) { private int getValueInternal(Expr e, Expr req) {
( (
interestingInternal(e, req, true) and this.interestingInternal(e, req, true) and
( (
result = req.(CompileTimeConstantInt).getIntValue() or result = req.(CompileTimeConstantInt).getIntValue() or
result = getCompoundValue(e, req.(CompileTimeVariableExpr)) result = this.getCompoundValue(e, req.(CompileTimeVariableExpr))
) and ) and
( (
req.getUnderlyingType().(IntegralType).isSigned() or 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. */ /** Gets the value of compound subexpressions `val` for expression `e`, if any. */
private int getCompoundValue(Expr e, CompileTimeVariableExpr val) { private int getCompoundValue(Expr e, CompileTimeVariableExpr val) {
interestingInternal(e, val, true) and this.interestingInternal(e, val, true) and
( (
exists(NotExpr req | req = val | exists(NotExpr req | req = val |
result = 1 and getValueInternal(e, req.getOperand()) = 0 result = 1 and this.getValueInternal(e, req.getOperand()) = 0
or or
result = 0 and getValueInternal(e, req.getOperand()) != 0 result = 0 and this.getValueInternal(e, req.getOperand()) != 0
) )
or or
exists(LogicalAndExpr req | req = val | exists(LogicalAndExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) != 0 and this.getValueInternal(e, req.getLeftOperand()) != 0 and
getValueInternal(e, req.getRightOperand()) != 0 this.getValueInternal(e, req.getRightOperand()) != 0
or or
result = 0 and getValueInternal(e, req.getAnOperand()) = 0 result = 0 and this.getValueInternal(e, req.getAnOperand()) = 0
) )
or or
exists(LogicalOrExpr req | req = val | exists(LogicalOrExpr req | req = val |
result = 1 and getValueInternal(e, req.getAnOperand()) != 0 result = 1 and this.getValueInternal(e, req.getAnOperand()) != 0
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) = 0 and this.getValueInternal(e, req.getLeftOperand()) = 0 and
getValueInternal(e, req.getRightOperand()) = 0 this.getValueInternal(e, req.getRightOperand()) = 0
) )
or or
exists(LTExpr req | req = val | exists(LTExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) <
this.getValueInternal(e, req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) >=
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(GTExpr req | req = val | exists(GTExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) >
this.getValueInternal(e, req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) <=
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(LEExpr req | req = val | exists(LEExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) <=
this.getValueInternal(e, req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) >
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(GEExpr req | req = val | exists(GEExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) >=
this.getValueInternal(e, req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) <
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(EQExpr req | req = val | exists(EQExpr req | req = val |
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) =
this.getValueInternal(e, req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) !=
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(NEExpr req | req = val | exists(NEExpr req | req = val |
result = 0 and result = 0 and
getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) =
this.getValueInternal(e, req.getRightOperand())
or or
result = 1 and result = 1 and
getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) !=
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(AddExpr req | req = val | exists(AddExpr req | req = val |
result = result =
getValueInternal(e, req.getLeftOperand()) + getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) +
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(SubExpr req | req = val | exists(SubExpr req | req = val |
result = result =
getValueInternal(e, req.getLeftOperand()) - getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) -
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(MulExpr req | req = val | exists(MulExpr req | req = val |
result = result =
getValueInternal(e, req.getLeftOperand()) * getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) *
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(RemExpr req | req = val | exists(RemExpr req | req = val |
result = result =
getValueInternal(e, req.getLeftOperand()) % getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) %
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(DivExpr req | req = val | exists(DivExpr req | req = val |
result = result =
getValueInternal(e, req.getLeftOperand()) / getValueInternal(e, req.getRightOperand()) this.getValueInternal(e, req.getLeftOperand()) /
this.getValueInternal(e, req.getRightOperand())
) )
or or
exists(AssignExpr req | req = val | result = getValueInternal(e, req.getRValue())) exists(AssignExpr req | req = val | result = this.getValueInternal(e, req.getRValue()))
or or
result = getVariableValue(e, val.(VariableAccess)) result = this.getVariableValue(e, val.(VariableAccess))
or or
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) | 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] language[monotonicAggregates]
private int getVariableValue(Expr e, VariableAccess va) { private int getVariableValue(Expr e, VariableAccess va) {
exists(Variable v | exists(Variable v |
interestingVariableAccess(e, va, v, true) and this.interestingVariableAccess(e, va, v, true) and
// All assignments must have the same int value // All assignments must have the same int value
result = result =
unique(Expr value | 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`. */ /** Holds if the function `f` is considered by the analysis and may return `ret`. */
pragma[noinline] pragma[noinline]
private predicate interestingReturnValue(Function f, Expr ret) { private predicate interestingReturnValue(Function f, Expr ret) {
interestingFunction(_, f) and this.interestingFunction(_, f) and
returnStmt(f, ret) returnStmt(f, ret)
} }
private int getFunctionValue(Function f) { private int getFunctionValue(Function f) {
// All returns must have the same int value // All returns must have the same int value
// And it must have at least one return // 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). * omitted).
*/ */
private int getValueInternalNonSubExpr(Expr req) { private int getValueInternalNonSubExpr(Expr req) {
interestingInternal(_, req, false) and this.interestingInternal(_, req, false) and
( (
result = req.(CompileTimeConstantInt).getIntValue() or result = req.(CompileTimeConstantInt).getIntValue() or
result = getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr)) result = this.getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr))
) and ) and
( (
req.getUnderlyingType().(IntegralType).isSigned() or req.getUnderlyingType().(IntegralType).isSigned() or
@@ -655,131 +674,131 @@ library class ExprEvaluator extends int {
private int getCompoundValueNonSubExpr(CompileTimeVariableExpr val) { private int getCompoundValueNonSubExpr(CompileTimeVariableExpr val) {
( (
exists(NotExpr req | req = val | exists(NotExpr req | req = val |
result = 1 and getValueInternalNonSubExpr(req.getOperand()) = 0 result = 1 and this.getValueInternalNonSubExpr(req.getOperand()) = 0
or or
result = 0 and getValueInternalNonSubExpr(req.getOperand()) != 0 result = 0 and this.getValueInternalNonSubExpr(req.getOperand()) != 0
) )
or or
exists(LogicalAndExpr req | req = val | exists(LogicalAndExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and this.getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and
getValueInternalNonSubExpr(req.getRightOperand()) != 0 this.getValueInternalNonSubExpr(req.getRightOperand()) != 0
or or
result = 0 and getValueInternalNonSubExpr(req.getAnOperand()) = 0 result = 0 and this.getValueInternalNonSubExpr(req.getAnOperand()) = 0
) )
or or
exists(LogicalOrExpr req | req = val | exists(LogicalOrExpr req | req = val |
result = 1 and getValueInternalNonSubExpr(req.getAnOperand()) != 0 result = 1 and this.getValueInternalNonSubExpr(req.getAnOperand()) != 0
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and this.getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and
getValueInternalNonSubExpr(req.getRightOperand()) = 0 this.getValueInternalNonSubExpr(req.getRightOperand()) = 0
) )
or or
exists(LTExpr req | req = val | exists(LTExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) < this.getValueInternalNonSubExpr(req.getLeftOperand()) <
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) >= this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(GTExpr req | req = val | exists(GTExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) > this.getValueInternalNonSubExpr(req.getLeftOperand()) >
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) <= this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(LEExpr req | req = val | exists(LEExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) <= this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) > this.getValueInternalNonSubExpr(req.getLeftOperand()) >
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(GEExpr req | req = val | exists(GEExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) >= this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) < this.getValueInternalNonSubExpr(req.getLeftOperand()) <
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(EQExpr req | req = val | exists(EQExpr req | req = val |
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) = this.getValueInternalNonSubExpr(req.getLeftOperand()) =
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) != this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(NEExpr req | req = val | exists(NEExpr req | req = val |
result = 0 and result = 0 and
getValueInternalNonSubExpr(req.getLeftOperand()) = this.getValueInternalNonSubExpr(req.getLeftOperand()) =
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
or or
result = 1 and result = 1 and
getValueInternalNonSubExpr(req.getLeftOperand()) != this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(AddExpr req | req = val | exists(AddExpr req | req = val |
result = result =
getValueInternalNonSubExpr(req.getLeftOperand()) + this.getValueInternalNonSubExpr(req.getLeftOperand()) +
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(SubExpr req | req = val | exists(SubExpr req | req = val |
result = result =
getValueInternalNonSubExpr(req.getLeftOperand()) - this.getValueInternalNonSubExpr(req.getLeftOperand()) -
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(MulExpr req | req = val | exists(MulExpr req | req = val |
result = result =
getValueInternalNonSubExpr(req.getLeftOperand()) * this.getValueInternalNonSubExpr(req.getLeftOperand()) *
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(RemExpr req | req = val | exists(RemExpr req | req = val |
result = result =
getValueInternalNonSubExpr(req.getLeftOperand()) % this.getValueInternalNonSubExpr(req.getLeftOperand()) %
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(DivExpr req | req = val | exists(DivExpr req | req = val |
result = result =
getValueInternalNonSubExpr(req.getLeftOperand()) / this.getValueInternalNonSubExpr(req.getLeftOperand()) /
getValueInternalNonSubExpr(req.getRightOperand()) this.getValueInternalNonSubExpr(req.getRightOperand())
) )
or or
exists(AssignExpr req | req = val | result = getValueInternalNonSubExpr(req.getRValue())) exists(AssignExpr req | req = val | result = this.getValueInternalNonSubExpr(req.getRValue()))
or or
result = getVariableValueNonSubExpr(val.(VariableAccess)) result = this.getVariableValueNonSubExpr(val.(VariableAccess))
or or
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) | exists(FunctionCall call | call = val and not callWithMultipleTargets(call) |
result = getFunctionValue(call.getTarget()) result = this.getFunctionValue(call.getTarget())
) )
) )
} }
private int getVariableValueNonSubExpr(VariableAccess va) { private int getVariableValueNonSubExpr(VariableAccess va) {
// All assignments must have the same int value // All assignments must have the same int value
result = getMinVariableValueNonSubExpr(va) and result = this.getMinVariableValueNonSubExpr(va) and
result = getMaxVariableValueNonSubExpr(va) result = this.getMaxVariableValueNonSubExpr(va)
} }
/** /**
@@ -790,8 +809,9 @@ library class ExprEvaluator extends int {
pragma[noopt] pragma[noopt]
private int getMinVariableValueNonSubExpr(VariableAccess va) { private int getMinVariableValueNonSubExpr(VariableAccess va) {
exists(Variable v | exists(Variable v |
interestingVariableAccess(_, va, v, false) and this.interestingVariableAccess(_, va, v, false) and
result = min(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value)) result =
min(Expr value | value = v.getAnAssignedValue() | this.getValueInternalNonSubExpr(value))
) )
} }
@@ -803,8 +823,9 @@ library class ExprEvaluator extends int {
pragma[noopt] pragma[noopt]
private int getMaxVariableValueNonSubExpr(VariableAccess va) { private int getMaxVariableValueNonSubExpr(VariableAccess va) {
exists(Variable v | exists(Variable v |
interestingVariableAccess(_, va, v, false) and this.interestingVariableAccess(_, va, v, false) and
result = max(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value)) 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); abstract predicate isLoopBody(Expr e, StmtParent s);
private predicate isLoopBodyDescendant(Expr e, StmtParent s) { private predicate isLoopBodyDescendant(Expr e, StmtParent s) {
isLoopBody(e, s) this.isLoopBody(e, s)
or or
exists(StmtParent mid | isLoopBodyDescendant(e, mid) | exists(StmtParent mid | this.isLoopBodyDescendant(e, mid) |
s = mid.(Stmt).getAChild() or s = mid.(Stmt).getAChild() or
s = mid.(Expr).getAChild() s = mid.(Expr).getAChild()
) )
@@ -977,13 +998,13 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
// Same as `interestingInternal(e, sub, true)` but avoids negative recursion // Same as `interestingInternal(e, sub, true)` but avoids negative recursion
private predicate interestingSubExpr(Expr e, Expr sub) { private predicate interestingSubExpr(Expr e, Expr sub) {
interesting(e) and e = sub this.interesting(e) and e = sub
or 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) { 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`. * definition of `v`.
*/ */
private predicate reachesLoopEntryFromLoopBody(Expr e, Variable v, StmtParent valueOrDef) { 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 (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. * Use primitive basic blocks in reachability analysis for better performance.
* This is similar to the pattern used in e.g. `DefinitionsAndUses` and * 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 | exists(PrimitiveBasicBlock bb1, int pos1 | bb1.getNode(pos1) = valueOrDef |
// Reaches in same basic block // Reaches in same basic block
exists(int pos2 | exists(int pos2 |
loopEntryAt(bb1, pos2, e) and this.loopEntryAt(bb1, pos2, e) and
pos2 > pos1 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 or
// Reaches in a successor block // Reaches in a successor block
exists(PrimitiveBasicBlock bb2 | exists(PrimitiveBasicBlock bb2 |
bb2 = bb1.getASuccessor() and bb2 = bb1.getASuccessor() and
not exists(int pos3 | assignmentAt(bb1, pos3, v) and pos3 > pos1) and not exists(int pos3 | this.assignmentAt(bb1, pos3, v) and pos3 > pos1) and
bbReachesLoopEntry(bb2, e, v) this.bbReachesLoopEntry(bb2, e, v)
) )
) )
} }
@@ -1024,12 +1045,12 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
private predicate loopEntryAt(PrimitiveBasicBlock bb, int pos, Expr e) { private predicate loopEntryAt(PrimitiveBasicBlock bb, int pos, Expr e) {
exists(Node cfn | exists(Node cfn |
bb.getNode(pos) = cfn and bb.getNode(pos) = cfn and
isLoopEntry(e, cfn) this.isLoopEntry(e, cfn)
) )
} }
private predicate assignmentAt(PrimitiveBasicBlock bb, int pos, Variable v) { private predicate assignmentAt(PrimitiveBasicBlock bb, int pos, Variable v) {
maybeInterestingVariable(_, v) and this.maybeInterestingVariable(_, v) and
bb.getNode(pos) = v.getAnAssignedValue() 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`. * the loop belonging to `e` without crossing an assignment to `v`.
*/ */
private predicate bbReachesLoopEntry(PrimitiveBasicBlock bb, Expr e, Variable v) { private predicate bbReachesLoopEntry(PrimitiveBasicBlock bb, Expr e, Variable v) {
bbReachesLoopEntryLocally(bb, e, v) this.bbReachesLoopEntryLocally(bb, e, v)
or or
exists(PrimitiveBasicBlock succ | succ = bb.getASuccessor() | exists(PrimitiveBasicBlock succ | succ = bb.getASuccessor() |
bbReachesLoopEntry(succ, e, v) and this.bbReachesLoopEntry(succ, e, v) and
not assignmentAt(bb, _, v) not this.assignmentAt(bb, _, v)
) )
} }
private predicate bbReachesLoopEntryLocally(PrimitiveBasicBlock bb, Expr e, Variable v) { private predicate bbReachesLoopEntryLocally(PrimitiveBasicBlock bb, Expr e, Variable v) {
exists(int pos | exists(int pos |
loopEntryAt(bb, pos, e) and this.loopEntryAt(bb, pos, e) and
maybeInterestingVariable(e, v) and this.maybeInterestingVariable(e, v) and
not exists(int pos1 | assignmentAt(bb, pos1, v) | pos1 < pos) 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) { override predicate ignoreNonAnalyzableVariableDefinition(Expr e, Variable v, StmtParent def) {
maybeInterestingVariable(e, v) and this.maybeInterestingVariable(e, v) and
nonAnalyzableVariableDefinition(v, def) and nonAnalyzableVariableDefinition(v, def) and
isLoopBodyDescendant(e, def) and this.isLoopBodyDescendant(e, def) and
not reachesLoopEntryFromLoopBody(e, v, def) not this.reachesLoopEntryFromLoopBody(e, v, def)
} }
/** /**
@@ -1120,10 +1141,10 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
* ``` * ```
*/ */
override predicate ignoreVariableAssignment(Expr e, Variable v, Expr value) { override predicate ignoreVariableAssignment(Expr e, Variable v, Expr value) {
maybeInterestingVariable(e, v) and this.maybeInterestingVariable(e, v) and
value = v.getAnAssignedValue() and value = v.getAnAssignedValue() and
isLoopBodyDescendant(e, value) and this.isLoopBodyDescendant(e, value) and
not reachesLoopEntryFromLoopBody(e, v, value) not this.reachesLoopEntryFromLoopBody(e, v, value)
} }
} }

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -106,13 +106,13 @@ class Node extends TNode {
predicate hasLocationInfo( predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn 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. * 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(); 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 { abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
@@ -309,7 +309,7 @@ abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDef
PartialDefinition getPartialDefinition() { result = pd } 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 { private class VariablePartialDefinitionNode extends PartialDefinitionNode {
@@ -380,13 +380,13 @@ private class ObjectInitializerNode extends PostUpdateNode, TExprNode {
class PreObjectInitializerNode extends Node, TPreObjectInitializerNode { class PreObjectInitializerNode extends Node, TPreObjectInitializerNode {
Expr getExpr() { this = TPreObjectInitializerNode(result) } 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() { 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 { class PreConstructorInitThis extends Node, TPreConstructorInitThis {
ConstructorFieldInit getConstructorFieldInit() { this = TPreConstructorInitThis(result) } ConstructorFieldInit getConstructorFieldInit() { this = TPreConstructorInitThis(result) }
override Constructor getFunction() { result = getConstructorFieldInit().getEnclosingFunction() } override Constructor getFunction() {
result = this.getConstructorFieldInit().getEnclosingFunction()
override PointerType getType() {
result.getBaseType() = getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
} }
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]" }
} }
/** /**

View File

@@ -354,7 +354,7 @@ module FlowVar_internal {
result = def.getAUse(v) result = def.getAUse(v)
or or
exists(SsaDefinition descendentDef | exists(SsaDefinition descendentDef |
getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and this.getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and
result = descendentDef.getAUse(v) result = descendentDef.getAUse(v)
) )
) )
@@ -515,7 +515,7 @@ module FlowVar_internal {
this.bbInLoopCondition(bbInside) and this.bbInLoopCondition(bbInside) and
not this.bbInLoop(bbOutside) and not this.bbInLoop(bbOutside) and
bbOutside = bbInside.getASuccessor() 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) { private predicate bbInLoop(BasicBlock bb) {
bbDominates(this.(Loop).getStmt(), bb) bbDominates(this.(Loop).getStmt(), bb)
or or
bbInLoopCondition(bb) this.bbInLoopCondition(bb)
} }
/** Holds if `sbb` is inside this loop. */ /** Holds if `sbb` is inside this loop. */
@@ -563,7 +563,7 @@ module FlowVar_internal {
bb = this.(Loop).getStmt() and bb = this.(Loop).getStmt() and
v = this.getARelevantVariable() v = this.getARelevantVariable()
or or
reachesWithoutAssignment(bb.getAPredecessor(), v) and this.reachesWithoutAssignment(bb.getAPredecessor(), v) and
this.bbInLoop(bb) this.bbInLoop(bb)
) and ) and
not assignsToVar(bb, v) not assignsToVar(bb, v)

View File

@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based * returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position. * position.
*/ */
deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 } deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline] pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) } private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
exists(BasicBlock bb | exists(BasicBlock bb |
exists(int outerIndex | exists(int outerIndex |
result = bb.getNode(outerIndex) and result = bb.getNode(outerIndex) and
index = outerToInnerIndex(bb, outerIndex) index = this.outerToInnerIndex(bb, outerIndex)
) )
) )
} }

View File

@@ -203,7 +203,7 @@ class PointerFieldAccess extends FieldAccess {
PointerFieldAccess() { PointerFieldAccess() {
exists(PointerType t | exists(PointerType t |
t = getQualifier().getFullyConverted().getUnspecifiedType() and t = this.getQualifier().getFullyConverted().getUnspecifiedType() and
t.getBaseType() instanceof Class t.getBaseType() instanceof Class
) )
} }
@@ -218,7 +218,9 @@ class PointerFieldAccess extends FieldAccess {
class DotFieldAccess extends FieldAccess { class DotFieldAccess extends FieldAccess {
override string getAPrimaryQlClass() { result = "DotFieldAccess" } override string getAPrimaryQlClass() { result = "DotFieldAccess" }
DotFieldAccess() { exists(Class c | c = getQualifier().getFullyConverted().getUnspecifiedType()) } DotFieldAccess() {
exists(Class c | c = this.getQualifier().getFullyConverted().getUnspecifiedType())
}
} }
/** /**

View File

@@ -148,7 +148,7 @@ class PostfixIncrExpr extends IncrementOperation, PostfixCrementOperation, @post
override int getPrecedence() { result = 17 } 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 int getPrecedence() { result = 17 }
override string toString() { result = "... " + getOperator() } override string toString() { result = "... " + this.getOperator() }
} }
/** /**

View File

@@ -35,12 +35,12 @@ class BuiltInVarArgsStart extends VarArgsExpr, @vastartexpr {
/** /**
* Gets the `va_list` argument. * 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. * 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. * 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. * 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. * 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. * Gets the the source `va_list` argument.
*/ */
final Expr getSourceVAList() { result = getChild(1) } final Expr getSourceVAList() { result = this.getChild(1) }
} }
/** /**

View File

@@ -71,10 +71,10 @@ class Call extends Expr, NameQualifiableElement, TCall {
* at index 2, respectively. * at index 2, respectively.
*/ */
Expr getAnArgumentSubExpr(int index) { Expr getAnArgumentSubExpr(int index) {
result = getArgument(index) result = this.getArgument(index)
or or
exists(Expr mid | exists(Expr mid |
mid = getAnArgumentSubExpr(index) and mid = this.getAnArgumentSubExpr(index) and
not mid instanceof Call and not mid instanceof Call and
not mid instanceof SizeofOperator and not mid instanceof SizeofOperator and
result = mid.getAChild() result = mid.getAChild()
@@ -167,27 +167,27 @@ class FunctionCall extends Call, @funbindexpr {
override string getAPrimaryQlClass() { result = "FunctionCall" } override string getAPrimaryQlClass() { result = "FunctionCall" }
/** Gets an explicit template argument for this call. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** Gets the nth explicit template argument for this call. */
Locatable getExplicitTemplateArgument(int n) { Locatable getExplicitTemplateArgument(int n) {
n < getNumberOfExplicitTemplateArguments() and n < this.getNumberOfExplicitTemplateArguments() and
result = getTemplateArgument(n) result = this.getTemplateArgument(n)
} }
/** Gets the nth explicit template argument value for this call. */ /** Gets the nth explicit template argument value for this call. */
Locatable getExplicitTemplateArgumentKind(int n) { Locatable getExplicitTemplateArgumentKind(int n) {
n < getNumberOfExplicitTemplateArguments() and n < this.getNumberOfExplicitTemplateArguments() and
result = getTemplateArgumentKind(n) result = this.getTemplateArgumentKind(n)
} }
/** Gets the number of explicit template arguments for this call. */ /** 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. */ /** 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). */ /** 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). */ /** 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. */ /** Holds if any template arguments for this call are implicit / deduced. */
predicate hasImplicitTemplateArguments() { predicate hasImplicitTemplateArguments() {
exists(int i | exists(int i |
exists(getTemplateArgument(i)) and exists(this.getTemplateArgument(i)) and
not exists(getExplicitTemplateArgument(i)) not exists(this.getExplicitTemplateArgument(i))
) )
} }
@@ -233,9 +233,9 @@ class FunctionCall extends Call, @funbindexpr {
* visible at the call site. * visible at the call site.
*/ */
Type getExpectedReturnType() { Type getExpectedReturnType() {
if getTargetType() instanceof RoutineType if this.getTargetType() instanceof RoutineType
then result = getTargetType().(RoutineType).getReturnType() then result = this.getTargetType().(RoutineType).getReturnType()
else result = getTarget().getType() else result = this.getTarget().getType()
} }
/** /**
@@ -247,9 +247,9 @@ class FunctionCall extends Call, @funbindexpr {
* was visible at the call site. * was visible at the call site.
*/ */
Type getExpectedParameterType(int n) { Type getExpectedParameterType(int n) {
if getTargetType() instanceof RoutineType if this.getTargetType() instanceof RoutineType
then result = getTargetType().(RoutineType).getParameterType(n) then result = this.getTargetType().(RoutineType).getParameterType(n)
else result = getTarget().getParameter(n).getType() 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. * 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. * 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. */ /** Gets a textual representation of this function call. */
override string toString() { override string toString() {
if exists(getTarget()) if exists(this.getTarget())
then result = "call to " + this.getTarget().getName() then result = "call to " + this.getTarget().getName()
else result = "call to unknown function" else result = "call to unknown function"
} }
@@ -288,15 +288,15 @@ class FunctionCall extends Call, @funbindexpr {
override predicate mayBeImpure() { override predicate mayBeImpure() {
this.getChild(_).mayBeImpure() or this.getChild(_).mayBeImpure() or
this.getTarget().mayHaveSideEffects() or this.getTarget().mayHaveSideEffects() or
isVirtual() or this.isVirtual() or
getTarget().getAnAttribute().getName() = "weak" this.getTarget().getAnAttribute().getName() = "weak"
} }
override predicate mayBeGloballyImpure() { override predicate mayBeGloballyImpure() {
this.getChild(_).mayBeGloballyImpure() or this.getChild(_).mayBeGloballyImpure() or
this.getTarget().mayHaveSideEffects() or this.getTarget().mayHaveSideEffects() or
isVirtual() or this.isVirtual() or
getTarget().getAnAttribute().getName() = "weak" this.getTarget().getAnAttribute().getName() = "weak"
} }
} }
@@ -367,7 +367,7 @@ class OverloadedPointerDereferenceExpr extends FunctionCall {
* ``` * ```
*/ */
class OverloadedArrayExpr extends FunctionCall { class OverloadedArrayExpr extends FunctionCall {
OverloadedArrayExpr() { getTarget().hasName("operator[]") } OverloadedArrayExpr() { this.getTarget().hasName("operator[]") }
override string getAPrimaryQlClass() { result = "OverloadedArrayExpr" } override string getAPrimaryQlClass() { result = "OverloadedArrayExpr" }
@@ -585,7 +585,7 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
*/ */
Expr getExpr() { result = this.getChild(0) } 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() } override predicate mayBeImpure() { this.getExpr().mayBeImpure() }

View File

@@ -188,8 +188,8 @@ private predicate isPointerToMemberOrNullPointer(Type type) {
class ArithmeticConversion extends Cast { class ArithmeticConversion extends Cast {
ArithmeticConversion() { ArithmeticConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
isArithmeticOrEnum(getUnspecifiedType()) and isArithmeticOrEnum(this.getUnspecifiedType()) and
isArithmeticOrEnum(getExpr().getUnspecifiedType()) isArithmeticOrEnum(this.getExpr().getUnspecifiedType())
} }
override string getSemanticConversionString() { result = "arithmetic conversion" } override string getSemanticConversionString() { result = "arithmetic conversion" }
@@ -204,8 +204,8 @@ class ArithmeticConversion extends Cast {
*/ */
class IntegralConversion extends ArithmeticConversion { class IntegralConversion extends ArithmeticConversion {
IntegralConversion() { IntegralConversion() {
isIntegralOrEnum(getUnspecifiedType()) and isIntegralOrEnum(this.getUnspecifiedType()) and
isIntegralOrEnum(getExpr().getUnspecifiedType()) isIntegralOrEnum(this.getExpr().getUnspecifiedType())
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -224,8 +224,8 @@ class IntegralConversion extends ArithmeticConversion {
*/ */
class FloatingPointConversion extends ArithmeticConversion { class FloatingPointConversion extends ArithmeticConversion {
FloatingPointConversion() { FloatingPointConversion() {
getUnspecifiedType() instanceof FloatingPointType and this.getUnspecifiedType() instanceof FloatingPointType and
getExpr().getUnspecifiedType() instanceof FloatingPointType this.getExpr().getUnspecifiedType() instanceof FloatingPointType
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -244,8 +244,8 @@ class FloatingPointConversion extends ArithmeticConversion {
*/ */
class FloatingPointToIntegralConversion extends ArithmeticConversion { class FloatingPointToIntegralConversion extends ArithmeticConversion {
FloatingPointToIntegralConversion() { FloatingPointToIntegralConversion() {
isIntegralOrEnum(getUnspecifiedType()) and isIntegralOrEnum(this.getUnspecifiedType()) and
getExpr().getUnspecifiedType() instanceof FloatingPointType this.getExpr().getUnspecifiedType() instanceof FloatingPointType
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -264,8 +264,8 @@ class FloatingPointToIntegralConversion extends ArithmeticConversion {
*/ */
class IntegralToFloatingPointConversion extends ArithmeticConversion { class IntegralToFloatingPointConversion extends ArithmeticConversion {
IntegralToFloatingPointConversion() { IntegralToFloatingPointConversion() {
getUnspecifiedType() instanceof FloatingPointType and this.getUnspecifiedType() instanceof FloatingPointType and
isIntegralOrEnum(getExpr().getUnspecifiedType()) isIntegralOrEnum(this.getExpr().getUnspecifiedType())
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -290,8 +290,8 @@ class IntegralToFloatingPointConversion extends ArithmeticConversion {
class PointerConversion extends Cast { class PointerConversion extends Cast {
PointerConversion() { PointerConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
isPointerOrNullPointer(getUnspecifiedType()) and isPointerOrNullPointer(this.getUnspecifiedType()) and
isPointerOrNullPointer(getExpr().getUnspecifiedType()) isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
} }
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "PointerConversion" } override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "PointerConversion" }
@@ -315,8 +315,8 @@ class PointerToMemberConversion extends Cast {
PointerToMemberConversion() { PointerToMemberConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
exists(Type fromType, Type toType | exists(Type fromType, Type toType |
fromType = getExpr().getUnspecifiedType() and fromType = this.getExpr().getUnspecifiedType() and
toType = getUnspecifiedType() and toType = this.getUnspecifiedType() and
isPointerToMemberOrNullPointer(fromType) and isPointerToMemberOrNullPointer(fromType) and
isPointerToMemberOrNullPointer(toType) and isPointerToMemberOrNullPointer(toType) and
// A conversion from nullptr to nullptr is a `PointerConversion`, not a // A conversion from nullptr to nullptr is a `PointerConversion`, not a
@@ -345,8 +345,8 @@ class PointerToMemberConversion extends Cast {
class PointerToIntegralConversion extends Cast { class PointerToIntegralConversion extends Cast {
PointerToIntegralConversion() { PointerToIntegralConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
isIntegralOrEnum(getUnspecifiedType()) and isIntegralOrEnum(this.getUnspecifiedType()) and
isPointerOrNullPointer(getExpr().getUnspecifiedType()) isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -366,8 +366,8 @@ class PointerToIntegralConversion extends Cast {
class IntegralToPointerConversion extends Cast { class IntegralToPointerConversion extends Cast {
IntegralToPointerConversion() { IntegralToPointerConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
isPointerOrNullPointer(getUnspecifiedType()) and isPointerOrNullPointer(this.getUnspecifiedType()) and
isIntegralOrEnum(getExpr().getUnspecifiedType()) isIntegralOrEnum(this.getExpr().getUnspecifiedType())
} }
override string getAPrimaryQlClass() { override string getAPrimaryQlClass() {
@@ -403,7 +403,7 @@ class BoolConversion extends Cast {
class VoidConversion extends Cast { class VoidConversion extends Cast {
VoidConversion() { VoidConversion() {
conversionkinds(underlyingElement(this), 0) and conversionkinds(underlyingElement(this), 0) and
getUnspecifiedType() instanceof VoidType this.getUnspecifiedType() instanceof VoidType
} }
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "VoidConversion" } 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. * conversion is to an indirect virtual base class.
*/ */
final ClassDerivation getDerivation() { final ClassDerivation getDerivation() {
result.getBaseClass() = getBaseClass() and result.getBaseClass() = this.getBaseClass() and
result.getDerivedClass() = getDerivedClass() result.getDerivedClass() = this.getDerivedClass()
} }
/** /**
@@ -490,12 +490,12 @@ class BaseClassConversion extends InheritanceConversion {
override Class getBaseClass() { result = getConversionClass(this) } 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. * 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 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) } override Class getDerivedClass() { result = getConversionClass(this) }
} }
@@ -637,8 +637,8 @@ class DynamicCast extends Cast, @dynamic_cast {
*/ */
class UuidofOperator extends Expr, @uuidof { class UuidofOperator extends Expr, @uuidof {
override string toString() { override string toString() {
if exists(getTypeOperand()) if exists(this.getTypeOperand())
then result = "__uuidof(" + getTypeOperand().getName() + ")" then result = "__uuidof(" + this.getTypeOperand().getName() + ")"
else result = "__uuidof(0)" else result = "__uuidof(0)"
} }

View File

@@ -26,7 +26,7 @@ class Expr extends StmtParent, @expr {
Function getEnclosingFunction() { result = exprEnclosingElement(this) } Function getEnclosingFunction() { result = exprEnclosingElement(this) }
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */ /** 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() { override Stmt getEnclosingStmt() {
result = this.getParent().(Expr).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 * Holds if this expression is a _glvalue_. A _glvalue_ is either an _lvalue_ or an
* _xvalue_. * _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 * Holds if this expression is an _rvalue_. An _rvalue_ is either a _prvalue_ or an
* _xvalue_. * _xvalue_.
*/ */
predicate isRValueCategory() { isPRValueCategory() or isXValueCategory() } predicate isRValueCategory() { this.isPRValueCategory() or this.isXValueCategory() }
/** /**
* Gets a string representation of the value category of the expression. * Gets a string representation of the value category of the expression.
@@ -240,15 +240,15 @@ class Expr extends StmtParent, @expr {
* `hasLValueToRvalueConversion()` holds. * `hasLValueToRvalueConversion()` holds.
*/ */
string getValueCategoryString() { string getValueCategoryString() {
isLValueCategory() and this.isLValueCategory() and
result = "lvalue" result = "lvalue"
or or
isXValueCategory() and this.isXValueCategory() and
result = "xvalue" result = "xvalue"
or or
( (
isPRValueCategory() and this.isPRValueCategory() and
if hasLValueToRValueConversion() then result = "prvalue(load)" else result = "prvalue" 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. * such as an expression inside a sizeof.
*/ */
predicate isUnevaluated() { predicate isUnevaluated() {
exists(Element e | e = getParentWithConversions+() | exists(Element e | e = this.getParentWithConversions+() |
e instanceof SizeofOperator e instanceof SizeofOperator
or or
exists(Expr e2 | exists(Expr e2 |
@@ -279,7 +279,7 @@ class Expr extends StmtParent, @expr {
e instanceof AlignofOperator e instanceof AlignofOperator
) )
or 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. * Gets the expression that is being dereferenced.
*/ */
deprecated Expr getExpr() { result = getOperand() } deprecated Expr getExpr() { result = this.getOperand() }
override string getOperator() { result = "*" } 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. * Gets the alignment argument passed to the allocation function, if any.
*/ */
Expr getAlignmentArgument() { Expr getAlignmentArgument() {
hasAlignedAllocation() and this.hasAlignedAllocation() and
( (
// If we have an allocator call, the alignment is the second argument to // If we have an allocator call, the alignment is the second argument to
// that call. // that call.
result = getAllocatorCall().getArgument(1) result = this.getAllocatorCall().getArgument(1)
or or
// Otherwise, the alignment winds up as child number 3 of the `new` // Otherwise, the alignment winds up as child number 3 of the `new`
// itself. // 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. * Gets the element type of the array being allocated.
*/ */
Type getAllocatedElementType() { 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() { Type getDeletedObjectType() {
result = 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. * 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 * Gets the `operator delete` that deallocates storage. Does not hold
@@ -1020,7 +1025,12 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
*/ */
Type getDeletedElementType() { Type getDeletedElementType() {
result = 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. * 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. * Gets the `operator delete[]` that deallocates storage.
@@ -1101,7 +1111,7 @@ class StmtExpr extends Expr, @expr_stmt {
* x = ({ dosomething(); a+b; }); * 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.) */ /** 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) } predicate isRightFold() { fold(underlyingElement(this), _, false) }
/** Holds if this is a unary fold expression. */ /** 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. */ /** 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. * Gets the child expression containing the unexpanded parameter pack.
*/ */
Expr getPackExpr() { Expr getPackExpr() {
this.isUnaryFold() and this.isUnaryFold() and
result = getChild(0) result = this.getChild(0)
or or
this.isBinaryFold() and 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() { Expr getInitExpr() {
this.isBinaryFold() and 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)
} }
} }

View File

@@ -24,7 +24,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
/** /**
* Gets an implicitly or explicitly captured value of this lambda expression. * 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. * 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 return type.
* - The statements comprising the lambda body. * - 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. * 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. * 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 { class LambdaCapture extends Locatable, @lambdacapture {
override string toString() { result = getField().getName() } override string toString() { result = this.getField().getName() }
override string getAPrimaryQlClass() { result = "LambdaCapture" } override string getAPrimaryQlClass() { result = "LambdaCapture" }

View File

@@ -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). */ /** 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) { 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). */ /** 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) { 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) { string getANonStandardEscapeSequence(int occurrence, int offset) {
// Find all single character escape sequences (ignoring the start of octal escape sequences), // 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. // 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. // 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). */ /** 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) { 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). */ /** 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) { string getAStandardEscapeSequence(int occurrence, int offset) {
result = getASimpleEscapeSequence(occurrence, offset) or result = this.getASimpleEscapeSequence(occurrence, offset) or
result = getAnOctalEscapeSequence(occurrence, offset) or result = this.getAnOctalEscapeSequence(occurrence, offset) or
result = getAHexEscapeSequence(occurrence, offset) result = this.getAHexEscapeSequence(occurrence, offset)
} }
/** /**
* Gets the length of the string literal (including null) before escape sequences added by the extractor. * 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 // If the field has an explicit initializer expression, then the field is
// initialized. // initialized.
exists(getFieldExpr(field)) exists(this.getFieldExpr(field))
or or
// If the type is not a union, all fields without initializers are value // If the type is not a union, all fields without initializers are value
// initialized. // initialized.
@@ -224,7 +224,7 @@ class ClassAggregateLiteral extends AggregateLiteral {
or or
// If the type is a union, and there are no explicit initializers, then // If the type is a union, and there are no explicit initializers, then
// the first declared field is value initialized. // the first declared field is value initialized.
not exists(getAChild()) and not exists(this.getAChild()) and
field.getInitializationOrder() = 0 field.getInitializationOrder() = 0
) )
} }
@@ -239,8 +239,8 @@ class ClassAggregateLiteral extends AggregateLiteral {
*/ */
pragma[inline] pragma[inline]
predicate isValueInitialized(Field field) { predicate isValueInitialized(Field field) {
isInitialized(field) and this.isInitialized(field) and
not exists(getFieldExpr(field)) not exists(this.getFieldExpr(field))
} }
} }
@@ -285,7 +285,7 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
bindingset[elementIndex] bindingset[elementIndex]
predicate isInitialized(int elementIndex) { predicate isInitialized(int elementIndex) {
elementIndex >= 0 and elementIndex >= 0 and
elementIndex < getArraySize() elementIndex < this.getArraySize()
} }
/** /**
@@ -298,8 +298,8 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
*/ */
bindingset[elementIndex] bindingset[elementIndex]
predicate isValueInitialized(int elementIndex) { predicate isValueInitialized(int elementIndex) {
isInitialized(elementIndex) and this.isInitialized(elementIndex) and
not exists(getElementExpr(elementIndex)) not exists(this.getElementExpr(elementIndex))
} }
} }

View File

@@ -173,7 +173,7 @@ class LocalVariable extends LocalScopeVariable, @localvariable { }
class VariableDeclarationEntry extends @var_decl { class VariableDeclarationEntry extends @var_decl {
string toString() { result = "QualifiedName DeclarationEntry" } string toString() { result = "QualifiedName DeclarationEntry" }
Variable getDeclaration() { result = getVariable() } Variable getDeclaration() { result = this.getVariable() }
/** /**
* Gets the variable which is being declared or defined. * Gets the variable which is being declared or defined.

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * 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. * 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` * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -3170,7 +3170,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
} }
override string toString() { override string toString() {
result = "[" + this.toStringImpl(true) + length().toString() + ")]" result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or or
result = "[" + this.toStringImpl(false) result = "[" + this.toStringImpl(false)
} }
@@ -3309,9 +3309,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" 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( override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3379,11 +3381,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() { override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node // an intermediate step to another intermediate node
result = getSuccMid() result = this.getSuccMid()
or or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges // 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 | exists(PathNodeMid mid, PathNodeSink sink |
mid = getSuccMid() and mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and sink.getConfiguration() = unbindConf(mid.getConfiguration()) and

View File

@@ -110,7 +110,7 @@ class Node extends TIRDataFlowNode {
/** /**
* Gets an upper bound on the type of this node. * 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. */ /** Gets the location of this element. */
Location getLocation() { none() } // overridden by subclasses Location getLocation() { none() } // overridden by subclasses
@@ -831,7 +831,7 @@ class FieldContent extends Content, TFieldContent {
FieldContent() { this = TFieldContent(c, startBit, endBit) } FieldContent() { this = TFieldContent(c, startBit, endBit) }
// Ensure that there's just 1 result for `toString`. // 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 } predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }

View File

@@ -366,7 +366,7 @@ class MetricClass extends Class {
1 + 1 +
count(string s | count(string s |
exists(Operation op | op = this.getAnEnclosedExpression() and s = op.getOperator()) exists(Operation op | op = this.getAnEnclosedExpression() and s = op.getOperator())
) + count(string s | s = getAUsedHalsteadN1Operator()) ) + count(string s | s = this.getAUsedHalsteadN1Operator())
} }
/** /**

View File

@@ -134,7 +134,7 @@ class MetricFile extends File {
result = result =
// avoid 0 values // avoid 0 values
1 + count(string s | exists(Operation op | op.getFile() = this and s = op.getOperator())) + 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())
} }
/** /**

View File

@@ -41,7 +41,7 @@ class MetricFunction extends Function {
* `&&`, and `||`) plus one. * `&&`, and `||`) plus one.
*/ */
int getCyclomaticComplexity() { int getCyclomaticComplexity() {
result = 1 + cyclomaticComplexityBranches(getBlock()) and result = 1 + cyclomaticComplexityBranches(this.getBlock()) and
not this.isMultiplyDefined() not this.isMultiplyDefined()
} }
@@ -295,7 +295,7 @@ class MetricFunction extends Function {
int getNestingDepth() { int getNestingDepth() {
result = result =
max(Stmt s, int aDepth | s.getEnclosingFunction() = this and nestingDepth(s, aDepth) | aDepth) and max(Stmt s, int aDepth | s.getEnclosingFunction() = this and nestingDepth(s, aDepth) | aDepth) and
not isMultiplyDefined() not this.isMultiplyDefined()
} }
} }

View File

@@ -15,10 +15,10 @@ private class MallocAllocationFunction extends AllocationFunction {
MallocAllocationFunction() { MallocAllocationFunction() {
// --- C library allocation // --- C library allocation
hasGlobalOrStdOrBslName("malloc") and // malloc(size) this.hasGlobalOrStdOrBslName("malloc") and // malloc(size)
sizeArg = 0 sizeArg = 0
or or
hasGlobalName([ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers // --- Windows Memory Management for Windows Drivers
"MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress) "MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress)
"MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer) "MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
@@ -39,7 +39,7 @@ private class MallocAllocationFunction extends AllocationFunction {
]) and ]) and
sizeArg = 0 sizeArg = 0
or or
hasGlobalName([ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers // --- Windows Memory Management for Windows Drivers
"ExAllocatePool", // ExAllocatePool(type, size) "ExAllocatePool", // ExAllocatePool(type, size)
"ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag) "ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag)
@@ -56,10 +56,10 @@ private class MallocAllocationFunction extends AllocationFunction {
]) and ]) and
sizeArg = 1 sizeArg = 1
or or
hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size) this.hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
sizeArg = 2 sizeArg = 2
or or
hasGlobalName([ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers // --- Windows Memory Management for Windows Drivers
"MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size) "MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
"MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags) "MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
@@ -79,7 +79,7 @@ private class AllocaAllocationFunction extends AllocationFunction {
int sizeArg; int sizeArg;
AllocaAllocationFunction() { AllocaAllocationFunction() {
hasGlobalName([ this.hasGlobalName([
// --- stack allocation // --- stack allocation
"alloca", // // alloca(size) "alloca", // // alloca(size)
"__builtin_alloca", // __builtin_alloca(size) "__builtin_alloca", // __builtin_alloca(size)
@@ -104,7 +104,7 @@ private class CallocAllocationFunction extends AllocationFunction {
CallocAllocationFunction() { CallocAllocationFunction() {
// --- C library allocation // --- C library allocation
hasGlobalOrStdOrBslName("calloc") and // calloc(num, size) this.hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
sizeArg = 1 and sizeArg = 1 and
multArg = 0 multArg = 0
} }
@@ -124,11 +124,11 @@ private class ReallocAllocationFunction extends AllocationFunction {
ReallocAllocationFunction() { ReallocAllocationFunction() {
// --- C library allocation // --- C library allocation
hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size) this.hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
sizeArg = 1 and sizeArg = 1 and
reallocArg = 0 reallocArg = 0
or or
hasGlobalName([ this.hasGlobalName([
// --- Windows Global / Local legacy allocation // --- Windows Global / Local legacy allocation
"LocalReAlloc", // LocalReAlloc(ptr, size, flags) "LocalReAlloc", // LocalReAlloc(ptr, size, flags)
"GlobalReAlloc", // GlobalReAlloc(ptr, size, flags) "GlobalReAlloc", // GlobalReAlloc(ptr, size, flags)
@@ -140,7 +140,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
sizeArg = 1 and sizeArg = 1 and
reallocArg = 0 reallocArg = 0
or or
hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size) this.hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
sizeArg = 3 and sizeArg = 3 and
reallocArg = 2 reallocArg = 2
} }
@@ -156,7 +156,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
*/ */
private class SizelessAllocationFunction extends AllocationFunction { private class SizelessAllocationFunction extends AllocationFunction {
SizelessAllocationFunction() { SizelessAllocationFunction() {
hasGlobalName([ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers // --- Windows Memory Management for Windows Drivers
"ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list) "ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list)
"ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list) "ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list)
@@ -209,18 +209,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
AllocationFunction target; AllocationFunction target;
CallAllocationExpr() { CallAllocationExpr() {
target = getTarget() and target = this.getTarget() and
// realloc(ptr, 0) only frees the pointer // realloc(ptr, 0) only frees the pointer
not ( not (
exists(target.getReallocPtrArg()) and exists(target.getReallocPtrArg()) and
getArgument(target.getSizeArg()).getValue().toInt() = 0 this.getArgument(target.getSizeArg()).getValue().toInt() = 0
) and ) and
// these are modelled directly (and more accurately), avoid duplication // these are modelled directly (and more accurately), avoid duplication
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this) not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
} }
override Expr getSizeExpr() { override Expr getSizeExpr() {
exists(Expr sizeExpr | sizeExpr = getArgument(target.getSizeArg()) | exists(Expr sizeExpr | sizeExpr = this.getArgument(target.getSizeArg()) |
if exists(target.getSizeMult()) if exists(target.getSizeMult())
then result = sizeExpr then result = sizeExpr
else else
@@ -233,16 +233,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
override int getSizeMult() { override int getSizeMult() {
// malloc with multiplier argument that is a constant // malloc with multiplier argument that is a constant
result = getArgument(target.getSizeMult()).getValue().toInt() result = this.getArgument(target.getSizeMult()).getValue().toInt()
or or
// malloc with no multiplier argument // malloc with no multiplier argument
not exists(target.getSizeMult()) and 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() { override Type getAllocatedElementType() {
result = result =
@@ -259,11 +261,11 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
private class NewAllocationExpr extends AllocationExpr, NewExpr { private class NewAllocationExpr extends AllocationExpr, NewExpr {
NewAllocationExpr() { this instanceof 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() { override Expr getSizeExpr() {
// new array expr with variable size // new array expr with variable size
result = getExtent() result = this.getExtent()
} }
override int getSizeMult() { override int getSizeMult() {
// new array expr with variable size // new array expr with variable size
exists(getExtent()) and exists(this.getExtent()) and
result = getAllocatedElementType().getSize() result = this.getAllocatedElementType().getSize()
} }
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() } 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()) }
} }

View File

@@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FlowSource
*/ */
private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction,
RemoteFlowSourceFunction { RemoteFlowSourceFunction {
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) } GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) { override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
i.isParameter(3) and o.isParameterDeref(0) i.isParameter(3) and o.isParameterDeref(0)

View File

@@ -19,7 +19,7 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
// gets(str) // gets(str)
// fgets(str, num, stream) // fgets(str, num, stream)
// fgetws(wstr, num, stream) // fgetws(wstr, num, stream)
hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"]) this.hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
} }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { 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) { override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
not hasName("gets") and not this.hasName("gets") and
bufParam = 0 and bufParam = 0 and
countParam = 1 countParam = 1
} }
override predicate hasArrayWithUnknownSize(int bufParam) { override predicate hasArrayWithUnknownSize(int bufParam) {
hasName("gets") and this.hasName("gets") and
bufParam = 0 bufParam = 0
} }

View File

@@ -44,27 +44,27 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
*/ */
int getParamSize() { if this.hasGlobalName("memccpy") then result = 3 else result = 2 } 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) { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(getParamSrc()) and input.isParameterDeref(this.getParamSrc()) and
output.isParameterDeref(getParamDest()) output.isParameterDeref(this.getParamDest())
or or
input.isParameterDeref(getParamSrc()) and input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref() output.isReturnValueDeref()
or or
input.isParameter(getParamDest()) and input.isParameter(this.getParamDest()) and
output.isReturnValue() output.isReturnValue()
} }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) { override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
( (
bufParam = getParamDest() or bufParam = this.getParamDest() or
bufParam = getParamSrc() bufParam = this.getParamSrc()
) and ) and
countParam = getParamSize() countParam = this.getParamSize()
} }
override predicate hasOnlySpecificReadSideEffects() { any() } override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -72,37 +72,37 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = getParamDest() and i = this.getParamDest() and
buffer = true and buffer = true and
// memccpy only writes until a given character `c` is found // memccpy only writes until a given character `c` is found
(if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true) (if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true)
} }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = getParamSrc() and buffer = true i = this.getParamSrc() and buffer = true
} }
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
result = getParamSize() and result = this.getParamSize() and
( (
i = getParamDest() or i = this.getParamDest() or
i = getParamSrc() i = this.getParamSrc()
) )
} }
override predicate parameterNeverEscapes(int index) { override predicate parameterNeverEscapes(int index) {
index = getParamSrc() index = this.getParamSrc()
or or
this.hasGlobalName("bcopy") and index = getParamDest() this.hasGlobalName("bcopy") and index = this.getParamDest()
} }
override predicate parameterEscapesOnlyViaReturn(int index) { 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) { override predicate parameterIsAlwaysReturned(int index) {
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
index = getParamDest() index = this.getParamDest()
} }
} }

View File

@@ -31,17 +31,17 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override predicate hasArrayWithVariableSize(int bufParam, int countParam) { override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 0 and 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) { override predicate parameterEscapesOnlyViaReturn(int index) {
not hasGlobalName(bzero()) and index = 0 not this.hasGlobalName(bzero()) and index = 0
} }
override predicate parameterIsAlwaysReturned(int index) { override predicate parameterIsAlwaysReturned(int index) {
not hasGlobalName(bzero()) and index = 0 not this.hasGlobalName(bzero()) and index = 0
} }
override predicate hasOnlySpecificReadSideEffects() { any() } override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -54,7 +54,7 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
i = 0 and i = 0 and
if hasGlobalName(bzero()) then result = 1 else result = 2 if this.hasGlobalName(bzero()) then result = 1 else result = 2
} }
} }

View File

@@ -10,49 +10,49 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction { SideEffectFunction {
PureStrFunction() { PureStrFunction() {
hasGlobalOrStdOrBslName([ this.hasGlobalOrStdOrBslName([
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr", atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
"strspn", strtol(), strrev(), strcmp(), strlwr(), strupr() "strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
]) ])
} }
override predicate hasArrayInput(int bufParam) { override predicate hasArrayInput(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
} }
override predicate hasArrayWithNullTerminator(int bufParam) { override predicate hasArrayWithNullTerminator(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i | exists(ParameterIndex i |
( (
input.isParameter(i) and input.isParameter(i) and
exists(getParameter(i)) exists(this.getParameter(i))
or or
input.isParameterDeref(i) and input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType this.getParameter(i).getUnspecifiedType() instanceof PointerType
) and ) and
// Functions that end with _l also take a locale argument (always as the last argument), // Functions that end with _l also take a locale argument (always as the last argument),
// and we don't want taint from those arguments. // 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 ) and
( (
output.isReturnValueDeref() and output.isReturnValueDeref() and
getUnspecifiedType() instanceof PointerType this.getUnspecifiedType() instanceof PointerType
or or
output.isReturnValue() output.isReturnValue()
) )
} }
override predicate parameterNeverEscapes(int i) { override predicate parameterNeverEscapes(int i) {
getParameter(i).getUnspecifiedType() instanceof PointerType and this.getParameter(i).getUnspecifiedType() instanceof PointerType and
not parameterEscapesOnlyViaReturn(i) not this.parameterEscapesOnlyViaReturn(i)
} }
override predicate parameterEscapesOnlyViaReturn(int i) { override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and i = 0 and
getUnspecifiedType() instanceof PointerType this.getUnspecifiedType() instanceof PointerType
} }
override predicate parameterIsAlwaysReturned(int i) { none() } override predicate parameterIsAlwaysReturned(int i) { none() }
@@ -62,7 +62,7 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
getParameter(i).getUnspecifiedType() instanceof PointerType and this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true buffer = true
} }
} }
@@ -97,21 +97,21 @@ private string strcmp() {
*/ */
private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction { private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
StrLenFunction() { StrLenFunction() {
hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"]) this.hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
or or
hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"]) this.hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
} }
override predicate hasArrayInput(int bufParam) { override predicate hasArrayInput(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
} }
override predicate hasArrayWithNullTerminator(int bufParam) { override predicate hasArrayWithNullTerminator(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
} }
override predicate parameterNeverEscapes(int i) { override predicate parameterNeverEscapes(int i) {
getParameter(i).getUnspecifiedType() instanceof PointerType this.getParameter(i).getUnspecifiedType() instanceof PointerType
} }
override predicate parameterEscapesOnlyViaReturn(int i) { none() } override predicate parameterEscapesOnlyViaReturn(int i) { none() }
@@ -123,7 +123,7 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
getParameter(i).getUnspecifiedType() instanceof PointerType and this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true buffer = true
} }
} }
@@ -133,12 +133,12 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
* side-effect free. Excludes functions modeled by `PureStrFunction` and `PureMemFunction`. * side-effect free. Excludes functions modeled by `PureStrFunction` and `PureMemFunction`.
*/ */
private class PureFunction extends TaintFunction, SideEffectFunction { private class PureFunction extends TaintFunction, SideEffectFunction {
PureFunction() { hasGlobalOrStdOrBslName(["abs", "labs"]) } PureFunction() { this.hasGlobalOrStdOrBslName(["abs", "labs"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i | exists(ParameterIndex i |
input.isParameter(i) and input.isParameter(i) and
exists(getParameter(i)) exists(this.getParameter(i))
) and ) and
output.isReturnValue() output.isReturnValue()
} }
@@ -155,44 +155,44 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction, private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction { SideEffectFunction {
PureMemFunction() { PureMemFunction() {
hasGlobalOrStdOrBslName([ this.hasGlobalOrStdOrBslName([
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem" "memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"
]) or ]) or
this.hasGlobalName("memfrob") this.hasGlobalName("memfrob")
} }
override predicate hasArrayInput(int bufParam) { override predicate hasArrayInput(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i | exists(ParameterIndex i |
( (
input.isParameter(i) and input.isParameter(i) and
exists(getParameter(i)) exists(this.getParameter(i))
or or
input.isParameterDeref(i) and input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType this.getParameter(i).getUnspecifiedType() instanceof PointerType
) and ) and
// `memfrob` should not have taint from the size argument. // `memfrob` should not have taint from the size argument.
(not this.hasGlobalName("memfrob") or i = 0) (not this.hasGlobalName("memfrob") or i = 0)
) and ) and
( (
output.isReturnValueDeref() and output.isReturnValueDeref() and
getUnspecifiedType() instanceof PointerType this.getUnspecifiedType() instanceof PointerType
or or
output.isReturnValue() output.isReturnValue()
) )
} }
override predicate parameterNeverEscapes(int i) { override predicate parameterNeverEscapes(int i) {
getParameter(i).getUnspecifiedType() instanceof PointerType and this.getParameter(i).getUnspecifiedType() instanceof PointerType and
not parameterEscapesOnlyViaReturn(i) not this.parameterEscapesOnlyViaReturn(i)
} }
override predicate parameterEscapesOnlyViaReturn(int i) { override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and i = 0 and
getUnspecifiedType() instanceof PointerType this.getUnspecifiedType() instanceof PointerType
} }
override predicate parameterIsAlwaysReturned(int i) { none() } override predicate parameterIsAlwaysReturned(int i) { none() }
@@ -202,7 +202,7 @@ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
getParameter(i).getUnspecifiedType() instanceof PointerType and this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true buffer = true
} }
} }

View File

@@ -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. // since these just take a size argument, which we don't want to propagate taint through.
not this.isArray() and not this.isArray() and
( (
input.isParameter([0 .. getNumberOfParameters() - 1]) input.isParameter([0 .. this.getNumberOfParameters() - 1])
or or
input.isParameterDeref([0 .. getNumberOfParameters() - 1]) input.isParameterDeref([0 .. this.getNumberOfParameters() - 1])
) and ) and
output.isReturnValue() output.isReturnValue()
} }
@@ -116,14 +116,14 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
or or
// When taking ownership of a smart pointer via an rvalue reference, always overwrite the input // When taking ownership of a smart pointer via an rvalue reference, always overwrite the input
// smart pointer. // smart pointer.
getPointerInput().isParameterDeref(i) and this.getPointerInput().isParameterDeref(i) and
this.getParameter(i).getUnspecifiedType() instanceof RValueReferenceType and this.getParameter(i).getUnspecifiedType() instanceof RValueReferenceType and
buffer = false and buffer = false and
mustWrite = true mustWrite = true
} }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
getPointerInput().isParameterDeref(i) and this.getPointerInput().isParameterDeref(i) and
buffer = false buffer = false
or or
not this instanceof Constructor and not this instanceof Constructor and
@@ -136,7 +136,7 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
override predicate parameterEscapesOnlyViaReturn(int index) { none() } override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate hasAddressFlow(FunctionInput input, FunctionOutput output) { override predicate hasAddressFlow(FunctionInput input, FunctionOutput output) {
input = getPointerInput() and input = this.getPointerInput() and
output.isQualifierObject() output.isQualifierObject()
or or
// Assignment operator always returns a reference to `*this`. // Assignment operator always returns a reference to `*this`.

View File

@@ -23,15 +23,15 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
bufParam = this.(ScanfFunction).getInputParameterIndex() 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 getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() }
private int getLocaleParameterIndex() { private int getLocaleParameterIndex() {
this.getName().matches("%\\_l") and this.getName().matches("%\\_l") and
( (
if exists(getLengthParameterIndex()) if exists(this.getLengthParameterIndex())
then result = getLengthParameterIndex() + 2 then result = this.getLengthParameterIndex() + 2
else result = 2 else result = 2
) )
} }
@@ -40,11 +40,11 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and 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) { override predicate parameterNeverEscapes(int index) {
index = [0 .. max(getACallToThisFunction().getNumberOfArguments())] index = [0 .. max(this.getACallToThisFunction().getNumberOfArguments())]
} }
override predicate parameterEscapesOnlyViaReturn(int index) { none() } override predicate parameterEscapesOnlyViaReturn(int index) { none() }
@@ -56,7 +56,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i >= getArgsStartPosition() and i >= this.getArgsStartPosition() and
buffer = true and buffer = true and
mustWrite = true mustWrite = true
} }
@@ -66,7 +66,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
i = i =
[ [
this.(ScanfFunction).getInputParameterIndex(), this.(ScanfFunction).getInputParameterIndex(),
this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex() this.(ScanfFunction).getFormatParameterIndex(), this.getLocaleParameterIndex()
] ]
} }
} }

View File

@@ -61,20 +61,20 @@ private class StdSequenceContainerConstructor extends Constructor, TaintFunction
* value type of the container. * value type of the container.
*/ */
int getAValueTypeParameterIndex() { int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>` 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. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object // taint flow from any parameter of the value type to the returned object
( (
input.isParameterDeref(getAValueTypeParameterIndex()) or input.isParameterDeref(this.getAValueTypeParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
( (
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object 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. * value type of the container.
*/ */
int getAValueTypeParameterIndex() { int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>` 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. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to container itself (qualifier) and return value // flow from parameter to container itself (qualifier) and return value
( (
input.isQualifierObject() or input.isQualifierObject() or
input.isParameterDeref(getAValueTypeParameterIndex()) or input.isParameterDeref(this.getAValueTypeParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
( (
output.isQualifierObject() or output.isQualifierObject() or
@@ -197,20 +197,20 @@ private class StdSequenceContainerAssign extends TaintFunction {
* value type of the container. * value type of the container.
*/ */
int getAValueTypeParameterIndex() { int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>` 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. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to container itself (qualifier) // flow from parameter to container itself (qualifier)
( (
input.isParameterDeref(getAValueTypeParameterIndex()) or input.isParameterDeref(this.getAValueTypeParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
output.isQualifierObject() output.isQualifierObject()
} }
@@ -246,7 +246,7 @@ class StdVectorEmplace extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter except the position iterator to qualifier and return value // 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) // (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.isQualifierObject() or
output.isReturnValue() output.isReturnValue()
@@ -263,7 +263,7 @@ class StdVectorEmplaceBack extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter to qualifier // flow from any parameter to qualifier
// (here we assume taint flow from any constructor parameter to the constructed object) // (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() output.isQualifierObject()
} }
} }

View File

@@ -22,12 +22,12 @@ private class StdMapConstructor extends Constructor, TaintFunction {
* Gets the index of a parameter to this function that is an iterator. * Gets the index of a parameter to this function that is an iterator.
*/ */
int getAnIteratorParameterIndex() { int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator this.getParameter(result).getUnspecifiedType() instanceof Iterator
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier // 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 output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or or
@@ -47,7 +47,7 @@ private class StdMapInsert extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value // 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) // (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.isQualifierObject() or
output.isReturnValue() 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 // construct a pair, or a pair to be copied / moved) to the qualifier and
// return value. // return value.
// (where the return value is a pair, this should really flow just to the first part of it) // (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.isQualifierObject() or
output.isReturnValue() output.isReturnValue()
@@ -87,9 +87,9 @@ private class StdMapTryEmplace extends TaintFunction {
// flow from any parameter apart from the key to qualifier and return value // 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) // (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) // (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 arg != 1
) and ) and
input.isParameterDeref(arg) input.isParameterDeref(arg)
@@ -154,7 +154,7 @@ private class StdMapErase extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value // flow from qualifier to iterator return value
getType().getUnderlyingType() instanceof Iterator and this.getType().getUnderlyingType() instanceof Iterator and
input.isQualifierObject() and input.isQualifierObject() and
output.isReturnValue() output.isReturnValue()
} }

View File

@@ -51,13 +51,13 @@ private class StdPairConstructor extends Constructor, TaintFunction {
* either value type of the pair. * either value type of the pair.
*/ */
int getAValueTypeParameterIndex() { int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>` this.getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair<T1, T2>`
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from second parameter of a value type to the qualifier // taint flow from second parameter of a value type to the qualifier
getAValueTypeParameterIndex() = 1 and this.getAValueTypeParameterIndex() = 1 and
input.isParameterDeref(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 output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object

View File

@@ -22,12 +22,12 @@ private class StdSetConstructor extends Constructor, TaintFunction {
* Gets the index of a parameter to this function that is an iterator. * Gets the index of a parameter to this function that is an iterator.
*/ */
int getAnIteratorParameterIndex() { int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator this.getParameter(result).getUnspecifiedType() instanceof Iterator
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier // 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 output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or or
@@ -45,7 +45,7 @@ private class StdSetInsert extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value // 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) // (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.isQualifierObject() or
output.isReturnValue() output.isReturnValue()
@@ -63,7 +63,7 @@ private class StdSetEmplace extends TaintFunction {
// flow from any parameter to qualifier and return value // flow from any parameter to qualifier and return value
// (here we assume taint flow from any constructor parameter to the constructed object) // (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) // (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.isQualifierObject() or
output.isReturnValue() output.isReturnValue()
@@ -107,7 +107,7 @@ private class StdSetErase extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value // flow from qualifier to iterator return value
getType().getUnderlyingType() instanceof Iterator and this.getType().getUnderlyingType() instanceof Iterator and
input.isQualifierObject() and input.isQualifierObject() and
output.isReturnValue() output.isReturnValue()
} }

View File

@@ -31,31 +31,31 @@ private class StdStringConstructor extends Constructor, TaintFunction {
* character). * character).
*/ */
int getAStringParameterIndex() { int getAStringParameterIndex() {
exists(Type paramType | paramType = getParameter(result).getUnspecifiedType() | exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() |
// e.g. `std::basic_string::CharT *` // e.g. `std::basic_string::CharT *`
paramType instanceof PointerType paramType instanceof PointerType
or or
// e.g. `std::basic_string &`, avoiding `const Allocator&` // e.g. `std::basic_string &`, avoiding `const Allocator&`
paramType instanceof ReferenceType and paramType instanceof ReferenceType and
not paramType.(ReferenceType).getBaseType() = not paramType.(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType() this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
or or
// i.e. `std::basic_string::CharT` // i.e. `std::basic_string::CharT`
getParameter(result).getUnspecifiedType() = this.getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
) )
} }
/** /**
* Gets the index of a parameter to this function that is an iterator. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object // taint flow from any parameter of the value type to the returned object
( (
input.isParameterDeref(getAStringParameterIndex()) or input.isParameterDeref(this.getAStringParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
( (
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object 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). * character).
*/ */
int getAStringParameterIndex() { int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *` this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &` this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
getParameter(result).getUnspecifiedType() = this.getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT` 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. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value // flow from string and parameter to string (qualifier) and return value
( (
input.isQualifierObject() or input.isQualifierObject() or
input.isParameterDeref(getAStringParameterIndex()) or input.isParameterDeref(this.getAStringParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
( (
output.isQualifierObject() or output.isQualifierObject() or
@@ -197,22 +197,22 @@ private class StdStringAssign extends TaintFunction {
* character). * character).
*/ */
int getAStringParameterIndex() { int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *` this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &` this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
getParameter(result).getUnspecifiedType() = this.getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT` 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. * 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value // flow from parameter to string itself (qualifier) and return value
( (
input.isParameterDeref(getAStringParameterIndex()) or input.isParameterDeref(this.getAStringParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex()) input.isParameter(this.getAnIteratorParameterIndex())
) and ) and
( (
output.isQualifierObject() or 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. * Gets the index of a parameter to this function that is a string.
*/ */
int getAStringParameterIndex() { 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of string type to the returned object // 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 output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or or

View File

@@ -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). * 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. * 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) { 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 input.isParameter(2) and
output.isParameterDeref(0) output.isParameterDeref(0)
or or
getName() = ["_mbsncat_l", "_mbsnbcat_l"] and this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
input.isParameter(3) and input.isParameter(3) and
output.isParameterDeref(0) output.isParameterDeref(0)
or or

View File

@@ -45,22 +45,22 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
) and ) and
// exclude the 2-parameter template versions // exclude the 2-parameter template versions
// that find the size of a fixed size destination buffer. // 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. * 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). * Gets the index of the parameter that is the maximum size of the copy (in characters).
*/ */
int getParamSize() { int getParamSize() {
if isSVariant() if this.isSVariant()
then result = 1 then result = 1
else ( else (
getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
result = 2 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. * 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. * Gets the index of the parameter that is the destination of the copy.
*/ */
int getParamDest() { result = 0 } 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) { override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = getParamDest() and bufParam = this.getParamDest() and
countParam = getParamSize() countParam = this.getParamSize()
} }
override predicate hasArrayWithUnknownSize(int bufParam) { override predicate hasArrayWithUnknownSize(int bufParam) {
not exists(getParamSize()) and not exists(this.getParamSize()) and
bufParam = getParamDest() bufParam = this.getParamDest()
} }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
not exists(getParamSize()) and not exists(this.getParamSize()) and
input.isParameterDeref(getParamSrc()) and input.isParameterDeref(this.getParamSrc()) and
output.isParameterDeref(getParamDest()) output.isParameterDeref(this.getParamDest())
or or
not exists(getParamSize()) and not exists(this.getParamSize()) and
input.isParameterDeref(getParamSrc()) and input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref() output.isReturnValueDeref()
or or
input.isParameter(getParamDest()) and input.isParameter(this.getParamDest()) and
output.isReturnValue() output.isReturnValue()
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// these may do only a partial copy of the input buffer to the output // these may do only a partial copy of the input buffer to the output
// buffer // buffer
exists(getParamSize()) and exists(this.getParamSize()) and
input.isParameter(getParamSrc()) and input.isParameter(this.getParamSrc()) and
( (
output.isParameterDeref(getParamDest()) or output.isParameterDeref(this.getParamDest()) or
output.isReturnValueDeref() output.isReturnValueDeref()
) )
} }
@@ -120,18 +120,18 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = getParamDest() and i = this.getParamDest() and
buffer = true and buffer = true and
mustWrite = false mustWrite = false
} }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = getParamSrc() and i = this.getParamSrc() and
buffer = true buffer = true
} }
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
i = getParamDest() and i = this.getParamDest() and
result = getParamSize() result = this.getParamSize()
} }
} }

View File

@@ -29,10 +29,10 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType 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) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(int index | hasArrayInput(index) | exists(int index | this.hasArrayInput(index) |
input.isParameter(index) and output.isReturnValue() input.isParameter(index) and output.isReturnValue()
or or
input.isParameterDeref(index) and output.isReturnValueDeref() input.isParameterDeref(index) and output.isReturnValueDeref()
@@ -44,6 +44,6 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
hasArrayInput(i) and buffer = true this.hasArrayInput(i) and buffer = true
} }
} }

View File

@@ -31,7 +31,7 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
this.hasName("swap") and this.hasName("swap") and
this.getNumberOfParameters() = 1 and this.getNumberOfParameters() = 1 and
this.getParameter(0).getType().(ReferenceType).getBaseType().getUnspecifiedType() = this.getParameter(0).getType().(ReferenceType).getBaseType().getUnspecifiedType() =
getDeclaringType() this.getDeclaringType()
} }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -44,7 +44,7 @@ class FunctionInput extends TFunctionInput {
* Holds if this is the input value of the parameter with index `index`. * Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead. * 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 * 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`. * `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead. * 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 * 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. * function.
* DEPRECATED: Use `isQualifierObject()` instead. * 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. * 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`. * index `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead. * 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 * 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. * function.
* DEPRECATED: Use `isQualifierObject()` instead. * 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. * 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. * Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead. * 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 * 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. * function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead. * 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 * Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or

View File

@@ -72,7 +72,7 @@ abstract class Architecture extends string {
or or
t instanceof CharType and result = 8 t instanceof CharType and result = 8
or or
t instanceof WideCharType and result = wideCharSize() t instanceof WideCharType and result = this.wideCharSize()
or or
t instanceof Char8Type and result = 8 t instanceof Char8Type and result = 8
or or
@@ -84,22 +84,22 @@ abstract class Architecture extends string {
or or
t instanceof IntType and result = 32 t instanceof IntType and result = 32
or or
t instanceof LongType and result = longSize() t instanceof LongType and result = this.longSize()
or or
t instanceof LongLongType and result = longLongSize() t instanceof LongLongType and result = this.longLongSize()
or or
result = enumBitSize(t.(Enum)) result = this.enumBitSize(t.(Enum))
or or
result = integralBitSize(t.(SpecifiedType).getBaseType()) result = this.integralBitSize(t.(SpecifiedType).getBaseType())
or or
result = integralBitSize(t.(TypedefType).getBaseType()) result = this.integralBitSize(t.(TypedefType).getBaseType())
} }
/** /**
* Gets the bit size of enum type `e`. * Gets the bit size of enum type `e`.
*/ */
int enumBitSize(Enum e) { int enumBitSize(Enum e) {
result = integralBitSize(e.getExplicitUnderlyingType()) result = this.integralBitSize(e.getExplicitUnderlyingType())
or or
not exists(e.getExplicitUnderlyingType()) and result = 32 not exists(e.getExplicitUnderlyingType()) and result = 32
} }
@@ -108,7 +108,7 @@ abstract class Architecture extends string {
* Gets the alignment of enum type `e`. * Gets the alignment of enum type `e`.
*/ */
int enumAlignment(Enum e) { int enumAlignment(Enum e) {
result = alignment(e.getExplicitUnderlyingType()) result = this.alignment(e.getExplicitUnderlyingType())
or or
not exists(e.getExplicitUnderlyingType()) and result = 32 not exists(e.getExplicitUnderlyingType()) and result = 32
} }
@@ -120,26 +120,26 @@ abstract class Architecture extends string {
*/ */
cached cached
int bitSize(Type t) { int bitSize(Type t) {
result = integralBitSize(t) result = this.integralBitSize(t)
or or
t instanceof FloatType and result = 32 t instanceof FloatType and result = 32
or or
t instanceof DoubleType and result = 64 t instanceof DoubleType and result = 64
or or
t instanceof LongDoubleType and result = longDoubleSize() t instanceof LongDoubleType and result = this.longDoubleSize()
or or
t instanceof PointerType and result = pointerSize() t instanceof PointerType and result = this.pointerSize()
or or
t instanceof ReferenceType and result = pointerSize() t instanceof ReferenceType and result = this.pointerSize()
or or
t instanceof FunctionPointerType and result = pointerSize() t instanceof FunctionPointerType and result = this.pointerSize()
or or
result = bitSize(t.(SpecifiedType).getBaseType()) result = this.bitSize(t.(SpecifiedType).getBaseType())
or or
result = bitSize(t.(TypedefType).getBaseType()) result = this.bitSize(t.(TypedefType).getBaseType())
or or
exists(ArrayType array | array = t | exists(ArrayType array | array = t |
result = array.getArraySize() * paddedSize(array.getBaseType()) result = array.getArraySize() * this.paddedSize(array.getBaseType())
) )
or or
result = t.(PaddedType).typeBitSize(this) result = t.(PaddedType).typeBitSize(this)
@@ -155,7 +155,7 @@ abstract class Architecture extends string {
or or
t instanceof CharType and result = 8 t instanceof CharType and result = 8
or or
t instanceof WideCharType and result = wideCharSize() t instanceof WideCharType and result = this.wideCharSize()
or or
t instanceof Char8Type and result = 8 t instanceof Char8Type and result = 8
or or
@@ -169,27 +169,27 @@ abstract class Architecture extends string {
or or
t instanceof FloatType and result = 32 t instanceof FloatType and result = 32
or or
t instanceof DoubleType and result = doubleAlign() t instanceof DoubleType and result = this.doubleAlign()
or or
t instanceof LongType and result = longSize() t instanceof LongType and result = this.longSize()
or or
t instanceof LongDoubleType and result = longDoubleAlign() t instanceof LongDoubleType and result = this.longDoubleAlign()
or or
t instanceof LongLongType and result = longLongAlign() t instanceof LongLongType and result = this.longLongAlign()
or or
t instanceof PointerType and result = pointerSize() t instanceof PointerType and result = this.pointerSize()
or or
t instanceof FunctionPointerType and result = pointerSize() t instanceof FunctionPointerType and result = this.pointerSize()
or or
t instanceof ReferenceType and result = pointerSize() t instanceof ReferenceType and result = this.pointerSize()
or or
result = enumAlignment(t.(Enum)) result = this.enumAlignment(t.(Enum))
or or
result = alignment(t.(SpecifiedType).getBaseType()) result = this.alignment(t.(SpecifiedType).getBaseType())
or or
result = alignment(t.(TypedefType).getBaseType()) result = this.alignment(t.(TypedefType).getBaseType())
or or
result = alignment(t.(ArrayType).getBaseType()) result = this.alignment(t.(ArrayType).getBaseType())
or or
result = t.(PaddedType).typeAlignment(this) result = t.(PaddedType).typeAlignment(this)
} }
@@ -203,7 +203,7 @@ abstract class Architecture extends string {
exists(Type realType | realType = stripSpecifiers(t) | exists(Type realType | realType = stripSpecifiers(t) |
if realType instanceof PaddedType if realType instanceof PaddedType
then result = realType.(PaddedType).paddedSize(this) 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 * Gets the number of bits wasted by padding at the end of this
* struct. * 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. * 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 * laid out one after another, and hence there is no padding between
* them. * 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 * 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) { private int fieldDataSize(Architecture arch) {
if this instanceof Union if this instanceof Union
then result = max(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() | 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. * reorganizing member structs' field layouts.
*/ */
int optimalSize(Architecture arch) { 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 // but that uses a recursive aggregate, which isn't supported in
// QL. We therefore use this slightly more complex implementation // QL. We therefore use this slightly more complex implementation
// instead. // instead.
result = biggestFieldSizeUpTo(lastFieldIndex(), arch) result = this.biggestFieldSizeUpTo(this.lastFieldIndex(), arch)
else else
// If we're not a union type, the size is the padded // If we're not a union type, the size is the padded
// sum of field sizes, 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 if index = 0
then result = 0 then result = 0
else else
exists(Field f, int fSize | index = fieldIndex(f) and fSize = fieldSize(f, arch) | exists(Field f, int fSize | index = this.fieldIndex(f) and fSize = this.fieldSize(f, arch) |
result = fSize.maximum(biggestFieldSizeUpTo(index - 1, arch)) result = fSize.maximum(this.biggestFieldSizeUpTo(index - 1, arch))
) )
} }
@@ -536,8 +536,10 @@ class PaddedType extends Class {
if index = 0 if index = 0
then result = 1 // Minimum possible alignment then result = 1 // Minimum possible alignment
else else
exists(Field f, int fAlign | index = fieldIndex(f) and fAlign = arch.alignment(f.getType()) | exists(Field f, int fAlign |
result = fAlign.maximum(biggestAlignmentUpTo(index - 1, arch)) 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. * Gets the 1-based index for each field.
*/ */
int fieldIndex(Field f) { 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. * Gets the 1-based index for the last field.
*/ */
int lastFieldIndex() { int lastFieldIndex() {
if exists(lastField()) if exists(this.lastField())
then result = fieldIndex(lastField()) then result = this.fieldIndex(this.lastField())
else else
// Field indices are 1-based, so return 0 to represent the lack of fields. // Field indices are 1-based, so return 0 to represent the lack of fields.
result = 0 result = 0
@@ -566,25 +569,27 @@ class PaddedType extends Class {
* `arch`. * `arch`.
*/ */
int fieldSize(Field f, Architecture arch) { int fieldSize(Field f, Architecture arch) {
exists(fieldIndex(f)) and exists(this.fieldIndex(f)) and
if f instanceof BitField if f instanceof BitField
then result = f.(BitField).getNumBits() then result = f.(BitField).getNumBits()
else result = arch.paddedSize(f.getType()) else result = arch.paddedSize(f.getType())
} }
/** Gets the last field of this type. */ /** 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 * Gets the offset, in bits, of the end of the class' last base class
* subobject, or zero if the class has no base classes. * subobject, or zero if the class has no base classes.
*/ */
int baseClassEnd(Architecture arch) { 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. */ /** 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 * Gets the 0-based offset, in bits, of the first free bit after
@@ -596,13 +601,13 @@ class PaddedType extends Class {
then then
// Base case: No fields seen yet, so return the offset of the end of the // Base case: No fields seen yet, so return the offset of the end of the
// base class subojects. // base class subojects.
result = baseClassEnd(arch) result = this.baseClassEnd(arch)
else else
exists(Field f | index = fieldIndex(f) | exists(Field f | index = this.fieldIndex(f) |
exists(int fSize | fSize = fieldSize(f, arch) | exists(int fSize | fSize = this.fieldSize(f, arch) |
// Recursive case: Take previous field's end point, pad and add // Recursive case: Take previous field's end point, pad and add
// this field's size // 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 if f instanceof BitField
then then
// Bitfield packing: // Bitfield packing:
@@ -629,9 +634,11 @@ class PaddedType extends Class {
// No additional restrictions, so just pack it in with no padding. // No additional restrictions, so just pack it in with no padding.
result = firstFree + fSize result = firstFree + fSize
) else ( ) else (
if exists(bitFieldAt(index - 1)) if exists(this.bitFieldAt(index - 1))
then then
exists(BitField previousBitField | previousBitField = bitFieldAt(index - 1) | exists(BitField previousBitField |
previousBitField = this.bitFieldAt(index - 1)
|
// Previous field was a bitfield. // Previous field was a bitfield.
if if
nextSizeofBoundary >= (firstFree + fSize) and nextSizeofBoundary >= (firstFree + fSize) and

View File

@@ -88,7 +88,7 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
ControlFlowNode getDefinition() { result = this } ControlFlowNode getDefinition() { result = this }
/** Gets the basic block containing this definition. */ /** 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`. */ /** Whether this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) } predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }

View File

@@ -127,17 +127,22 @@ private string getValue(Expr e) {
private class UnsignedBitwiseAndExpr extends BitwiseAndExpr { private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
UnsignedBitwiseAndExpr() { UnsignedBitwiseAndExpr() {
( (
getLeftOperand().getFullyConverted().getType().getUnderlyingType().(IntegralType).isUnsigned() or this.getLeftOperand()
getValue(getLeftOperand().getFullyConverted()).toInt() >= 0
) and
(
getRightOperand()
.getFullyConverted() .getFullyConverted()
.getType() .getType()
.getUnderlyingType() .getUnderlyingType()
.(IntegralType) .(IntegralType)
.isUnsigned() or .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
) )
} }
} }

View File

@@ -77,21 +77,21 @@ abstract class BufferWrite extends Expr {
* much smaller (8 bytes) than their true maximum length. This can be * much smaller (8 bytes) than their true maximum length. This can be
* helpful in determining the cause of a buffer overflow issue. * 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 * Gets the size of a single character of the type this
* operation works with, in bytes. * operation works with, in bytes.
*/ */
int getCharSize() { int getCharSize() {
result = getBufferType().(PointerType).getBaseType().getSize() or result = this.getBufferType().(PointerType).getBaseType().getSize() or
result = getBufferType().(ArrayType).getBaseType().getSize() result = this.getBufferType().(ArrayType).getBaseType().getSize()
} }
/** /**
* Gets a description of this buffer write. * 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 { class StrCopyBW extends BufferWriteCall {
StrcpyFunction f; 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). * 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() } int getParamSrc() { result = f.getParamSrc() }
override Type getBufferType() { 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() { override int getExplicitLimit() {
result = getArgument(getParamSize()).getValue().toInt() * getCharSize() result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
} }
override int getMaxData() { 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 { class StrCatBW extends BufferWriteCall {
StrcatFunction f; 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). * 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() } int getParamSrc() { result = f.getParamSrc() }
override Type getBufferType() { 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() { override int getExplicitLimit() {
result = getArgument(getParamSize()).getValue().toInt() * getCharSize() result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
} }
override int getMaxData() { 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; FormattingFunction f;
SprintfBW() { 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: * C sprintf variants:
*/ */
@@ -229,19 +231,19 @@ class SprintfBW extends BufferWriteCall {
result = this.(FormattingFunctionCall).getFormatArgument(_) result = this.(FormattingFunctionCall).getFormatArgument(_)
} }
override Expr getDest() { result = getArgument(f.getOutputParameterIndex(false)) } override Expr getDest() { result = this.getArgument(f.getOutputParameterIndex(false)) }
override int getMaxData() { override int getMaxData() {
exists(FormatLiteral fl | exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLength() * getCharSize() result = fl.getMaxConvertedLength() * this.getCharSize()
) )
} }
override int getMaxDataLimited() { override int getMaxDataLimited() {
exists(FormatLiteral fl | exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and 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 { class SnprintfBW extends BufferWriteCall {
SnprintfBW() { 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: * C snprintf variants:
*/ */
@@ -326,25 +328,25 @@ class SnprintfBW extends BufferWriteCall {
result = this.(FormattingFunctionCall).getFormatArgument(_) 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() { override int getExplicitLimit() {
result = getArgument(getParamSize()).getValue().toInt() * getCharSize() result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
} }
override int getMaxData() { override int getMaxData() {
exists(FormatLiteral fl | exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLength() * getCharSize() result = fl.getMaxConvertedLength() * this.getCharSize()
) )
} }
override int getMaxDataLimited() { override int getMaxDataLimited() {
exists(FormatLiteral fl | exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and 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 { class GetsBW extends BufferWriteCall {
GetsBW() { GetsBW() {
getTarget().(TopLevelFunction).getName() = this.getTarget().(TopLevelFunction).getName() =
[ [
"gets", // gets(dst) "gets", // gets(dst)
"fgets", // fgets(dst, max_amount, src_stream) "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. * 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 Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }
override Expr getASource() { override Expr getASource() {
if exists(getArgument(2)) if exists(this.getArgument(2))
then result = getArgument(2) then result = this.getArgument(2)
else else
// the source is input inside the 'gets' call itself // the source is input inside the 'gets' call itself
result = this 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() { 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 | exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
this = fc.getArgument(arg) and this = fc.getArgument(arg) and
fl = fc.getFormat() 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 { class RealpathBW extends BufferWriteCall {
RealpathBW() { RealpathBW() {
exists(path_max()) and // Ignore realpath() calls if PATH_MAX cannot be determined 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 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() { override int getMaxData() {
result = path_max() and result = path_max() and

View File

@@ -52,9 +52,9 @@ class BasicOStreamClass extends Type {
*/ */
class BasicOStreamCall extends FunctionCall { class BasicOStreamCall extends FunctionCall {
BasicOStreamCall() { BasicOStreamCall() {
if getTarget() instanceof MemberFunction if this.getTarget() instanceof MemberFunction
then getQualifier().getType() instanceof BasicOStreamClass then this.getQualifier().getType() instanceof BasicOStreamClass
else getArgument(0).getType() instanceof BasicOStreamClass else this.getArgument(0).getType() instanceof BasicOStreamClass
} }
} }
@@ -77,10 +77,10 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
*/ */
Expr getEndDest() { Expr getEndDest() {
// recurse into the destination // recurse into the destination
result = getDest().(ChainedOutputCall).getEndDest() result = this.getDest().(ChainedOutputCall).getEndDest()
or or
// or return something other than a ChainedOutputCall // or return something other than a ChainedOutputCall
result = getDest() and result = this.getDest() and
not result instanceof ChainedOutputCall not result instanceof ChainedOutputCall
} }
} }
@@ -89,18 +89,18 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
* A call to `operator<<` on an output stream. * A call to `operator<<` on an output stream.
*/ */
class OperatorLShiftCall extends ChainedOutputCall { class OperatorLShiftCall extends ChainedOutputCall {
OperatorLShiftCall() { getTarget().(Operator).hasName("operator<<") } OperatorLShiftCall() { this.getTarget().(Operator).hasName("operator<<") }
override Expr getSource() { override Expr getSource() {
if getTarget() instanceof MemberFunction if this.getTarget() instanceof MemberFunction
then result = getArgument(0) then result = this.getArgument(0)
else result = getArgument(1) else result = this.getArgument(1)
} }
override Expr getDest() { override Expr getDest() {
if getTarget() instanceof MemberFunction if this.getTarget() instanceof MemberFunction
then result = getQualifier() then result = this.getQualifier()
else result = getArgument(0) else result = this.getArgument(0)
} }
} }
@@ -108,22 +108,22 @@ class OperatorLShiftCall extends ChainedOutputCall {
* A call to 'put'. * A call to 'put'.
*/ */
class PutFunctionCall extends ChainedOutputCall { 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'. * A call to 'write'.
*/ */
class WriteFunctionCall extends ChainedOutputCall { 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() }
} }
/** /**

View File

@@ -24,7 +24,7 @@ private class RemoteReturnSource extends RemoteFlowSource {
RemoteReturnSource() { RemoteReturnSource() {
exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output | exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and this.asInstruction() = instr and
instr.getStaticCallTarget() = func and instr.getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and func.hasRemoteFlowSource(output, sourceType) and
( (
@@ -43,7 +43,7 @@ private class RemoteParameterSource extends RemoteFlowSource {
RemoteParameterSource() { RemoteParameterSource() {
exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output | exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and this.asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and func.hasRemoteFlowSource(output, sourceType) and
output.isParameterDerefOrQualifierObject(instr.getIndex()) output.isParameterDerefOrQualifierObject(instr.getIndex())
@@ -58,7 +58,7 @@ private class LocalReturnSource extends LocalFlowSource {
LocalReturnSource() { LocalReturnSource() {
exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output | exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
asInstruction() = instr and this.asInstruction() = instr and
instr.getStaticCallTarget() = func and instr.getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and func.hasLocalFlowSource(output, sourceType) and
( (
@@ -77,7 +77,7 @@ private class LocalParameterSource extends LocalFlowSource {
LocalParameterSource() { LocalParameterSource() {
exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output | exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
asInstruction() = instr and this.asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and func.hasLocalFlowSource(output, sourceType) and
output.isParameterDerefOrQualifierObject(instr.getIndex()) output.isParameterDerefOrQualifierObject(instr.getIndex())

View File

@@ -77,7 +77,7 @@ abstract class FunctionWithWrappers extends Function {
) { ) {
// base case // base case
func = this and func = this and
interestingArg(paramIndex) and this.interestingArg(paramIndex) and
callChain = toCause(func, paramIndex) and callChain = toCause(func, paramIndex) and
depth = 0 depth = 0
or or
@@ -101,7 +101,7 @@ abstract class FunctionWithWrappers extends Function {
private predicate wrapperFunctionAnyDepth(Function func, int paramIndex, string cause) { private predicate wrapperFunctionAnyDepth(Function func, int paramIndex, string cause) {
// base case // base case
func = this and func = this and
interestingArg(paramIndex) and this.interestingArg(paramIndex) and
cause = toCause(func, paramIndex) cause = toCause(func, paramIndex)
or or
// recursive step // recursive step
@@ -147,7 +147,7 @@ abstract class FunctionWithWrappers extends Function {
) )
or or
not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and
cause = wrapperFunctionAnyDepthUnique(func, paramIndex) cause = this.wrapperFunctionAnyDepthUnique(func, paramIndex)
} }
/** /**

View File

@@ -78,7 +78,7 @@ class SecurityOptions extends string {
functionCall.getTarget().getName() = fname and functionCall.getTarget().getName() = fname and
( (
fname = ["fgets", "gets"] or fname = ["fgets", "gets"] or
userInputReturn(fname) this.userInputReturn(fname)
) )
) )
or or

View File

@@ -29,7 +29,7 @@ private predicate suspicious(string s) {
*/ */
class SensitiveVariable extends Variable { class SensitiveVariable extends Variable {
SensitiveVariable() { SensitiveVariable() {
suspicious(getName().toLowerCase()) and suspicious(this.getName().toLowerCase()) and
not this.getUnspecifiedType() instanceof IntegralType not this.getUnspecifiedType() instanceof IntegralType
} }
} }
@@ -39,7 +39,7 @@ class SensitiveVariable extends Variable {
*/ */
class SensitiveFunction extends Function { class SensitiveFunction extends Function {
SensitiveFunction() { SensitiveFunction() {
suspicious(getName().toLowerCase()) and suspicious(this.getName().toLowerCase()) and
not this.getUnspecifiedType() instanceof IntegralType not this.getUnspecifiedType() instanceof IntegralType
} }
} }

View File

@@ -113,7 +113,7 @@ module BoostorgAsio {
result.getName() = "tls_server" result.getName() = "tls_server"
) )
or or
result = getASslv23ProtocolConstant() result = this.getASslv23ProtocolConstant()
} }
/** /**

View File

@@ -76,9 +76,9 @@ class BlockStmt extends Stmt, @stmt_block {
* the result is the expression statement `a = b`. * the result is the expression statement `a = b`.
*/ */
Stmt getLastStmtIn() { Stmt getLastStmtIn() {
if getLastStmt() instanceof BlockStmt if this.getLastStmt() instanceof BlockStmt
then result = getLastStmt().(BlockStmt).getLastStmtIn() then result = this.getLastStmt().(BlockStmt).getLastStmtIn()
else result = getLastStmt() else result = this.getLastStmt()
} }
/** /**

View File

@@ -27,10 +27,10 @@ class Stmt extends StmtParent, @stmt {
*/ */
BlockStmt getEnclosingBlock() { BlockStmt getEnclosingBlock() {
if if
getParentStmt() instanceof BlockStmt and this.getParentStmt() instanceof BlockStmt and
not getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation not this.getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation
then result = getParentStmt() then result = this.getParentStmt()
else result = getParentStmt().getEnclosingBlock() else result = this.getParentStmt().getEnclosingBlock()
} }
/** Gets a child of this statement. */ /** Gets a child of this statement. */
@@ -438,7 +438,7 @@ class WhileStmt extends Loop, @stmt_while {
* while(1) { ...; if(b) break; ...; } * while(1) { ...; if(b) break; ...; }
* ``` * ```
*/ */
predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) } predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
/** /**
* Holds if the loop condition is provably `false`. * Holds if the loop condition is provably `false`.
@@ -448,7 +448,7 @@ class WhileStmt extends Loop, @stmt_while {
* while(0) { ...; } * while(0) { ...; }
* ``` * ```
*/ */
predicate conditionAlwaysFalse() { conditionAlwaysFalse(getCondition()) } predicate conditionAlwaysFalse() { conditionAlwaysFalse(this.getCondition()) }
/** /**
* Holds if the loop condition is provably `true` upon entry, * 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`. * 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. * 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`. * 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. */ /** 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 * 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) } DeclStmt getBeginEndDeclaration() { result = this.getChild(1) }
/** Gets the compiler-generated `__begin` variable after desugaring. */ /** 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. */ /** 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 * 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) } Expr getUpdate() { result = this.getChild(3) }
/** Gets the compiler-generated `__begin` variable after desugaring. */ /** 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; } * for(x = 0; 1; ++x) { sum += x; }
* ``` * ```
*/ */
predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) } predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
/** /**
* Holds if the loop condition is provably `false`. * 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; } * 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, * 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. * 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'. */ /** 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. * 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&amp; e)` introduces a * For example, `catch(std::exception&amp; e)` introduces a
* parameter `e`, whereas `catch(...)` does not introduce a parameter. * parameter `e`, whereas `catch(...)` does not introduce a parameter.
*/ */
Parameter getParameter() { result = getBlock().getParameter() } Parameter getParameter() { result = this.getBlock().getParameter() }
override predicate mayBeImpure() { none() } override predicate mayBeImpure() { none() }
@@ -1921,15 +1921,15 @@ class MicrosoftTryStmt extends Stmt, @stmt_microsoft_try {
* This is a Microsoft C/C++ extension. * This is a Microsoft C/C++ extension.
*/ */
class MicrosoftTryExceptStmt extends MicrosoftTryStmt { class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
MicrosoftTryExceptStmt() { getChild(1) instanceof Expr } MicrosoftTryExceptStmt() { this.getChild(1) instanceof Expr }
override string toString() { result = "__try { ... } __except( ... ) { ... }" } override string toString() { result = "__try { ... } __except( ... ) { ... }" }
/** Gets the expression guarding the `__except` statement. */ /** 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`). */ /** Gets the `__except` statement (usually a `BlockStmt`). */
Stmt getExcept() { result = getChild(2) } Stmt getExcept() { result = this.getChild(2) }
override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" } override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" }
} }
@@ -1948,12 +1948,12 @@ class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
* This is a Microsoft C/C++ extension. * This is a Microsoft C/C++ extension.
*/ */
class MicrosoftTryFinallyStmt extends MicrosoftTryStmt { class MicrosoftTryFinallyStmt extends MicrosoftTryStmt {
MicrosoftTryFinallyStmt() { not getChild(1) instanceof Expr } MicrosoftTryFinallyStmt() { not this.getChild(1) instanceof Expr }
override string toString() { result = "__try { ... } __finally { ... }" } override string toString() { result = "__try { ... } __finally { ... }" }
/** Gets the `__finally` statement (usually a `BlockStmt`). */ /** Gets the `__finally` statement (usually a `BlockStmt`). */
Stmt getFinally() { result = getChild(1) } Stmt getFinally() { result = this.getChild(1) }
override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" } override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" }
} }

View File

@@ -68,12 +68,12 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
/** /**
* Gets the start column of the first `VariableDeclarationEntry` on this line. * 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. * 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 * Gets the rank of this `VariableDeclarationLine` in its file and class
@@ -89,14 +89,14 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
*/ */
VariableDeclarationLine getNext() { VariableDeclarationLine getNext() {
result = TVariableDeclarationLine(c, f, _) and result = TVariableDeclarationLine(c, f, _) and
result.getRank() = getRank() + 1 result.getRank() = this.getRank() + 1
} }
/** /**
* Gets the `VariableDeclarationLine` following this one, if it is nearby. * Gets the `VariableDeclarationLine` following this one, if it is nearby.
*/ */
VariableDeclarationLine getProximateNext() { VariableDeclarationLine getProximateNext() {
result = getNext() and result = this.getNext() and
result.getLine() <= this.getLine() + 3 result.getLine() <= this.getLine() + 3
} }
@@ -114,14 +114,14 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
// there is no `VariableDeclarationLine` within three lines previously // there is no `VariableDeclarationLine` within three lines previously
not any(VariableDeclarationLine prev).getProximateNext() = this and not any(VariableDeclarationLine prev).getProximateNext() = this and
// `end` is the last transitively proximate line // `end` is the last transitively proximate line
end = getProximateNext*() and end = this.getProximateNext*() and
not exists(end.getProximateNext()) not exists(end.getProximateNext())
} }
predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) { predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) {
path = f.getAbsolutePath() and path = f.getAbsolutePath() and
startline = getLine() and startline = this.getLine() and
startcol = getStartColumn() and startcol = this.getStartColumn() and
endline = end.getLine() and endline = end.getLine() and
endcol = end.getEndColumn() endcol = end.getEndColumn()
} }
@@ -132,18 +132,18 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
int getCount() { int getCount() {
result = result =
count(VariableDeclarationLine l | count(VariableDeclarationLine l |
l = getProximateNext*() l = this.getProximateNext*()
| |
l.getAVDE().getVariable().getName() l.getAVDE().getVariable().getName()
) )
} }
override string toString() { override string toString() {
getCount() = 1 and this.getCount() = 1 and
result = "declaration of " + getAVDE().getVariable().getName() result = "declaration of " + this.getAVDE().getVariable().getName()
or or
getCount() > 1 and this.getCount() > 1 and
result = "group of " + getCount() + " fields here" result = "group of " + this.getCount() + " fields here"
} }
} }

View File

@@ -50,7 +50,7 @@ class SemaphoreTake extends LockOperation {
result.(SemaphoreGive).getLocked() = this.getLocked() 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 { class SemaphoreGive extends UnlockOperation {
@@ -76,13 +76,13 @@ class LockingPrimitive extends FunctionCall, LockOperation {
this.getTarget().getName().replaceAll("Lock", "Unlock") 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 { class UnlockingPrimitive extends FunctionCall, UnlockOperation {
UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] } UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] }
Function getLocked() { result = getMatchingLock().getLocked() } Function getLocked() { result = this.getMatchingLock().getLocked() }
override LockOperation getMatchingLock() { this = result.getMatchingUnlock() } override LockOperation getMatchingLock() { this = result.getMatchingUnlock() }
} }

View File

@@ -38,10 +38,10 @@ class Copy extends @duplication_or_similarity {
int sourceStartColumn() { tokens(this, 0, _, result, _, _) } int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
/** Gets the line on which the last token in this block ends. */ /** 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. */ /** 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. */ /** Gets the number of lines containing at least (part of) one token in this block. */
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() } int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
@@ -66,11 +66,11 @@ class Copy extends @duplication_or_similarity {
predicate hasLocationInfo( predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn string filepath, int startline, int startcolumn, int endline, int endcolumn
) { ) {
sourceFile().getAbsolutePath() = filepath and this.sourceFile().getAbsolutePath() = filepath and
startline = sourceStartLine() and startline = this.sourceStartLine() and
startcolumn = sourceStartColumn() and startcolumn = this.sourceStartColumn() and
endline = sourceEndLine() and endline = this.sourceEndLine() and
endcolumn = sourceEndColumn() endcolumn = this.sourceEndColumn()
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
@@ -79,13 +79,15 @@ class Copy extends @duplication_or_similarity {
/** A block of duplicated code. */ /** A block of duplicated code. */
class DuplicateBlock extends Copy, @duplication { 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. */ /** A block of similar code. */
class SimilarBlock extends Copy, @similarity { class SimilarBlock extends Copy, @similarity {
override string toString() { override string toString() {
result = "Similar code: " + sourceLines() + " almost duplicated lines." result = "Similar code: " + this.sourceLines() + " almost duplicated lines."
} }
} }

View File

@@ -67,7 +67,7 @@ class MetricResult extends int {
/** Gets the URL corresponding to the location of this query result. */ /** Gets the URL corresponding to the location of this query result. */
string getURL() { string getURL() {
result = result =
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" + "file://" + this.getFile().getAbsolutePath() + ":" + this.getStartLine() + ":" +
getEndLine() + ":" + getEndColumn() this.getStartColumn() + ":" + this.getEndLine() + ":" + this.getEndColumn()
} }
} }